【轉】java事件監聽機制

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

1.event object:事件狀態對象,用於listener的相應的方法之中做爲參數,通常存在與listerner的方法之中ide

2.event source:具體的事件源,好比說,你點擊一個button,那麼button就是event source,要想使button對某些事件進行響應,你就須要註冊特定的listener。函數

3.event listener:對每一個明確的事件的發生,都相應地定義一個明確的Java方法。這些方法都集中定義在事件監聽者(EventListener)接口中,這個接口要繼承 java.util.EventListener。 實現了事件監聽者接口中一些或所有方法的類就是事件監聽者。this

(我的理解:)spa

將須要監聽的對象封裝在自定義的事件狀態對象類(EventObject)中,這個類必須繼承java.util.EventObject。事件狀態對象做爲單參傳遞給應響應該事件的自定義監聽器方法中。該自定義監聽器需實現自定義監聽接口,實現此接口中以事件狀態對象爲參數的方法。發出某種特定事件的事件源:必須在類中實例化自定義的監聽器對象,當監聽到event object時,調用相應方法進行處理。線程

先看看jdk提供的event包:code

public interface EventListener:全部事件偵聽器接口必須擴展的標記接口。對象

public class EventObject extends Object implements Serializable
全部事件狀態對象都將從其派生的根類。 全部 Event 在構造時都引用了對象 "source",在邏輯上認爲該對象是最初發生有關 Event 的對象。
blog

 舉例:繼承

複製代碼
 1 //自定義的事件狀態對象類
 2 class MyEvent extends EventObject  
 3 {  
 4     private Object obj;  
 5     //此監聽對象能夠是自定義對象
 6     private String sName;  
 7     public MyEvent(Object source,String sName)  
 8     {   
 9         super(source);  
10         this.obj=source;  
11         this.sName=sName;  }  
12     public Object getObj()  
13     {   
14         return obj; 
15     }  
16     public String getsName()  
17     {   
18         return sName; 
19     }  
20 }  
21 //定義自定義監聽器接口,繼承EventListener
22 interface MyEventListener extends EventListener  
23 {   
24     void handleEvent (MyEvent me);   
25 }  
26 //定義事件源
27 class MyEventSource  
28 {   
29     private Vector list=new Vector();  
30     private String   sName  = "";  
31     public MyEventSource()  
32     {  
33         super();  
34     }  
35     public void addMyEventListener(MyEventListener me)  
36     {  
37         list.add(me);  
38     }  
39     public void deleteMyEventListener(MyEventListener me)  
40     {  
41         list.remove(me);  
42     }  
43     public void notifyMyEvent(MyEvent me)  
44     {   
45         Iterator it=list.iterator();  
46         while(it.hasNext())  
47         {  
48             //在類中實例化自定義的監聽器對象,並調用監聽器方法
49             ((MyEventListener) it.next()).handleEvent(me); 
50         }  
51     }  
52     public void setName(String str)  
53     {   boolean bool = false;  
54     if (str == null && sName != null)  
55         bool = true;  
56     else if (str != null && sName == null)  
57         bool = true;  
58     else if (!sName.equals(str))  
59         bool = true;  
60     this.sName = str;  
61     // 若是改變則執行事件  
62     if (bool)  
63         notifyMyEvent(new MyEvent(this, sName));  
64     }  
65     public String getsName()  
66     {   return sName;   }  
67 }  
68 //自定義監聽器,繼承自定義監聽接口
69 class Mylistener implements MyEventListener   
70 {   
71     public Map<Integer, String>  map =null;
72     public int i=0;
73 
74     public Mylistener(Map<Integer, String>  map) 
75     {  
76         this.map = map;
77         MyEventSource mes = new MyEventSource();  
78         mes.addMyEventListener(this);  
79         mes.setName("niu");  
80     }  
81 
82     //實現接口中的方法
83     public void handleEvent(MyEvent me)   
84     {   
85         System.out.println("me.getSource()  "+me.getSource());  
86         System.out.println("me.getsName()  "+me.getsName());
87         //此處能夠將寫,將監聽到的對象存入map中
88         map.put(++i, me.getsName());
89     }  
90 }  
91 //主函數
92 public class test2  
93 {   
94     public static void main(String args[])  
95     {   
96         Map<Integer, String>  map = new HashMap<Integer, String>();
97         Mylistener mylistener = new Mylistener(map);
98     }  
99 }
複製代碼

實際運用多是:

事件源是一個一直接收的線程,線程中一直監聽須要監聽的對象

在主函數中執行兩個線程

1.事件源的接收線程

2.一個計時器,每隔一段時間先試一下監聽到的對象個數

複製代碼
TimerTask task = new TimerTask() {
    @Override
    public void run() {
        System.out.println("size:"+DPMap.size());
        }
};

Calendar calendar = Calendar.getInstance();
Date firstTime = calendar.getTime();
Timer timer = new Timer();
timer.schedule(task, firstTime, 20*1000);
相關文章
相關標籤/搜索