监听器的介绍
- 监听器的概念
监听器就是实现特定接口的一个普通java类,这个类专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器的某个方法就会被执行。 - 监听器案例–监听window窗口的事件监听器
package lister;
import java.awt.Frame;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class ListerDemo1 {
/**
* java事件监听机制
* 1.事件监听涉及到三个组件:事件源、事件对象、事件监听器
* 2.当事件源上发生一个动作时,它会调用事件监听器的一个方法,并
* 在调用该方式时把事件对象传过去
* 开发人员在监听器中通过事件对象,就可以拿到事件源,从而对事件源进行操作
* @param args
*/
public static void main(String[] args) {
Frame f = new Frame();
f.setSize(400, 400);
f.setVisible(true);
//注册事件监听器,因为监听器是接口,所以这里使用了匿名内部类
f.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {}
@Override
public void windowIconified(WindowEvent e) {}
@Override
public void windowDeiconified(WindowEvent e) {}
@Override
public void windowDeactivated(WindowEvent e) {}
/**
* 当window窗体关闭时就会被WindowListener这个监听器听到
* 监听器就会调用WindowClosing方法处理窗体关闭时的动作
*/
@Override
public void windowClosing(WindowEvent e) {
Frame f = (Frame)e.getSource();//通过事件对象拿到事件源
System.out.println(f+"窗体正在关闭");//模拟对事件源处理
f.dispose();
}
@Override
public void windowClosed(WindowEvent e) {}
@Override
public void windowActivated(WindowEvent e) {}
});
}
}
.
3. 设计一个可以被别的监听对象监听的对象
一般我们都是写监听器去监听其它对象,现在我们设计一个对象可以被其它对象监听。我们可以按照严格的事件处理模型来设计一个对象,它就可以被监听,事件处理模型涉及到三个组件:事件源、时间对象、事件监听器。
下面我们按照事件处理模型来设计一个Person对象,代码如下:
package beanListen;
/**
* 设计一个Person类作为事件源,这个类的对象的行为可以被
* 其它的对象监听
* @author flb
*
*/
public class Person {
/**
* 在Person类中定义一个PersonListener变量来传递进来的监听器
*/
private PersonListener listener;
/**
* 设计Person的行为:eat
*/
public void eat() {
if(listener!=null) {
/**
* 调用监听器的doeat方法来监听Person类对象eat这个行为
* 将事件对象Event传递给doeat方法
* 事件对象封装了事件源,new Event(this)中的this代表的
* 的就是事件源(也就是Person对象)
*/
listener.doeat(new Event(this));
}
}
public void run() {
if(listener!=null) {
listener.dorun(new Event(this));
}
}
/**
* 这个方法是用来注册对Person类对象的行为进行监听的监听器
* @param listener
*/
public void registerListener(PersonListener listener) {
this.listener = listener;
}
}
/*一般监听器都是一个单独接口,这里就直接和事件源在一个类里了*/
interface PersonListener{
/**
* 这个方法是用来监听Person对象eat这个行为动作
* 当实现类实现doeat方法时就可以监听到Person对象eat这个行为
* @param e
*/
void doeat(Event e);
/**
* 这个方法是用来监听Person对象run这个行为的
* @param e
*/
void dorun(Event e);
}
/**
* 此类被用作事件对象:封装事件源
* 一般事件源也是一个单独的类,这里为了方便就和事件源在一个类了
* @author flb
*
*/
class Event{
/**
* 事件源(Person就是事件源)
*/
private Person source;
public Event() {
}
public Event(Person source) {
this.source = source;
}
public Person getSource() {
return source;
}
public void setSource(Person source) {
this.source = source;
}
}
经过这样的设计之后,Person对象就可以被其它对象监听了,测试代码如下:
package beanListen;
public class PersonTest {
public static void main(String[] args) {
Person p = new Person();
p.registerListener(new PersonListener() {
@Override
public void dorun(Event e) {
Person p = e.getSource();
System.out.println(p+"在跑步");
}
@Override
public void doeat(Event e) {
Person p = e.getSource();
System.out.println(p+"在吃东西");
}
});
p.eat();
p.run();
}
}
运行结果:
总结:
事件源要想被监听,就得注册事件监听器,然后在要被监听的方法(行为)中去调用监听器的响应方法,并把事件对象传过去
一个监听器通常只能监听一个对象,所以我们要根据监听的事件类型实现相应的监听器接口。