監聽實例中的方法是在事件發生后才會執行的。並不是在事件是執行。如果想對事件發生時的代碼修改,需要在類中找到產生事件的方法。
在java中時常會有使用到監聽的場景,我覺得這其實就是對接口(interface)的活用。
事件源:就是產生事件的對象(是實例),就是要被監聽的對象;
監聽器: 就是一個接口;
事件對象:就是一個javabean,用來封裝事件的信息,比如:產生事件的對象,對事件的描述之類的。不是必須的。
在事件源中,當事件源中的監聽事件發生時(即創建了事件對象),就要調用被傳入的監聽器實例(自己實現)的方法。這就是回調。
在事件源對應的類中要設置添加被實現的監聽器實例。
下面是個簡單的demo:
import java.util.EventListener;
import java.util.EventObject;
import java.util.Iterator;
import java.util.Vector;
//事件源
public class Test {
private TestListener testListener;//這樣只能存放一個監聽器實例,用Vetoc
private Vector<Object> vector=new Vector<Object>();//同步訪問
private final int TestListener=1;
//添加監聽器
public void addTestListener(TestListener l) {
vector.add(l);
}
//去除監聽器
public void removeTestListener(TestListener t) {
vector.remove(t);
}
//產生事件的方法
public void createTestEvent() {
/*
* do something
* */
TestEvent testEvent=new TestEvent(this,1);
notifyListener(testEvent,TestListener);
}
//每個會產生事件對象的方法都要調用
public void notifyListener(TestEvent t,int listenerState) {
//在vector數組中尋找對應的監聽器實例,並將事件傳遞給它
Iterator<Object> it=vector.iterator();
while(it.hasNext()) {
Object object=it.next();
switch(listenerState) {
case TestListener:
if(object instanceof TestListener) {
((TestListener) object).handle(t);
};
default:;
}
}
}
//其他產生事件的方法
}
//監聽器
public interface TestListener extends EventListener{
public void handle(TestEvent e);
}
//事件對象
class TestEvent extends EventObject{
private int state;//可以用來標記不同的的事件,如點擊事件,鼠標事件,窗口事件等根據這來調用不同監聽器的方法
public TestEvent(Object source,int state) {
super(source);
this.state=state;
}
public void setSource(Object source) {
super.source=source;
}
public Object getSource() {
return super.source;
}
public void setState(int state) {this.state=state;}
public int getState() {return this.state;}
}
從上面可以看出,事件對象只是一個用來封裝事件源信息的javabean,如果你的監聽器方法不會用到事件源對象的信息,那么你就可以不傳遞事件對象,那么就不用編寫事件對象類了。事件源既產生事件,也執行事件處理方法,監視器是其暴露出來讓我們編寫的事件處理方法而已。
應用場景:創建事件源實例后,調用實例中會產生事件的方法,來激活已經添加的監聽器實例,從而按照監聽器方法處理。
比如在一個線程中接收數據,當接收到特定字節時就會調用事件源的方法來產生事件對象,從而激活監聽器實例中的方法。