<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 117  文章 - 72  trackbacks - 0

    聲明:原創作品(標有[原]字樣)轉載時請注明出處,謝謝。

    常用鏈接

    常用設置
    常用軟件
    常用命令
     

    訂閱

    訂閱

    留言簿(7)

    隨筆分類(130)

    隨筆檔案(123)

    搜索

    •  

    積分與排名

    • 積分 - 155595
    • 排名 - 391

    最新評論

    [關鍵字]:java,design pattern,設計模式,《Java與模式》學習,閻宏,Ph.D,Factory,觀察者模式,observer,event,java自定義事件,java事件機制,事件模型,事件監聽,訂閱發布,事件消息
    [環境]:StarUML5.0 + JDK6
    [作者]:天堂露珠 (wintys@gmail.comhttp://m.tkk7.com/wintys
    [正文]:

    java_event     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://m.tkk7.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://m.tkk7.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://m.tkk7.com/wintys
    */
    interface MyListener extends java.util.EventListener{
        void doMyAction(MyEvent e);
    }

    /**
    * 自定義事件源.
    * @version 2009-10-11
    * @author 天堂露珠(wintys@gmail.com)
    * @see http://m.tkk7.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",就是這樣操作的。

     

    [參考資料]:

      [1] 《java 自定義事件》 : http://blog.csdn.net/qking93415981/archive/2007/08/29/1763757.aspx

      [2] 《Use EventListenerList to store event listener list》 : http://www.java2s.com/Code/Java/Swing-JFC/UseEventListenerListtostoreeventlistenerlist.htm

      [3] 《創建一個自定義事件》 : http://www.java2s.com/CN/Code/Java/Event/CreatingaCustomEvent.htm

      [4] 《java 自定義事件的觸發及監聽》 : http://zhidao.baidu.com/question/50126506.html

      [5] 《關于觀察者模式的問題》 : http://www.javaeye.com/topic/182643

      [6]  JDK1.6源代碼

      [7] 《Java與模式》 : 閻宏

     

    [附件]:

    event_MyEventTest.zip :

    EventListener.java
    EventListenerList.java
    EventObject.java
    MyEventTest.java

    原創作品,轉載請注明出處。
    作者:Winty (wintys@gmail.com)
    博客:http://m.tkk7.com/wintys
    posted on 2009-10-11 20:32 天堂露珠 閱讀(3868) 評論(2)  編輯  收藏 所屬分類: Pattern

    FeedBack:
    # re: [原]觀察者模式-Java自定義事件 2009-10-12 12:04 Scorpio Zhen
    做個標記  回復  更多評論
      
    # re: [原]觀察者模式-Java自定義事件 2009-10-12 16:58 document
    good...  回復  更多評論
      
    主站蜘蛛池模板: 亚洲国产成人精品无码区二本| 亚洲高清中文字幕免费| 美女被免费视频网站a| 午夜无遮挡羞羞漫画免费| 亚洲一卡二卡三卡四卡无卡麻豆| 精品福利一区二区三区免费视频 | 亚洲AV无码一区二区三区久久精品| 亚洲性线免费观看视频成熟| 亚洲六月丁香六月婷婷蜜芽| 一个人免费观看视频www| 亚洲乱码一区二区三区国产精品| 成人毛片免费观看视频在线| 爱情岛论坛亚洲品质自拍视频网站| gogo全球高清大胆亚洲| 中国内地毛片免费高清| 久热综合在线亚洲精品| 国产成人精品免费视频动漫| 亚洲乱码在线观看| 亚洲高清免费视频| 暖暖免费日本在线中文| 亚洲香蕉免费有线视频| 亚洲av无码乱码在线观看野外 | 国产在线19禁免费观看| 羞羞漫画页面免费入口欢迎你| 亚洲毛片av日韩av无码| 国产午夜无码精品免费看| 亚洲大片免费观看| 四虎影视永久免费观看网址| 中国极品美軳免费观看| 7777久久亚洲中文字幕蜜桃| 成人永久免费福利视频网站| 二区久久国产乱子伦免费精品 | 国产亚洲综合久久| 国产亚洲福利精品一区| 日韩欧毛片免费视频| 一级A毛片免费观看久久精品| 亚洲AV日韩AV永久无码下载| 日韩精品无码人妻免费视频| 中国极品美軳免费观看| 亚洲人成未满十八禁网站| 国外亚洲成AV人片在线观看|