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++)+" 次"); } });