读书人

事件驱动模型的简略Java实现

发布时间: 2013-02-25 10:23:36 作者: rapoo

事件驱动模型的简单Java实现

事件驱动模型的原理不再赘述,Swing是不错的实现。别人也有不错的博文来说明原理。

本文的目的是提供一种简单的,可供参考的简短代码,用来帮助理解该模型。

?

Project Navigator

?

事件驱动模型的简略Java实现

?

Event

?

事件通用接口:

package org.joshua.event.events;public interface Event {}

?

Click事件:

package org.joshua.event.events;public class ClickEvent implements Event {}

?

Double click事件:

package org.joshua.event.events;public class DblClickEvent implements Event {}

?

Listener

?

事件监听器通用接口:

package org.joshua.event.listener;import org.joshua.event.events.Event;public interface EventListener<T extends Event> {public void handleEvent(T event);}

?

Click事件监听器:

package org.joshua.event.listener;import org.joshua.event.events.ClickEvent;public interface ClickEventHandler extends EventListener<ClickEvent> {}

?

Double Click事件监听器:

package org.joshua.event.listener;import org.joshua.event.events.DblClickEvent;public interface DblClickEventHandler extends EventListener<DblClickEvent> {}

?

Event Source

?

事件源通用接口:

package org.joshua.event.source;import org.joshua.event.events.Event;import org.joshua.event.listener.EventListener;public interface EventSource {void addEventListener(EventListener<? extends Event> listener);void removeEventListener(EventListener<? extends Event> listener);void notifyListeners(Event event);}

?

模拟的按钮控件:

package org.joshua.event.source;import java.util.LinkedList;import java.util.List;import org.joshua.event.events.Event;import org.joshua.event.listener.EventListener;public class Button implements EventSource {protected List<EventListener<? extends Event>> listeners = new LinkedList<EventListener<? extends Event>>();@Overridepublic void addEventListener(EventListener<? extends Event> listener) {listeners.add(listener);}@Overridepublic void removeEventListener(EventListener<? extends Event> listener) {listeners.remove(listener);}@Overridepublic void notifyListeners(Event event) {for (EventListener listener : listeners) {try {listener.handleEvent(event);} catch (ClassCastException e) {}}}}

?

Client

package org.joshua.event;import org.joshua.event.events.ClickEvent;import org.joshua.event.events.DblClickEvent;import org.joshua.event.events.Event;import org.joshua.event.listener.ClickEventHandler;import org.joshua.event.listener.DblClickEventHandler;import org.joshua.event.source.Button;import org.junit.Before;import org.junit.Test;public class Client {private Event currentEvent;private Button button;@Beforepublic void initComponent() {button = new Button();button.addEventListener(new ClickEventHandler() {@Overridepublic void handleEvent(ClickEvent event) {System.out.println("Button was clicked!");}});button.addEventListener(new DblClickEventHandler() {@Overridepublic void handleEvent(DblClickEvent event) {System.out.println("Button was double clicked!");}});}@Testpublic void testCommonEvents() {currentEvent = new ClickEvent();button.notifyListeners(currentEvent);currentEvent = new DblClickEvent();button.notifyListeners(currentEvent);}}

?

?Button类中的notifyListener方法实现起来虽方便,利用了一把异常机制,但着实不推荐大家在项目中这样做。且不说性能问题,Listener的handleEvent方法里所有抛出的ClassCastException都需要重新包装。当然,我们可以使用annotation、限定类名等方式相对优雅地解决event和对应listener的mapping问题。

?

?

?


?

事件驱动模型的简略Java实现

读书人网 >编程

热点推荐