屬性事件主要關注屬性值的變化所產生的事件。一般都會定義好屬性並保存着,只是其值會變化,變化即產生事件,要作相應的處理。應該與點擊一個按鈕等產生的事件相區別。
如一個屬性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);
}
}