1 什么是事件监听机制
前一篇文章简述了观察者模式,事件监听机制是对观察者模式的另一种实现,本质上均是多个对象(观察者/监听器)依赖于一个对象(被观察者/事件)的状态的关系。
观察者模式中主要有角色:观察者(Observer)、被观察者(Subject,Obserable).
事件监听机制中的主要角色:事件(Event),事件源(Source),事件发布器(EventPublisher),监听器(Listener)
两者主要区别是什么?
观察者模式中:被观察者(Subject)需要主动维护观察者的引用集合,并通知观察者状态变化
事件监听机制中:事件发布器承担了维护观察者的引用集合,并通知观察者状态变化的功能。
观察者模式 | 事件监听机制 |
---|---|
观察者(Observer) | 监听器(Listener) |
被观察者(Subject,Obserable) | 事件(Event),事件源(Source) |
被观察者(Subject,Obserable)中负责维护主题与观察者映射关系以及在自身状态改变时通知观察者的职责 | 事件发布器(EventPublisher) |
事件源(Source):产生事件的源头,也即发生事件的组件。例如按钮(事件源)和点击(事件)的关系
事件(Event):对一个组件的某种同类型操作动作的集合.
监听器(Listener):首先,监听组件,观察组件有没有发生某类事件;其次如果监听的组件发生了某类事件,则调用对应的动作处理方法立刻处理这个事件。
这些角色/组件之间的关系如图所示(网图侵删):
事件发布器(EventPublisher)组件在图中主要表现为:将监听器注册到事件源上,在必要的时候调用事件所对应的监听器处理事件。
2 JDK的事件监听机制
jdk中为实现事件监听机制提供了两个基础类:EventObject和EventListener,均是java.util包的类。
2.1 EventObject(事件)
EventObject:表示事件基类,该EventObject定义了事件对象,其中source表示事件源(或者任意其它对象),自定义事件扩展该类,源码如下:
package java.util;
/**
* <p>
* The root class from which all event state objects shall be derived.
* <p>
* All Events are constructed with a reference to the object, the "source",
* that is logically deemed to be the object upon which the Event in question
* initially occurred upon.
*
* @since JDK1.1
*/
public class EventObject implements java.io.Serializable {
private static final long serialVersionUID = 5516075349620653480L;
/**
* 表示事件最初发生的地方(事件源)
* The object on which the Event initially occurred.
*/
protected transient Object source;
/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @exception IllegalArgumentException if source is null.
*/
public EventObject(Object source) {
if (source == null)
throw new IllegalArgumentException("null source");
this.source = source;
}
/**
* The object on which the Event initially occurred.
*
* @return The object on which the Event initially occurred.
*/
public Object getSource() {
return source;
}
/**
* Returns a String representation of this EventObject.
*
* @return A a String representation of this EventObject.
*/
public String toString() {
return getClass().getName() + "[source=" + source + "]";
}
}
2.2 EventListener(事件监听器)
EventListener:事件监听器,是一个标记接口,自定义监听器扩展该监听器,源码如下:
package java.util;
/**
* A tagging interface that all event listener interfaces must extend.
* @since JDK1.1
*/
public interface EventListener {
}
2.3 EventPublisher(事件发布器)
该类jdk没有提供相应的实现,需要我们自己手动编写。
2.4 基于jdk的事件机制示例
该示例以过红绿灯为例(类似前文的观察者模式)
2.4.1 事件源(红绿灯)
//事件源
public class Source {
public String color = "red";
}
2.4.1 事件
public class SwitchLightEvent extends EventObject {
public SwitchLightEvent(Object source) {
super(source);
}
}
2.4.2 事件监听器
自定义事件监听器接口
public interface ObjectListener extends EventListener {
public void deal(SwitchLightEvent event);
}
自定义监听器实例
public class CarListener implements ObjectListener{
/**
* 监听器接收到事件对象也可以通过getSource获得事件源对象
* 这样可以根据事件及事件源来执行相应的处理逻辑
* @param event 事件对象
*/
public void deal(SwitchLightEvent event) {
System.out.println(event.getSource()+" Car Run");
}
}
public class ManListener implements ObjectListener {
public void deal(SwitchLightEvent event) {
System.out.println(event.getSource()+" Man Run");
}
}
2.4.3 事件发布器
public class SwitchLightEventPublisher {
//观察者对象引用的集合
private List<ObjectListener> listeners = new ArrayList<ObjectListener>();
//注册监听器
public void attach(ObjectListener listener) {
if (listener == null) {
return;
}
listeners.add(listener);
}
//删除监视器
public void detach(ObjectListener listener) {
Iterator<ObjectListener> iterator = listeners.iterator();
while (iterator.hasNext()) {
ObjectListener next = iterator.next();
if (listener.equals(next)) {
iterator.remove();
}
}
}
//发布红绿灯切换事件
public void publishEvent(SwitchLightEvent event) {
for (ObjectListener observer : listeners) {