观察者模式-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:
  1. package  wintys.event;    
  2. import  javax.swing.event.EventListenerList;    
  3. import  java.util.Date;    
  4. import  java.text.DateFormat;    
  5. import  java.text.SimpleDateFormat;    
  6.   
  7. /**   
  8. * Java的事件机制/自定义事件.   
  9. 运行结果:   
  10. do something interesting in source here.   
  11. listener detects [event]:wintys.event.MyEvent[source=wintys.event.MySource@18158   
  12. 59] [occur at]:2009-10-11 16:27:49   
  13. listener detects [event]:wintys.event.MyEvent[source=wintys.event.MySource@18158   
  14. 59] [occur at]:2009-10-11 16:27:49   
  15. * @version 2009-10-11   
  16. * @author 天堂露珠 (wintys@gmail.com)   
  17. * @see http://www.blogjava.net/wintys   
  18. */     
  19. class  MyEventTest{    
  20.      public   static   void  main(String[] args){    
  21.         MySource source =  new  MySource();    
  22.         MyListener myListener =  new  MyListener(){    
  23.              public   void  doMyAction(MyEvent e){    
  24.                 System.out.println( "listener detects "  + e);    
  25.             }    
  26.         };    
  27.         source.addMyListener(myListener);    
  28.         source.addMyListener(myListener);    
  29.         source.addMyListener(myListener);    
  30.         source.removeMyListener(myListener);    
  31.   
  32.         source.doSomething();    
  33.     }    
  34. }    
  35.   
  36. /**   
  37. * 自定义的事件.   
  38. * @version 2009-10-11   
  39. * @author 天堂露珠(wintys@gmail.com)   
  40. * @see http://www.blogjava.net/wintys   
  41. */     
  42. class  MyEvent  extends  java.util.EventObject{    
  43.      private  Date date; //记录事件发生的时间    
  44.   
  45.      public  MyEvent(Object source , Date date){    
  46.          super (source);    
  47.   
  48.          this .date = date;    
  49.     }    
  50.   
  51.      public  String toString(){    
  52.         DateFormat df =  new  SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );    
  53.         String dt = df.format(date);    
  54.   
  55.          return   "[event]:"  +  super .toString() +  " [occur at]:"  + dt;    
  56.     }    
  57. }    
  58.   
  59. /**   
  60. * 自定义事件监听器接口.   
  61. * @version 2009-10-11   
  62. * @author 天堂露珠(wintys@gmail.com)   
  63. * @see http://www.blogjava.net/wintys   
  64. */     
  65. interface  MyListener  extends  java.util.EventListener{    
  66.      void  doMyAction(MyEvent e);    
  67. }    
  68.   
  69. /**   
  70. * 自定义事件源.   
  71. * @version 2009-10-11   
  72. * @author 天堂露珠(wintys@gmail.com)   
  73. * @see http://www.blogjava.net/wintys   
  74. */     
  75. class  MySource{    
  76.      /**   
  77.      * 保存注册的监听器列表.   
  78.      * 子类可以使用它保存自己的事件监听器(非MyListener监听器)列表.   
  79.      */     
  80.      protected  EventListenerList listenerList =  new  EventListenerList();    
  81.      private  MyEvent myEvent =  null ; //fireDoMyAction()使用此变量    
  82.   
  83.      /**   
  84.      * 没有做任何事   
  85.      */     
  86.      public  MySource(){    
  87.     }    
  88.      /**   
  89.      * 添加一个MyListener监听器   
  90.      */     
  91.      public   void  addMyListener(MyListener listener){    
  92.         listenerList.add(MyListener. class  , listener);    
  93.     }    
  94.   
  95.      /**   
  96.      * 移除一个已注册的MyListener监听器.   
  97.      * 如果监听器列表中已有相同的监听器listener1、listener2,   
  98.      * 并且listener1==listener2,   
  99.      * 那么只移除最近注册的一个监听器。   
  100.      */     
  101.      public   void  removeMyListener(MyListener listener){    
  102.         listenerList.remove(MyListener. class  , listener);    
  103.     }    
  104.   
  105.      /**   
  106.      * @return 在此对象上监听的所有MyListener类型的监听器   
  107.      */     
  108.      public  MyListener[] getMyListeners(){    
  109.          return  (MyListener[])listenerList.getListeners(MyListener. class );    
  110.     }    
  111.   
  112.      //Winty:Copy directly from javax.swing.event.EventListenerList    
  113.      /*Notify all listeners that have registered interest for   
  114.        notification on this event type.  The event instance   
  115.        is lazily created using the parameters passed into   
  116.        the fire method.   
  117.      */     
  118.      protected   void  fireDoMyAction() {    
  119.           // getListenerList() Guaranteed to return a non-null array    
  120.          Object[] listeners = listenerList.getListenerList();    
  121.           // Process the listeners last to first, notifying    
  122.           // those that are interested in this event    
  123.          for  ( int  i = listeners.length- 2 ; i>= 0 ; i-= 2 ) {    
  124.              if  (listeners[i]==MyListener. class ) {    
  125.                  // Lazily create the event:    
  126.                  if  (myEvent ==  null )    
  127.                     myEvent =  new  MyEvent( this  ,  new  Date());    
  128.                 ((MyListener)listeners[i+ 1 ]).doMyAction(myEvent);    
  129.             }    
  130.         }    
  131.     }    
  132.   
  133.      /**   
  134.      * 做一些事件源应该做的有意义的事,然后通知监听器.   
  135.      * 这里只是一个示例方法.   
  136.      * 例如:MySource如果是一个按钮,则doSomething()就可以命名为click(),   
  137.      * 当用户点击按钮时调用click()方法.   
  138.      */     
  139.      public   void  doSomething() {    
  140.         System.out.println( "do something interesting here." );    
  141.   
  142.         fireDoMyAction(); //通知监听器    
  143.     }    
  144. }   


         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 飞熊 阅读(253) 评论(0)  编辑  收藏 所属分类: java设计模式


只有注册用户登录后才能发表评论。


网站导航:
 
<2010年1月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

文章分类

文章档案

收藏夹

搜索

最新评论

阅读排行榜

评论排行榜