[正文]: package wintys.event; import javax.swing.event.EventListenerList; import java.util.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; /** * Java的事件機(jī)制/自定義事件. 運(yùn)行結(jié)果: do something interesting in source here. listener detects [event]:wintys.event.MyEvent[source=wintys.event.MySource@18158 59] [occur at]:2009-10-11 16:27:49 listener detects [event]:wintys.event.MyEvent[source=wintys.event.MySource@18158 59] [occur at]:2009-10-11 16:27:49 * @version 2009-10-11 * @author 天堂露珠 ([email protected]) */ class MyEventTest{ public static void main(String[] args){ MySource source = new MySource(); MyListener myListener = new MyListener(){ public void doMyAction(MyEvent e){ System.out.println("listener detects " + e); } }; source.addMyListener(myListener); source.addMyListener(myListener); source.addMyListener(myListener); source.removeMyListener(myListener); source.doSomething(); } } /** * 自定義的事件. * @version 2009-10-11 * @author 天堂露珠([email protected]) */ class MyEvent extends java.util.EventObject{ private Date date;//記錄事件發(fā)生的時(shí)間 public MyEvent(Object source , Date date){ super(source); this.date = date; } public String toString(){ DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dt = df.format(date); return "[event]:" + super.toString() + " [occur at]:" + dt; } } /** * 自定義事件監(jiān)聽器接口. * @version 2009-10-11 * @author 天堂露珠([email protected]) */ interface MyListener extends java.util.EventListener{ void doMyAction(MyEvent e); } /** * 自定義事件源. * @version 2009-10-11 * @author 天堂露珠([email protected]) */ class MySource{ /** * 保存注冊的監(jiān)聽器列表. * 子類可以使用它保存自己的事件監(jiān)聽器(非MyListener監(jiān)聽器)列表. */ protected EventListenerList listenerList = new EventListenerList(); private MyEvent myEvent = null;//fireDoMyAction()使用此變量 /** * 沒有做任何事 */ public MySource(){ } /** * 添加一個(gè)MyListener監(jiān)聽器 */ public void addMyListener(MyListener listener){ listenerList.add(MyListener.class , listener); } /** * 移除一個(gè)已注冊的MyListener監(jiān)聽器. * 如果監(jiān)聽器列表中已有相同的監(jiān)聽器listener1,、listener2, * 并且listener1==listener2, * 那么只移除最近注冊的一個(gè)監(jiān)聽器,。 */ public void removeMyListener(MyListener listener){ listenerList.remove(MyListener.class , listener); } /** * @return 在此對象上監(jiān)聽的所有MyListener類型的監(jiān)聽器 */ public MyListener[] getMyListeners(){ return (MyListener[])listenerList.getListeners(MyListener.class); } //Winty:Copy directly from javax.swing.event.EventListenerList /*Notify all listeners that have registered interest for notification on this event type. The event instance is lazily created using the parameters passed into the fire method. */ protected void fireDoMyAction() { // getListenerList() Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length-2; i>=0; i-=2) { if (listeners[i]==MyListener.class) { // Lazily create the event: if (myEvent == null) myEvent = new MyEvent(this , new Date()); ((MyListener)listeners[i+1]).doMyAction(myEvent); } } } /** * 做一些事件源應(yīng)該做的有意義的事,,然后通知監(jiān)聽器. * 這里只是一個(gè)示例方法. * 例如:MySource如果是一個(gè)按鈕,,則doSomething()就可以命名為click(), * 當(dāng)用戶點(diǎn)擊按鈕時(shí)調(diào)用click()方法. */ public void doSomething() { System.out.println("do something interesting here."); fireDoMyAction();//通知監(jiān)聽器 } } EventListenerList是特別需要說明的,,它內(nèi)部使用一個(gè)Object數(shù)組存放監(jiān)聽器。但是它并不是直接存放,,而是先存監(jiān)聽器的class類型,,然后再存監(jiān)聽器本身。即存放(MyListener.class , myListener),。一個(gè)Object數(shù)組可以存放多種類型的Listener,,如果還有一種監(jiān)聽器AnotherListener,那么(AnotherListener.class , anotherListener)也可以存放,。無論增刪都是兩個(gè)對象一同被添加或刪除,。上述代碼中的listenerList.add(MyListener.class , listener)或listenerList.remove(MyListener.class , listener),以及fireDoMyAction()中的"i-=2",就是這樣操作的,。 [參考資料]: [1] 《java 自定義事件》 : http://blog.csdn.net/qking93415981/archive/2007/08/29/1763757.aspx [2] 《Use EventListenerList to store event listener list》 : http://www./Code/Java/Swing-JFC/UseEventListenerListtostoreeventlistenerlist.htm [3] 《創(chuàng)建一個(gè)自定義事件》 : http://www./CN/Code/Java/Event/CreatingaCustomEvent.htm [4] 《java 自定義事件的觸發(fā)及監(jiān)聽》 : http://zhidao.baidu.com/question/50126506.html [5] 《關(guān)于觀察者模式的問題》 : http://www./topic/182643 [6] JDK1.6源代碼 [7] 《Java與模式》 : 閻宏
|
|