1. 絮絮叨叨
- 进行过Java图形界面编程的同学会发现,各种控件的点击、打开、关闭等操作,都注册了对应的事件监听器,并可以根据不同的事件执行不同操作。
- 例如,同样是button,点击
关闭
可以直接关闭窗口;点击登录
可以在后台实现用户名、密码的校验,并根据校验结果执行不同的操作。 - 在上面的例子中:button是事件源,点击操作是事件,事件发生后,根据事件执行不同的操作(关闭窗口、校验用户名及密码),这是监听器的行为。
总结起来
- 事件源:执行某些操作时,产生事件;事件源中注册了监听器,将产生的事件传给监听器,由监听器处理事件
- 事件:由事件源执行某些操作时产生,事件中包含事件源,这样监听器可以根据事件源执行特定的处理操作
- 监听器:很多事件的处理方法,根据事件或事件源,执行不同操作
2. 自己的理解
- 事件的监听、处理流程:
- 事件源、事件、监听器之间的关系:
- 事件源通过事件监听器注册方法,为自身添加事件监听器
- 事件监听器中,实现了事件的handler方法:根据传入的事件或事件的事件源,执行具体操作
- 事件源的某个动作,将(主动)触发事件监听器的handler方法处理事件
3. 编程示例
- 事件源: 事件监听器注册方法 + 具体操作,触发事件监听器的handler方法
package com.vivo.lucy.listener;
public class Animal {
private String name;
private AnimalListener animalListener;
public Animal(String name) {
this.name = name;
}
public void addAnimalListener(AnimalListener animalListener) {
this.animalListener = animalListener;
}
public void eat() {
System.out.println("event source: Trigger event —— " + name + " will eat!");
animalListener.eatEventHandler(new AnimalEvent(this));
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Animal dog = new Animal("dog");
// 为事件源添加监听器
AnimalListener listener = new AnimalListener();
dog.addAnimalListener(listener);
// 触发事件,会被事件监听器监听到
dog.eat();
}
}
- 事件: 继承Java自带的EventObject,自己只修改了其构造方法,打印了一些信息。
package com.vivo.lucy.listener;
import java.util.EventObject;
public class AnimalEvent extends EventObject {
public AnimalEvent(Object source) {
super(source);
Animal animal = (Animal) source;
System.out.println("event: Generate event —— " + animal.getName() + " is eating!");
}
}
- 事件监听器: 实现Java自带的EventListener,创建事件handler(入参为具体的事件)
package com.vivo.lucy.listener;
import java.util.EventListener;
import java.util.EventObject;
public class AnimalListener implements EventListener {
public void eatEventHandler(EventObject eventObject) {
// 从事件中获取事件源
Animal source = (Animal) eventObject.getSource();
// 打印事件源的名称
System.out.println("listener: Get event —— " + source.getName() + " is eating!");
}
}
- 执行结果如下:
- 虽然事件、事件源、监听器环环相扣,但是自己更喜欢按照下面的步骤实现事件监听
- 定义事件:事件中将包含事件源(可以通过构造函数设置)
- 定义监听器:监听器中有事件的handler方法,用于处理对应的事件
- 定义事件源:包含监听器注册方法、具体的操作(生成事件,触发监听器的handler方法)
4. 关于事件监听器
- EventListener是一个没有抽象方法的接口,一般JDK中的监听器接口是存在抽象方法的。
- 在为事件源注册监听器时,需要创建匿名类并实现对应的抽象方法。
- 例如,为java swing中的按钮注册监听器的代码如下
button1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
label.setText("按钮被单击了 "+(clicks++)+" 次");
}
});