熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java中使用觀察者模式實現自定義事件

2022-06-13   來源: Java核心技術 

  MyEventTestjava:

  package wintysevent;

  import javaxswingeventEventListenerList;

  import javautilDate;

  import javatextDateFormat;

  import javatextSimpleDateFormat;

  /**

  * Java的事件機制/自定義事件

  運行結果:

  do something interesting in source here

  listener detects [event]:wintyseventMyEvent[source=wintyseventMySource@

  ] [occur at]: ::

  listener detects [event]:wintyseventMyEvent[source=wintyseventMySource@

  ] [occur at]: ::

  * @version

  * @author 天堂露珠 ()

  * @see

  */

  class MyEventTest{

  public static void main(String[] args){

  MySource source = new MySource();

  MyListener myListener = new MyListener(){

  public void doMyAction(MyEvent e){

  Systemoutprintln(listener detects + e);

  }

  };

  sourceaddMyListener(myListener);

  sourceaddMyListener(myListener);

  sourceaddMyListener(myListener);

  sourceremoveMyListener(myListener);

  sourcedoSomething();

  }

  }

  /**

  * 自定義的事件

  * @version

  * @author 天堂露珠()

  * @see

  */

  class MyEvent extends javautilEventObject{

  private Date date;//記錄事件發生的時間

  public MyEvent(Object source Date date){

  super(source);

  thisdate = date;

  }

  public String toString(){

  DateFormat df = new SimpleDateFormat(yyyyMMdd HH:mm:ss);

  String dt = dfformat(date);

  return [event]: + supertoString() + [occur at]: + dt;

  }

  }

  /**

  * 自定義事件監聽器接口

  * @version

  * @author 天堂露珠()

  * @see

  */

  interface MyListener extends javautilEventListener{

  void doMyAction(MyEvent e);

  }

  /**

  * 自定義事件源

  * @version

  * @author 天堂露珠()

  * @see

  */

  class MySource{

  /**

  * 保存注冊的監聽器列表

  * 子類可以使用它保存自己的事件監聽器(非MyListener監聽器)列表

  */

  protected EventListenerList listenerList = new EventListenerList();

  private MyEvent myEvent = null;//fireDoMyAction()使用此變量

  /**

  * 沒有做任何事

  */

  public MySource(){

  }

  /**

  * 添加一個MyListener監聽器

  */

  public void addMyListener(MyListener listener){

  listenerListadd(MyListenerclass listener);

  }

  /**

  * 移除一個已注冊的MyListener監聽器

  * 如果監聽器列表中已有相同的監聽器listenerlistener

  * 並且listener==listener

  * 那麼只移除最近注冊的一個監聽器

  */

  public void removeMyListener(MyListener listener){

  listenerListremove(MyListenerclass listener);

  }

  /**

  * @return 在此對象上監聽的所有MyListener類型的監聽器

  */

  public MyListener[] getMyListeners(){

  return (MyListener[])listenerListgetListeners(MyListenerclass);

  }

  //Winty:Copy directly from javaxswingeventEventListenerList

  /*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 nonnull array

  Object[] listeners = listenerListgetListenerList();

  // Process the listeners last to first notifying

  // those that are interested in this event

  for (int i = listenerslength; i>=; i=) {

  if (listeners[i]==MyListenerclass) {

  // Lazily create the event:

  if (myEvent == null)

  myEvent = new MyEvent(this new Date());

  ((MyListener)listeners[i+])doMyAction(myEvent);

  }

  }

  }

  /**

  * 做一些事件源應該做的有意義的事然後通知監聽器

  * 這裡只是一個示例方法

  * 例如:MySource如果是一個按鈕則doSomething()就可以命名為click()

  * 當用戶點擊按鈕時調用click()方法

  */

  public void doSomething() {

  Systemoutprintln(do something interesting here);

  fireDoMyAction();//通知監聽器

  }

  }

  EventListenerList是特別需要說明的它內部使用一個Object數組存放監聽器但是它並不是直接存放而是先存監聽器的class類型然後再存監聽器本身即存放(MyListenerclass myListener)一個Object數組可以存放多種類型的Listener如果還有一種監聽器AnotherListener那麼(AnotherListenerclass anotherListener)也可以存放無論增刪都是兩個對象一同被添加或刪除上述代碼中的listenerListadd(MyListenerclass listener)或listenerListremove(MyListenerclass listener)以及fireDoMyAction()中的i=就是這樣操作的


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