java屬性變化事件機制(1)

         屬性事件主要關注屬性值的變化所產生的事件。一般都會定義好屬性並保存着,只是其值會變化,變化即產生事件,要作相應的處理。應該與點擊一個按鈕等產生的事件相區別。
  如一個屬性light(燈),它的值有on和off。。。。

  也寫了一個例子,與java標準事件機制類似。一個信號燈,紅,黃,綠變化着,即當這個信號燈的屬性color的值是紅則變爲紅燈,值是黃則變爲黃燈,值是綠則變爲綠燈。要監聽JButton(點擊開始才運行,運行後可暫停),又要使燈運行,所以也練習了一下線程。同時也加了一個方向指示。
  light.propertyChangeEvent("light", "green");//綠燈亮

  light.propertyChangeEvent("light", "red");//紅燈亮

  light.propertyChangeEvent("light", "yellow");//黃燈亮
  


package cn.com.cathay.event.LED;

import java.util.EventListener;

public interface LEDListener extends EventListener
{
    public void onStatusChange(LEDEvent event);

}


package cn.com.cathay.event.LED;

import java.util.EventObject;

public class LEDEvent extends EventObject
{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    private String color = null;
   
    public LEDEvent(Object source, String color)
    {
        super(source);
        this.color = color;
    }

    /**
     * @return the color
     */
    public String getColor() {
        return color;
    }

    /**
     * @param color the color to set
     */
    public void setColor(String color) {
        this.color = color;
    }
}

package cn.com.cathay.event.LED;

import java.util.HashMap;

import javax.swing.JButton;

public class LED extends JButton
{
    private static HashMap<String, LEDListener> listenerList = null;
   
    private String oldColor = null;
   
    public LED()
    {       
    }
   
    //增加事件
    public void addLEDListener(String propertyName, LEDListener listener)
    {
        if (listenerList == null)
        {
            listenerList = new HashMap<String, LEDListener>();
        }
       
        listenerList.put(propertyName,listener);       
    }
   
    //移除事件
    public void removeLEDListener(String propertyName)
    {
        if (listenerList == null)
        {
            return;
        }
        else
        {
            listenerList.remove(propertyName);
        }
    }
   
    /**
     * 響應事件.<br >
     * 如果屬性的值有變化,則調用實現了<code>LEDListener</code>接口的類的onStatusChange方法。
     */
    public void propertyChangeEvent(String propertyName, String newColor)
    {
        LEDListener Listener = listenerList.get(propertyName);
        if ( Listener == null)
        {
            return;
        }       
       
        //如果屬性有變化,則要調用具體的實現方法onStatusChange()
        if (this.oldColor == null || ! this.oldColor.equalsIgnoreCase(newColor))
        {
            this.oldColor = newColor;
            LEDEvent event = new LEDEvent(this,newColor);
            Listener.onStatusChange(event);
        }       
    }
   
}


package cn.com.cathay.event.LED;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class LEDPanel extends JFrame
{
    /** 信號燈 */
    private LED light;
   
    /** 方向指示燈 */
    private LED way;
   
    /** 控制按鈕 */
    private JButton operator;
   
    /** 是否運行。 true:運行  false:暫停 */
    private boolean loop;
   
    /** 同步信號*/
    private Object lock = new Object();
   
    /** 工作線程 */
    private Worker worker = null;
   
    public LEDPanel()
    {
        //設置主面板屬性
        setTitle("交通信號燈");
        setLayout(new GridLayout(3,1));
        setSize(50,200);
       
        light = new LED();
        way = new LED();
        operator = new JButton("start");
       
        //註冊事件
        light.addLEDListener("light", new MyLedListener());
        way.addLEDListener("way", new MyWayListener());
        operator.addActionListener(new myButtonListener());
       
        //將按鈕加到主面板
        add(light);
        add(way);
        add(operator);
   
        setVisible(true);
       
        startWork();
    }
   
    /**
     * start work
     */
    public void startWork()
    {
        worker = new Worker();
        worker.start();
    }
   
    /**
     * 運行信號燈。控制燈亮的時間,順序
     */
    public void change()
    {
        redOn(2000l);
       
        greenOn(2000l);
       
        yellowOn(2000l);
    }
   

    /**
     * 紅燈亮
     * @param time 控制燈亮的時間,單位爲mm
     */

    public void redOn(long time)
    {
        light.propertyChangeEvent("light", "red");
        way.propertyChangeEvent("way", "red");
       
        try
        {
            Thread.sleep(time);
            if (loop == false)
            {
                lock.wait();
            }
           
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
   
    /**
     * 綠燈亮
     * @param time 控制燈亮的時間,單位爲mm
     */
    public void greenOn(long time)
    {
        light.propertyChangeEvent("light", "green");
        way.propertyChangeEvent("way", "green");
       
        try
        {
            Thread.sleep(time);
            if (loop == false)
            {
                lock.wait();
            }
           
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 黃燈亮
     * @param time 控制燈亮的時間,單位爲mm
     */
    public void yellowOn(long time)
    {
        light.propertyChangeEvent("light", "yellow");
        way.propertyChangeEvent("way", "yellow");
       
        try
        {
            Thread.sleep(time);
            if (loop == false)
            {
                lock.wait();
            }
           
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }


    //LED燈屬性變化監聽事件
    public class MyLedListener implements LEDListener
    {
        public void onStatusChange(LEDEvent event)
        {
            LED led = (LED)event.getSource();
           
            if ("red".equalsIgnoreCase(event.getColor()))
            {
                led.setBackground(Color.red);
            }
            else if ("green".equalsIgnoreCase(event.getColor()))
            {
                led.setBackground(Color.green);
            }
            else if ("yellow".equalsIgnoreCase(event.getColor()))
            {
                led.setBackground(Color.yellow);
            }
            else
            {
                led.setBackground(Color.LIGHT_GRAY);
            }
           
        }
    }
   
    //方向指示燈事件
    public class MyWayListener implements LEDListener
    {
        public void onStatusChange(LEDEvent event)
        {
            LED led = (LED)event.getSource();
           
            if ("red".equalsIgnoreCase(event.getColor()))
            {
                led.setText("→");
                led.setForeground(Color.green);
            }
            else if ("green".equalsIgnoreCase(event.getColor()))
            {
                led.setText("↑");
                led.setForeground(Color.green);
            }
            else if ("yellow".equalsIgnoreCase(event.getColor()))
            {
                led.setText("←");
                led.setForeground(Color.green);
            }
            else
            {
                led.setBackground(Color.LIGHT_GRAY);
            }
        }
    }

   
    //Button的監聽事件
    public class myButtonListener implements ActionListener
    {
        JButton led;
       
        public void actionPerformed(ActionEvent event)
        {
            led = (JButton)event.getSource();
           
            try
            {   
                if ("start".equals(led.getText()))
                {   
                    synchronized (lock)
                    {
                        loop = true;
                        led.setText("stop");
                        lock.notify();  //喚醒,開始燈亮
                    }               
                }
                else
                {
                    led.setText("start");
                    loop = false;
                }
            } catch (Exception e)
            {               
                e.printStackTrace();
            }
           
        }
    }
   
    /**
     * 工作線程類,使燈亮的線程
     */
    public class Worker extends Thread
    {
        public void run()
        {
            try
            {
                synchronized (lock)
                {
                    lock.wait();//線程一開始不要運行,點擊start按鈕纔開始。
                   
                    while (true)
                    {               
                        change();
                    }
                }               
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }          
        }
    }
   
   
    public static void main(String[] args)
    {
        JFrame f = new LEDPanel();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章