监听实例中的方法是在事件发生后才会执行的。并不是在事件是执行。如果想对事件发生时的代码修改,需要在类中找到产生事件的方法。
在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,如果你的监听器方法不会用到事件源对象的信息,那么你就可以不传递事件对象,那么就不用编写事件对象类了。事件源既产生事件,也执行事件处理方法,监视器是其暴露出来让我们编写的事件处理方法而已。
应用场景:创建事件源实例后,调用实例中会产生事件的方法,来激活已经添加的监听器实例,从而按照监听器方法处理。
比如在一个线程中接收数据,当接收到特定字节时就会调用事件源的方法来产生事件对象,从而激活监听器实例中的方法。