觀察者模式-Java自定義事件
核心提示:觀察者模式-Java自定義事件 [正文]: MyEventTest.java: package wintys.event; import javax.swing.event.EventListenerList; import java.util.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; /** *Java的事件機制/自定義事件. 運
觀察者模式-Java自定義事件?
MyEventTest.java:
觀察者模式-Java自定義事件?
MyEventTest.java:
- package ?wintys.event;? ??
- import ?javax.swing.event.EventListenerList;? ??
- import ?java.util.Date;? ??
- import ?java.text.DateFormat;? ??
- import ?java.text.SimpleDateFormat;? ??
- ??
- /**? ?
- *?Java的事件機制/自定義事件.? ?
- 運行結果:? ?
- 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?天堂露珠?(wintys@gmail.com)? ?
- *?@see?http://www.aygfsteel.com/wintys? ?
- */ ? ??
- 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?天堂露珠(wintys@gmail.com)? ?
- *?@see?http://www.aygfsteel.com/wintys? ?
- */ ? ??
- class ?MyEvent? extends ?java.util.EventObject{? ??
- ???? private ?Date?date; //記錄事件發生的時間? ??
- ??
- ???? 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;? ??
- ????}? ??
- }? ??
- ??
- /**? ?
- *?自定義事件監聽器接口.? ?
- *?@version?2009-10-11? ?
- *?@author?天堂露珠(wintys@gmail.com)? ?
- *?@see?http://www.aygfsteel.com/wintys? ?
- */ ? ??
- interface ?MyListener? extends ?java.util.EventListener{? ??
- ???? void ?doMyAction(MyEvent?e);? ??
- }? ??
- ??
- /**? ?
- *?自定義事件源.? ?
- *?@version?2009-10-11? ?
- *?@author?天堂露珠(wintys@gmail.com)? ?
- *?@see?http://www.aygfsteel.com/wintys? ?
- */ ? ??
- class ?MySource{? ??
- ???? /**? ?
- ?????*?保存注冊的監聽器列表.? ?
- ?????*?子類可以使用它保存自己的事件監聽器(非MyListener監聽器)列表.? ?
- ?????*/ ? ??
- ???? protected ?EventListenerList?listenerList?=? new ?EventListenerList();? ??
- ???? private ?MyEvent?myEvent?=? null ; //fireDoMyAction()使用此變量? ??
- ??
- ???? /**? ?
- ?????*?沒有做任何事? ?
- ?????*/ ? ??
- ???? public ?MySource(){? ??
- ????}? ??
- ???? /**? ?
- ?????*?添加一個MyListener監聽器? ?
- ?????*/ ? ??
- ???? public ? void ?addMyListener(MyListener?listener){? ??
- ????????listenerList.add(MyListener. class ?,?listener);? ??
- ????}? ??
- ??
- ???? /**? ?
- ?????*?移除一個已注冊的MyListener監聽器.? ?
- ?????*?如果監聽器列表中已有相同的監聽器listener1、listener2,? ?
- ?????*?并且listener1==listener2,? ?
- ?????*?那么只移除最近注冊的一個監聽器。? ?
- ?????*/ ? ??
- ???? public ? void ?removeMyListener(MyListener?listener){? ??
- ????????listenerList.remove(MyListener. class ?,?listener);? ??
- ????}? ??
- ??
- ???? /**? ?
- ?????*?@return?在此對象上監聽的所有MyListener類型的監聽器? ?
- ?????*/ ? ??
- ???? 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);? ??
- ????????????}? ??
- ????????}? ??
- ????}? ??
- ??
- ???? /**? ?
- ?????*?做一些事件源應該做的有意義的事,然后通知監聽器.? ?
- ?????*?這里只是一個示例方法.? ?
- ?????*?例如:MySource如果是一個按鈕,則doSomething()就可以命名為click(),? ?
- ?????*?當用戶點擊按鈕時調用click()方法.? ?
- ?????*/ ? ??
- ???? public ? void ?doSomething()?{? ??
- ????????System.out.println( "do?something?interesting?here." );? ??
- ??
- ????????fireDoMyAction(); //通知監聽器? ??
- ????}? ??
- }???
?????????EventListenerList是特別需要說明的,它內部使用一個Object數組存放監聽器。但是它并不是直接存放,而是先存監聽器的class類型,然后再存監聽器本身。即存放(MyListener.class , myListener)。一個Object數組可以存放多種類型的Listener,如果還有一種監聽器AnotherListener,那么(AnotherListener.class , anotherListener)也可以存放。無論增刪都是兩個對象一同被添加或刪除。上述代碼中的listenerList.add(MyListener.class , listener)或listenerList.remove(MyListener.class , listener),以及fireDoMyAction()中的"i-=2",就是這樣操作的。
posted on 2010-01-17 18:15 飛熊 閱讀(268) 評論(0) 編輯 收藏 所屬分類: java設計模式