熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

淺析Java與C#的事件處理機制(一)

2022-06-13   來源: .NET編程 

  Java與C#的事件處理都是實現了事件源事件響應者機制但又不完全相同Java實現的是一種事件源與事件響應者兩級實體對象方式這裡的事件響應者也是事件監聽者而C#實現的是一種事件源代理事件響應者三級實體對象方式下面就這兩種方式來具體說明

  Java事件處理

  從概念上講事件是一種在源對象監聽者對象之間某種狀態發生變化的傳遞機制事件有許多不同的用途例如在Windows系統中常要處理的鼠標事件窗口邊界改變事件鍵盤事件等在Java中則是定義了一個普通的可擴充的事件機制這種機制能夠

  對事件類型和傳遞的模型的定義和擴充提供一個公共框架並適合於廣泛的應用

  與Java語言和環境有較高的集成度

  事件能被描述環境捕獲和觸發

  能使其它構造工具采取某種技術在設計時直接控制事件以及事件源和事件監聽者之間的聯系

  事件機制本身不依賴於復雜的開發工具

  事件從事件源到監聽者的傳遞是通過對目標監聽者對象的Java方法調用進行的 對每個明確的事件的發生都相應地定義一個明確的Java方法這些方法都集中定義在事件監聽者(EventListener)接口中這個接口要繼承javautilEventListener實現了事件監聽者接口中一些或全部方法的類就是事件監聽者 伴隨著事件的發生相應的狀態通常都封裝在事件狀態對象中該對象必須繼承自javautilEventObject事件狀態對象作為單參傳遞給應響應該事件的監聽者方法中發出某種特定事件的事件源的標識是遵從規定的設計格式為事件監聽者定義注冊方法並接受對指定事件監聽者接口實例的引用有時事件監聽者不能直接實現事件監聽者接口或者還有其它的額外動作時就要在一個源與其它一個或多個監聽者之間插入一個事件適配器類的實例來建立它們之間的聯系

  事件狀態對象(Event State Object)

  與事件發生有關的狀態信息一般都封裝在一個事件狀態對象中這種對象是javautilEventObject的子類按設計習慣這種事件狀態對象類的名應以Event結尾例如

  public class MouseMovedExampleEvent extends javautilEventObject
  {
   protected int x y
   /* 創建一個鼠標移動事件MouseMovedExampleEvent */
   MouseMovedExampleEvent(javaawtComponent source Point location)
   {
    super(source);
    x = locationx;
    y = locationy;
   }
   /* 獲取鼠標位置*/
   public Point getLocation()
   {
    return new Point(x y);
   }
  }

  事件監聽者接口(EventListener Interface)與事件監聽者

  由於Java事件模型是基於方法調用因而需要一個定義並組織事件操縱方法的方式事件操縱方法都被定義在繼承了javautilEventListener類的EventListener接口中按規定EventListener接口的命名要以Listener結尾任何一個類如果想操縱在EventListener接口中定義的方法都必須以實現這個接口方式進行這個類也就是事件監聽者例如

  /*先定義了一個鼠標移動事件對象*/
  public class MouseMovedExampleEvent extends javautilEventObject
  {
   // 在此類中包含了與鼠標移動事件有關的狀態信息
   
  }
  /*定義了鼠標移動事件的監聽者接口*/
  interface MouseMovedExampleListener extends javautilEventListener
  {
   /*在這個接口中定義了鼠標移動事件監聽者所應支持的方法*/
   void mouseMoved(MouseMovedExampleEvent mme);
  }

  在接口中只定義方法名方法的參數和返回值類型上面接口中的mouseMoved方法的具體實現是在下面的ArbitraryObject類中定義的

  class ArbitraryObject implements MouseMovedExampleListener
  {
   public void mouseMoved(MouseMovedExampleEvent mme){ }
  }

  ArbitraryObject就是MouseMovedExampleEvent事件的監聽者

  事件監聽者的注冊與注銷

  為了各種可能的事件監聽者把自己注冊入合適的事件源中建立源與事件監聽者間的事件流事件源必須為事件監聽者提供注冊和注銷的方法在前面的bound屬性介紹中已看到了這種使用過程在實際中事件監聽者的注冊和注銷要使用標准的設計格式

  public void add< ListenerType>(< ListenerType> listener)
  public void remove< ListenerType>(< ListenerType> listener)

  首先定義了一個事件監聽者接口

  public interface ModelChangedListener extends javautilEventListener
  {
   void modelChanged(EventObject e);
  }

  接著定義事件源類

  public abstract class Model
  {
   private Vector listeners = new Vector(); // 定義了一個儲存事件監聽者的數組
   /*上面設計格式中的< ListenerType>在此處即是下面的ModelChangedListener*/
   public synchronized void addModelChangedListener(ModelChangedListener mcl)
   {
    listenersaddElement(mcl); }//把監聽者注冊入listeners數組中
    public synchronized void removeModelChangedListener(ModelChangedListener mcl)
    {
     listenersremoveElement(mcl); file://把監聽者從listeners中注銷
    }
    /*以上兩個方法的前面均冠以synchronized是因為運行在多線程環境時可能同時有幾個對象同時要進行注冊和注銷操作使用  synchronized來確保它們之間的同步開發工具或程序員使用這兩個方法建立源與監聽者之間的事件流*/
    protected void notifyModelChanged() {/**事件源使用本方法通知監聽者發生了modelChanged事件*/
    Vector l;
    EventObject e = new EventObject(this);
    /* 首先要把監聽者拷貝到l數組中凍結EventListeners的狀態以傳遞事件這樣來確保在事件傳遞到所有監聽者之前已接收了事件的目標監聽者的對應方法暫不生效*/
    synchronized(this)
    {
     l = (Vector)listenersclone();
    }
    for (int i = ; i < lsize(); i++)
    {
     /* 依次通知注冊在監聽者隊列中的每個監聽者發生了modelChanged事件並把事件狀態對象e作為參數傳遞給監聽者隊列中的每個監聽者*/
     ((ModelChangedListener)lelementAt(i))modelChanged(e);
    }
   }
  }


From:http://tw.wingwit.com/Article/program/net/201311/14840.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.