事件源类:描述事件发生源的基本属性和行为。比如,按钮是很多事件发生的事件源,Java构造按钮类来描述按钮的形状,颜色等等属性以及在屏幕上绘制按钮等动作,当然也包括按钮按下等相关事件发生本身。同时,在事件发生时,事件源类还负责发出事件发生的通知。该行为通过事件源查找自己的事件监听者队列,并将事件信息通知队列中的监听者来完成。同时,事件源还在得到有关监听者信息时负责维护自己的监听者队列。
事件类:定义事件的特征;
事件监听器接口:事件发生后,事件源要将相关的信息通知对应的监听者。这要求必须在事件源和监听者之间定义一个标准的接口规范,以便完成这样的信息交换。监听者接口正是负责定义这样的接口规范。也就是定义监听器应该实现的功能;
事件监听器适配器类:在Java中,由于应用接口必须在应用的类中实现接口中的所有申明函数,有时对于不需要使用所有申明函数的监听者比较麻烦,所以通常可以编写一个基础的适配器类来应用接口,适配器中预先实现所有的空接口函数,监听者则通过继承适配器并重载自己需要的接口函数来避免直接应用接口的麻烦。
事件监听器类:实现监听器接口,监听事件的发生并作出响应;
所有的事件类必须继承Java事件基类,即java.util.EventObject;EventObject(Object source)是EventObject唯一的构造方法,这意味着所有事件必须在实例化时就指定事件源;EventObject类提供了getSource()方法来获取事件源;
定义了事件类后,产生一个事件,就是生成事件类的一个实例。
除了事件源,复杂的事件类代码可以含有其他属性、方法,包含更多的信息,如事件的名称、事件发生的时间、事件所属类别以及事件的描述等等
监听器接口定义了一个类要成为监听器必须具备的功能。所有的监听器接口也都必须继承监听器接口基类java.util.EventListener;EventListener本身没有定义任何方法,它只是一个标志接口,用来表明所有继承自EventListener的接口属于监听器接口。
监听器接口定义了监听器必须实现的方法。可以在监听器接口中定义任意多的事件处理方法,取决于应用所需,事件处理方法以事件对象作为入口参数,包含对事件进行处理的代码,方法名称任意,如processEvent或者handleEvent之类。
监听器是监听器接口的实现者,提供监听器接口中定义的所有方法的实现代码。简单情形下,一个监听器只监听一种类型的事件,即实现一种监听器接口。复杂的监听器可以实现多种监听器接口,监听多种类型的事件。在事件处理方法代码中,监听器可以从入口参数中获得事件对象,并通过该对象获得所需的信息,例如事件源、事件发生时间等等。事件源是一定可以从事件对象中 获得的,因为事件基类EventObject提供了getSource()方法,除此以外,能从事件对象中获得的信息,取决于事件类的定义。
介绍了那么多,下面给出一个完整的实例,这个例子是将网上的一个实例修改完善后的。修改后的实例完全符合我上面介绍的情形。这个实例会让你更容易理解java的事件模型。
事件类:
package com.amuse.event;
import java.util.EventObject;
/**
* 类DoorEvent.java的实现描述:DoorEvent.java
* <p>
* 这是一个事件类继承了 java.util.EventObject
*
* @author yongchun.chengyc 2012-3-13 下午5:17:57
*/
public class DoorEvent extends EventObject {
private String doorState = "";
/**
* @param source
*/
public DoorEvent(Object source, String doorState){
super(source);
this.doorState = doorState;
}
/**
* @return the doorState
*/
public String getDoorState() {
return doorState;
}
/**
* @param doorState the doorState to set
*/
public void setDoorState(String doorState) {
this.doorState = doorState;
}
}
事件监听器接口:
package com.amuse.event;
import java.util.EventListener;
/**
* 类DoorEventListener.java的实现描述:DoorEventListener.java
* <P>
* 这是一个事件监听接口,继承了java.util.EventListener类
*
* @author yongchun.chengyc 2012-3-13 下午5:22:28
*/
public interface DoorEventListener extends EventListener {
public long beforeHandleDoorEvent();
public void handleDoorEvent(DoorEvent event);
public long afterHandlerDoorEvent();
}
事件监听器适配器:
package com.amuse.event;
/**
* 类DoorEventAdapter.java的实现描述:DoorEventAdapter.java
* <p>
* 这是一个监听器适配器,用于实现监听器接口的一些方法,方便具体的监听器实现类的编写。
*
* @author yongchun.chengyc 2012-3-13 下午9:33:13
*/
public abstract class DoorEventAdapter implements DoorEventListener {
public long beforeHandleDoorEvent() {
return System.currentTimeMillis();
}
public long afterHandlerDoorEvent() {
return System.currentTimeMillis();
}
}
事件监听器实现类1:
package com.amuse.event;
/**
* 类DoorEventListener1.java的实现描述:DoorEventListener1.java
* <p>
* 具体的监听器实现类
*
* @author yongchun.chengyc 2012-3-13 下午5:24:34
*/
public class DoorEventListener1 extends DoorEventAdapter {
/*
* (non-Javadoc)
* @see com.amuse.event.DoorEventListener#onDoorEvent(com.amuse.event.DoorEvent)
*/
@Override
public void handleDoorEvent(DoorEvent event) {
if ((event != null) && (event.getDoorState().equals("open"))) {
System.out.println("the door are opened!-------->in listener1---->事件源" + event.getSource()“);
} else {
System.out.println("the door are closed!-------->in listener1---->事件源" + event.getSource()”);
}
}
}
事件监听器实现类2:
package com.amuse.event;
/**
* 类DoorEventListener1.java的实现描述:DoorEventListener1.java
* <p>
* 具体的监听器实现类
*
* @author yongchun.chengyc 2012-3-13 下午5:24:34
*/
public class DoorEventListener2 extends DoorEventAdapter {
/*
* (non-Javadoc)
* @see com.amuse.event.DoorEventListener#onDoorEvent(com.amuse.event.DoorEvent)
*/
@Override
public void handleDoorEvent(DoorEvent event) {
if ((event != null) && (event.getDoorState().equals("open"))) {
System.out.println("the door are opened!-------->in listener2---->事件源" + event.getSource()”);
} else {
System.out.println("the door are closed!--------->in listener2---->事件源" + event.getSource()“);
}
}
}
事件源类:
package com.amuse.event;
import java.util.Vector;
/**
* 类DoorManager.java的实现描述:DoorManager.java
* <p>
* 事件源
*
* @author yongchun.chengyc 2012-3-13 下午5:28:47
*/
public class DoorEventSource {
// 这个是模仿java.util.Observable类的
private Vector<DoorEventListener> listeners;
// 注册监听者
public synchronized void addDoorListener(DoorEventListener listener) {
if (listener != null) {
listeners.add(listener);
}
}
// 撤销监听者
public synchronized void removeDoorListener(DoorEventListener listener) {
if (listener != null) {
listeners.remove(listener);
}
}
// 事件处罚器
protected void fireWorkspaceOpened() {
if (listeners == null) {
return;
}
DoorEvent event = new DoorEvent(this, "open");
notifyListeners(event);
}
// 事件处罚器
protected void fireWorkspaceClosed() {
if (listeners == null) {
return;
}
DoorEvent event = new DoorEvent(this, "closed");
notifyListeners(event);
}
// 触发事件
private synchronized void notifyListeners(DoorEvent event) {
for (DoorEventListener listener : listeners) {
listener.handleDoorEvent(event);
}
}
/**
* @return the listeners
*/
public Vector<DoorEventListener> getListeners() {
return listeners;
}
/**
* @param listeners the listeners to set
*/
public void setListeners(Vector<DoorEventListener> listeners) {
this.listeners = listeners;
}
public int getListenerNum() {
if (listeners != null) {
return listeners.size();
}
return 0;
}
}
测试类:
package com.amuse.event;
import java.util.Vector;
/**
* 类DoorMainTest.java的实现描述:DoorMainTest.java
* @author yongchun.chengyc 2012-3-13 下午5:40:11
*/
public class DoorMainTest {
/**
* @param args
*/
public static void main(String[] args) {
DoorEventSource source = new DoorEventSource();
source.setListeners(new Vector<DoorEventListener>());
DoorEventListener1 listener1 = new DoorEventListener1();
source.addDoorListener(listener1);
long time1 = listener1.beforeHandleDoorEvent() - listener1.afterHandlerDoorEvent();
System.out.println(time1);
DoorEventListener2 listener2 = new DoorEventListener2();
source.addDoorListener(listener2);
long time2 = listener2.beforeHandleDoorEvent() - listener2.afterHandlerDoorEvent();
System.out.println(time2);
source.fireWorkspaceOpened();
source.fireWorkspaceClosed();
}
}
输出结果为:
0
0
the door are opened!-------->in listener1---->事件源com.amuse.event.DoorEventSource@3d4b7453
the door are opened!-------->in listener2---->事件源com.amuse.event.DoorEventSource@3d4b7453
the door are closed!-------->in listener1---->事件源com.amuse.event.DoorEventSource@3d4b7453
the door are closed!--------->in listener2---->事件源com.amuse.event.DoorEventSource@3d4b7453
观察者模式的实例见另外一位同学的文章:http://www.iteye.com/topic/102068