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

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐