Java事件机制

事件机制的三个角色

  • 事件源,表示事件发生的起源
  • 事件对象,持有一个事件源
  • 事件处理的监听器,事件发生时具体的处理回调,需要用户去实现这个接口

在Java AWT中,事件机制广泛应用。我们将模仿点击事件,构建完整的源->触发->处理过程。UML类图如下:


image.png

首先,创建一个事件对象。

import java.util.EventObject;

public class ClickEvent extends EventObject {
    private EventSource src;
    /**
     * Constructs a prototypical Event.
     *
     * @param source The object on which the Event initially occurred.
     * @throws IllegalArgumentException if source is null.
     */
    public ClickEvent(EventSource source) {
        super(source);
        this.src = source;
    }
}

ClickEvent继承自EventObject,持有一个EventSource的引用,在构造点击事件时必须指明事件源。
事件源定义:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

public class EventSource {
    private Semaphore semaphore = new Semaphore(1);
    private final List<ClickEventListener> listeners = new ArrayList<>();
    
    public void addListener(ClickEventListener listener) throws InterruptedException {
        semaphore.acquire(1);
        listeners.add(listener);
        semaphore.release(1);
    }
    
    public void removeListener(ClickEventListener listener) throws InterruptedException {
        semaphore.acquire(1);
        if(!listeners.isEmpty())
            listeners.remove(listener);
        semaphore.release(1);
    }
    
    protected void actionPerformed() throws InterruptedException {
        semaphore.acquire(1);
        ClickEvent event = new ClickEvent(this);
        for (ClickEventListener listener : listeners) {
            listener.click(event);
        }
        semaphore.release(1);
    }
    
}

事件源可以添加一组监听器,绑定的一组监听器在事件触发之后,会将监听器的具体动作逐一执行。
定义一个简单的点击事件监听器:

public interface ClickEventListener extends EventListener {
    void click(ClickEvent e);
}

ClickEventListener继承自EventListener,查看源码发现EventListener是一个空接口,因此定义的事件监听器将是一个SAM interface,如果还不清楚SAM interface的概念,请查看我之前的一篇文章Functional Programming in Java 8,因此可以使用lambda表达式来实现这个监听器接口。
最后,我们需要完成一次完整的调用处理:

public class Main {
    public static void main(String[] args) {
        EventSource source = new EventSource();
        try {
            source.addListener((e) -> System.out.println("Click event performed!"));
            source.actionPerformed();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

事件处理机制在某种程度上与发布-订阅模式非常相似,事件监听器的角色与观察者类似,事件源则充当了被观察对象。事件源状态触发后,主动发起通知给监听器,监听器完成各种后续处理。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,342评论 19 139
  • 以下文章为转载,对理解JavaScript中的事件处理机制很有帮助,浅显易懂,特分享于此。 什么是事件? 事件(E...
    jxyjxy阅读 3,155评论 1 10
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 12,140评论 6 13
  • 与界面编程紧密相关的就是事件处理机制,当用户在程序界面上执行各种操作时,应用程序必须为用户动作提供响应动作,这种响...
    GB_speak阅读 2,372评论 0 3
  • 01 去音乐节看朴树时,遇到个小姑娘,叫素素。一米五的小丫头,背着包从湘潭一路坐车到长沙。看起来小小的一只,脸上永...
    晨希_阅读 642评论 3 10

友情链接更多精彩内容