Java事件机制原理
事件机制是通过观察者模式实现的。
在Java事件机制中,有三个组成部分:事件源、事件、事件监听者。
事件源
事件源是一个Subject,当事件发生时,它会广播消息给所有的事件监听者。
事件监听者
事件监听者是一个Observer,接收到消息之后,会产生相应动作。
事件
描述事件的信息。
在此三者中,事件源比较复杂。它需要维护一个事件监听者队列,提供方法让事件监听者注册、删除,当事件发生时,需要广播消息给所有的事件监听者。
一个简单的例子
事件:每个三秒产生一个打印当前时间的事件。
事件监听者1:以24小时制打印事件发生的时间。
事件监听者2:以12小时制打印事件发生的时间。
事件的实现
继承java.util.EventObject,它只有一个构造函数EventObject(Object obj):
package java.util; import java.io.Serializable; public class EventObject implements Serializable { public EventObject(Object obj) { if(obj == null) { throw new IllegalArgumentException("null source"); } else { source = obj; return; } } public Object getSource() { return source; } public String toString() { return (new StringBuilder()).append(getClass().getName()).append("[source=").append(source).append("]").toString(); } private static final long serialVersionUID = 5516075349620653480L; protected transient Object source; }
继承之后,可以在自己定义的事件类中加入更多的信息。我在TestEvent中加入了Date信息:
package test; import java.util.Date; import java.util.EventObject; public class TestEvent extends EventObject { private Date date; public TestEvent(Object src, Date date) { super(src); this.date = date; } public Date getDate() { return date; } }
事件监听者
由接口和具体的实现两部分组成。
TestEventListener接口继承java.util.EventListener,EventListener接口不包含任何方法,只是一个标志。
我在TestEventListener接口中定义了打印时间的方法:
package test; import java.util.EventListener; public interface TestEventListener extends EventListener { public void printTime(TestEvent event); }
具体实现1,以24小时制打印时间:package test; import java.text.SimpleDateFormat; public class TestEventListenerImpl1 implements TestEventListener { public void printTime(TestEvent event) { System.out.println(new SimpleDateFormat("HH:mm:ss").format(event.getDate())); } }
具体实现2,以12小时制打印时间:package test; import java.text.SimpleDateFormat; public class TestEventListenerImpl2 implements TestEventListener { public void printTime(TestEvent event) { System.out.println(new SimpleDateFormat("hh:mm:ss").format(event.getDate())); } }
事件源
我采用了一个ArrayList维护监听者队列,提供addTestEventListener()、removeTestEventListener()方法让监听者注册和删除,通过notifyListeners()方法广播事件发生的消息:
package test; import java.util.ArrayList; import java.util.Date; public class TestSource { private ArrayList listenerList; private TestEvent event; public TestSource() { listenerList = new ArrayList(); } public void addTestListener(TestEventListener listener) { listenerList.add(listener); } public void removeTestListener(TestEventListener listener) { listenerList.remove(listener); } public void notifyListeners() { for (Object listener : listenerList) { ((TestEventListener)listener).printTime(event); } } public void eventOccur() { event = new TestEvent(this, new Date()); notifyListeners(); } }
模拟测试:
package test; import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) throws InterruptedException { TestSource src = new TestSource(); TestEventListener t1 = new TestEventListenerImpl1(); TestEventListener t2 = new TestEventListenerImpl2(); src.addTestListener(t1); src.addTestListener(t2); while (true) { src.eventOccur(); TimeUnit.SECONDS.sleep(3); } } }
测试结果:
17:20:38 05:20:38 17:20:41 05:20:41 17:20:44 05:20:44 ... ...