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

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

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

    posts - 51, comments - 17, trackbacks - 0, articles - 9
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    java 事件機(jī)制

    Posted on 2007-04-13 09:22 chenweicai 閱讀(10343) 評(píng)論(14)  編輯  收藏

    java中的事件機(jī)制的參與者有3種角色:

    1.event object:就是事件產(chǎn)生時(shí)具體的“事件”,用于listener的相應(yīng)的方法之中,作為參數(shù),一般存在與listerner的方法之中

    2.event source:具體的接受事件的實(shí)體,比如說(shuō),你點(diǎn)擊一個(gè)button,那么button就是event source,這樣你必須使button對(duì)某些事件進(jìn)行相應(yīng),你就需要注冊(cè)特定的listener,比如說(shuō)MouseEvent之中的MouseClicked方法,這是他就必須有了add方法

    3.event listener:具體的對(duì)監(jiān)聽(tīng)的事件類(lèi),當(dāng)有其對(duì)應(yīng)的event object產(chǎn)生的時(shí)候,它就調(diào)用相應(yīng)的方法,進(jìn)行處理。在windows程序設(shè)計(jì)里邊這種相應(yīng)使用callback機(jī)制來(lái)實(shí)現(xiàn)的

    先看看jdk提供的event包:
    public interface EventListener:所有事件偵聽(tīng)器接口必須擴(kuò)展的標(biāo)記接口。
    public class EventObject extends Object implements Serializable

    所有事件狀態(tài)對(duì)象都將從其派生的根類(lèi)。 所有 Event 在構(gòu)造時(shí)都引用了對(duì)象 "source",在邏輯上認(rèn)為該對(duì)象是最初發(fā)生有關(guān) Event 的對(duì)象。

            在Java2處理事件時(shí),沒(méi)有采用dispatchEvent()-postEvent()-handleEvent()方式,采用了監(jiān)聽(tīng)器類(lèi),每個(gè)事件類(lèi)都有相關(guān)聯(lián)的監(jiān)聽(tīng)器接口。事件從事件源到監(jiān)聽(tīng)者的傳遞是通過(guò)對(duì)目標(biāo)監(jiān)聽(tīng)者對(duì)象的Java方法調(diào)用進(jìn)行的。

      對(duì)每個(gè)明確的事件的發(fā)生,都相應(yīng)地定義一個(gè)明確的Java方法。這些方法都集中定義在事件監(jiān)聽(tīng)者(EventListener)接口中,這個(gè)接口要繼承 java.util.EventListener。 實(shí)現(xiàn)了事件監(jiān)聽(tīng)者接口中一些或全部方法的類(lèi)就是事件監(jiān)聽(tīng)者。

      伴隨著事件的發(fā)生,相應(yīng)的狀態(tài)通常都封裝在事件狀態(tài)對(duì)象中,該對(duì)象必須繼承自java.util.EventObject。事件狀態(tài)對(duì)象作為單參傳遞給應(yīng)響應(yīng)該事件的監(jiān)聽(tīng)者方法中。發(fā)出某種特定事件的事件源的標(biāo)識(shí)是:遵從規(guī)定的設(shè)計(jì)格式為事件監(jiān)聽(tīng)者定義注冊(cè)方法,并接受對(duì)指定事件監(jiān)聽(tīng)者接口實(shí)例的引用。

    開(kāi)始之前首先問(wèn)個(gè)問(wèn)題:您熟悉java.util.EventObject 和java.util.EventListener兩個(gè)類(lèi)以及他們已有的子類(lèi)嗎?

    如果你已經(jīng)能夠熟練使用jdk為我們提供的事件監(jiān)聽(tīng)器,并且很熟悉MouseEvent, KeyEvent, WindowEvent等等這些jdk為我們準(zhǔn)備好的事件,那么想必你對(duì)java的事件機(jī)制已經(jīng)有所理解。但是也許你還是覺(jué)得雖然用起來(lái)沒(méi)什么問(wèn)題,但是原理還是有些糊涂,那么下面我們?cè)龠M(jìn)一步自己實(shí)現(xiàn)這些事件和監(jiān)聽(tīng)器,我們把這個(gè)取名為自定義事件。

    其實(shí)自定義事件在java中很有用處,我們有的時(shí)候想讓自己的程序產(chǎn)生一個(gè)事件,但有不希望(或者不可能)用鼠標(biāo),鍵盤(pán)之類(lèi)的輸入設(shè)備進(jìn)行操作,比如你寫(xiě)一個(gè)應(yīng)用程序,在這個(gè)程序中一旦收到郵件就對(duì)郵件進(jìn)行相關(guān)處理,對(duì)于“收到郵件”這個(gè)事件,jdk中就沒(méi)有定義。對(duì)于這樣的事件,以及對(duì)于這樣的事件的監(jiān)聽(tīng)器,我們只能自己動(dòng)手完成了。

    那么下面就以實(shí)例開(kāi)始我們這個(gè)“創(chuàng)新”的過(guò)程:首先,我們要明確jdk中需要的資源:類(lèi)EventObject作為父類(lèi)用來(lái)生成我們自己的事件類(lèi),接口EventListener用來(lái)實(shí)現(xiàn)我們自己的監(jiān)聽(tīng)器;剩下的事情就是如何注冊(cè)這些事件以及測(cè)試他們了。

    (1)       通過(guò)DemoEvent.java文件創(chuàng)建DemoEvent類(lèi),這個(gè)類(lèi)繼承EventObject。這個(gè)類(lèi)的構(gòu)造函數(shù)的參數(shù)傳遞了產(chǎn)生這個(gè)事件的事件源(比如各種控件),方法getSource用來(lái)獲得這個(gè)事件源的引用。

    DemoEvent.java

    package demo.listener;

     

    import java.util.EventObject;

     

    public class DemoEvent extends EventObject

    {

            Object obj;

            public DemoEvent(Object source)

            {

                   super(source);

                   obj = source;

            }

            public Object getSource()

            {

                   return obj;

            }

            public void say()

            {

                   System.out.println("This is say method...");

            }

    }

     

    (2)       定義新的事件監(jiān)聽(tīng)接口,該接口繼承自EventListener;該接口包含對(duì)DemeEvent事件的處理程序:

    DemoListener.java

    package demo.listener;

     

    import java.util.EventListener;

     

    public interface DemoListener extends EventListener

    {

           public void demoEvent(DemoEvent dm);

    }

     

    通過(guò)上面的接口我們?cè)俣x事件監(jiān)聽(tīng)類(lèi),這些類(lèi)具體實(shí)現(xiàn)了監(jiān)聽(tīng)功能和事件處理功能。回想一下上文中那四種實(shí)現(xiàn)方式,我們這里不正是使用了其中的第三種——外部類(lèi)寫(xiě)法的方式嗎?

    Listener1.java

    package demo.listener;

     

    public class Listener1 implements DemoListener

    {

           public void demoEvent(DemoEvent de)

           {

                  System.out.println("Inside listener1...");

           }

    }



    Listener2.java

    package demo.listener;

     

    public class Listener2 implements DemoListener

    {

           public void demoEvent(DemoEvent de)

           {

                  System.out.println("Inside listener2...");

           }

    }


    Listener3.java

    package demo.listener;

     

    public class Listener3 implements DemoListener

    {

           public void demoEvent(DemoEvent de)

           {

                  System.out.println("Inside listener3...");

           }

    }

     

    (3)       通過(guò)DemeSource..ava文件創(chuàng)造一個(gè)事件源類(lèi),它用一個(gè)java.utile.Vector對(duì)象來(lái)存儲(chǔ)所有的事件監(jiān)聽(tīng)器對(duì)象,存儲(chǔ)方式是通過(guò)addListener(..)這樣的方法。notifyDemeEvent(..)是觸發(fā)事件的方法,用來(lái)通知系統(tǒng):事件發(fā)生了,你調(diào)用相應(yīng)的處理函數(shù)(回調(diào)函數(shù))吧。

    DemoSource.java

     

    package demo.listener;

    import java.util.*;

     

    public class DemoSource

    {

           private Vector repository = new Vector();

           DemoListener dl;

           public DemoSource()

           {

     

           }

           public void addDemoListener(DemoListener dl)

           {

                  repository.addElement(dl);

           }

           public void notifyDemoEvent()

           {

                  Enumeration enum = repository.elements();

                  while(enum.hasMoreElements())

                  {

                        dl = (DemoListener)enum.nextElement();

                        dl.demoEvent(new DemoEvent(this));

                  }

           }

    }

     

     

                 

    (4)       好了,最后寫(xiě)一個(gè)測(cè)試程序測(cè)試一下我們自定義的事件吧,這段程序應(yīng)該不難理解吧:)

    TestDemo.java

     

    package demo.listener;

     

    public class TestDemo

    {

           DemoSource ds;

     

           public TestDemo()

           {

                  try{

                        ds = new DemoSource();

                        Listener1 l1 = new Listener1();

                        Listener2 l2 = new Listener2();

                        Listener3 l3 = new Listener3();

     

                        ds.addDemoListener(l1);

                        ds.addDemoListener(l2);

                        ds.addDemoListener(l3);

                        ds.addDemoListener(new DemoListener(){
                                   public void demoEvent(DemoEvent event){
                                             System.out.println("Method come from 匿名類(lèi)...");
                                   }
                           });

                        ds.notifyDemoEvent();

     

                  }catch(Exception ex)

                  {ex.printStackTrace();}

           }

     

           public static void main(String args[])

           {

                  new TestDemo();

           }

    }



    評(píng)論

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2007-09-29 15:33 by somesongs
    解惑啊,寫(xiě)得非常好,謝謝。
    本來(lái)自己還想邊學(xué)邊寫(xiě),但無(wú)法超越了。呵呵。

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2007-12-18 13:40 by hondz
    還是有收獲的,但是例子倒是沒(méi)啥看明白,初學(xué)可能是水平太次了吧,DemoEvent對(duì)象在哪里創(chuàng)建的呢?如果在事件處理器中調(diào)用say方法會(huì)不會(huì)拋空指針異常?

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2007-12-18 14:03 by hondz
    不好意思了,在notify方法里面創(chuàng)建的,完全明白了,謝謝!!

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2008-01-21 11:33 by 盧劍鳴
    淺顯易懂!贊!

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2008-11-24 19:51 by 路段的
    鳳飛飛

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2008-12-12 17:20 by 鮑鮑
    不錯(cuò)。謝謝樓主。

    # re: java 事件機(jī)制[未登錄](méi)  回復(fù)  更多評(píng)論   

    2009-03-30 10:33 by abc
    Observer pattern

    # re: java 事件機(jī)制[未登錄](méi)  回復(fù)  更多評(píng)論   

    2009-05-11 17:53 by neo
    恩 很好 贊一個(gè)

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2009-05-13 17:51 by 路人
    非常謝謝樓主!!!!

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2009-08-11 20:10 by hermit
    這個(gè)例子還是有些問(wèn)題的。主要是事件何時(shí)觸發(fā)應(yīng)該是由 DemoSource 自身決定的,所以,事件源 DemoSource 的通知方法 notifyDemoEvent 一般是私有的方法,或者若你想 DemoSource 可以有子類(lèi),那么設(shè)成protected。也就是 notifyDemoEvent 應(yīng)該由 DemoSource 在能夠發(fā)生DemoEvent 時(shí)自己來(lái)調(diào)用,而何時(shí)發(fā)生DemoEvent事件,是DemoSource 自身特點(diǎn)決定的,外部對(duì)象是不知道的。比如我們可以在 DemoEvent 中加一個(gè)屬性 demoValue,
    private int demoValue;
    public int getDemoValue() {
    return demoValue;
    }
    public void setDemoValue(int val) {
    this.demoValue = val;
    notifyDemoEvent(new DemoEvent(this));
    }
    這時(shí),外部對(duì)象 TestDemo 可以調(diào)用 ds.setDemoValue(1),就使DemoSource 觸發(fā)了事件,并通知各個(gè)監(jiān)聽(tīng)器處理事件。外部對(duì)象 TestDemo 不應(yīng)該調(diào)用 notifyDemoEvent 方法,它怎么知道什么時(shí)候應(yīng)該發(fā)生 DemoEvent 事件呢?

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2009-09-04 10:24 by zzw
    嗯,樓上有理,樓主也寫(xiě)的好

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2009-10-10 12:08 by 啊白
    受益了,感謝樓主

    # re: java 事件機(jī)制[未登錄](méi)  回復(fù)  更多評(píng)論   

    2014-11-13 15:03 by scott
    樓主總體來(lái)說(shuō)是不錯(cuò)的,我就想問(wèn)問(wèn)你有沒(méi)有想過(guò)為什么要“DemoEvent extends EventObject”,不這樣寫(xiě)行不?是運(yùn)行不了還是性能損失了?或者處于別的什么考慮寫(xiě)了這個(gè)?
    你為什么又要這樣寫(xiě)“DemoListener extends EventListener”,這個(gè)也是必須的嗎?
    我只能說(shuō)你在不求甚解的時(shí)候,已經(jīng)開(kāi)始誤人子弟了(有很多人讀了你的這篇博文,而且留言了)。網(wǎng)上有很多類(lèi)似的帖子,代碼幾乎都是一樣的。不知道是樓樓拷了別人的代碼,還是別人拷了樓樓的代碼,希望樓樓加油,寫(xiě)出更好的帖子。

    # re: java 事件機(jī)制  回復(fù)  更多評(píng)論   

    2015-04-29 15:17 by 莾s
    多虧看評(píng)論了。

    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲精品无码MV在线观看| 国产亚洲精品a在线观看app| 亚洲综合图色40p| 亚洲无限乱码一二三四区| 精品久久久久亚洲| 国产乱子影视频上线免费观看| 亚洲一本大道无码av天堂| 亚洲精品福利在线观看| 国产亚洲精品美女| 免费无码一区二区三区| 国产大片91精品免费看3| 免费国产一级特黄久久| 亚洲av午夜福利精品一区人妖| 亚洲中文字幕精品久久| 国产免费无码AV片在线观看不卡 | aa级一级天堂片免费观看| 亚洲国产精品自产在线播放| 亚洲国产午夜精品理论片| www在线观看播放免费视频日本| 免费观看美女用震蛋喷水的视频| 亚洲综合最新无码专区| 久久亚洲国产成人影院| 男人j进入女人j内部免费网站| 国产美女做a免费视频软件| 亚洲AV成人一区二区三区AV| 国产亚洲女在线线精品| h视频在线免费看| 亚洲一区爱区精品无码| 久久亚洲国产精品五月天| 综合一区自拍亚洲综合图区| 91成人在线免费视频| 最近中文字幕免费mv视频7| 亚洲国产精品一区二区第一页| 亚洲国产成人精品无码区花野真一 | 一本色道久久88—综合亚洲精品| 日本高清不卡aⅴ免费网站| 一个人免费视频在线观看www| 国产一区在线观看免费| 亚洲视频一区二区三区四区| 国产亚洲欧美日韩亚洲中文色| 91青青青国产在观免费影视|