一文带你学会Java事件机制

目录
  • 委托事件模型
  • 核心组件
  • 总结

相信做 Java 开发的朋友,大多都是学习过或至少了解过 Java GUI 编程的,其中有大量的事件和控件的绑定,当我们需要在点击某个按钮实现某些操作的时候,其实就是为这个按钮控件注册了一个合理处理点击事件的监听器。此外,Spring Framework 中也有许多用到事件处理机制的地方,如 ApplicationContextEvent 及其子类,代表着容器的启动、停止、关闭、刷新等事件。本文会为大家介绍 Java 的事件处理机制,也会用示例来说明,如何优雅地触发并处理一个自定义事件。

委托事件模型

Java 自 1.1 之后基于委托事件模型,定义了标准一致的获取和处理事件的方式。它的思路非常简单,由事件源发起特定事件,并将事件发送给一个或多个事件监听器,而监听器在此过程中一直处于等待状态,直到接收到该事件,然后处理事件并返回。实现起来也很简单:

  • 定义事件
  • 实现特定的监听器接口,接收特定类型的事件
  • 实现代码,注册(或解除)监听器作为特定事件类型的接收者
  • 在恰当的时机触发事件

核心组件

在 Java 的这个事件处理机制中,包含三个核心组件:

  • 事件 事件对象,描述相位的变化。比如在 GUI 中一个动作的点击,在 Spring Framework 中容器的启停,更多的诸如电脑的开机、关机、休眠,缓存的过期,公众号的关注、取关等等。
  • 事件源 可以是任意对象,它具备触发事件的能力。一般在这个对象中注册(或解除)监听器,此外事件的触发通常也在这里。一个源可能产生多个不同类的事件,要为不同的事件类型分别注册事件监听器,而每个事件类型可以注册一个或多个监听器。
  • 事件监听器 一个实现了特定接口的类,它需要实现对针对特定事件的具体处理方法,且必须被注册到该特定事件上。

那么问题来了,我们如何优雅地触发并处理一个自定义事件呢?

自定义事件

在 Java 中自定义事件非常简单。考虑到现在各个应用中都有绑定社交账号的需求,我们就以此为例,在社交账号绑定或者解绑时简单的打印一条记录。

首先定义一个事件对象,代码如下:

public class SocialEvent extends EventObject {
    private static final long serialVersionUID = -5473622737706032666L;
    public static final int WECHAT_BIND = 1;
    public static final int WECHAT_UNBIND = 2;
    public static final int WEIBO_BIND = 3;
    public static final int WEIBO_UNBIND = 4;
    private int socialType;
    public SocialEvent(Object source, int socialType) {
        super(source);
        this.socialType = socialType;
    }
    public int getSocialType() {
        return socialType;
    }
    public void setSocialType(int socialType) {
        this.socialType = socialType;
    }
}

事件类必须是 EventObject 的子类。值得一提的是,事件对象通常代表一类而非一个事件,即合理的做法是将一类事件而非一个事件概念融合起来。

接下来,我们实现一套事件处理逻辑,即事件监听器:

public class SocialEventListener implements EventListener {
    public void onSocialChanged(SocialEvent event) {
        switch (event.getSocialType()) {
            case SocialEvent.WECHAT_BIND:
                System.out.println("Wechat bind.");
                break;
            case SocialEvent.WECHAT_UNBIND:
                System.out.println("Wechat unbind.");
                break;
            case SocialEvent.WEIBO_BIND:
                System.out.println("Weibo bind.");
                break;
            case SocialEvent.WEIBO_UNBIND:
                System.out.println("Weibo unbind.");
                break;
            default:
                System.out.println("Bad social type.");
                break;
        }
    }
}

此外,我们需要一个事件源:

public class Social {
    private List<SocialEventListener> listeners;
    public void addListener(SocialEventListener listener) {
        if (listeners == null) {
            listeners = new ArrayList<>();
        }
        listeners.add(listener);
    }
    public void removeListener(SocialEventListener listener) {
        if (listeners != null) {
            listeners.remove(listener);
        }
    }
    public void emitEvent(SocialEvent event) {
        for (SocialEventListener listener : listeners) {
            listener.onSocialChanged(event);
        }
    }
    public List<SocialEventListener> getListeners() {
        return listeners;
    }
    public void setListeners(List<SocialEventListener> listeners) {
        this.listeners = listeners;
    }
}

在这里,我们定义了专门的类 Social 作为事件源,事实上,可以在任意其他的类中实现事件的触发与注册逻辑,比如启动类中。

顺便说一句,我们在 Java GUI 编程中,通常只需要为组件注册事件监听器,而无需考虑事件的触发逻辑,这是因为它们的事件是由系统自动触发的。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 详解JAVA Spring 中的事件机制

    说到事件机制,可能脑海中最先浮现的就是日常使用的各种 listener,listener去监听事件源,如果被监听的事件有变化就会通知listener,从而针对变化做相应的动作.这些listener是怎么实现的呢?说listener之前,我们先从设计模式开始讲起. 观察者模式 观察者模式一般包含以下几个对象: Subject:被观察的对象.它提供一系列方法来增加和删除观察者对象,同时它定义了通知方法notify().目标类可以是接口,也可以是抽象类或具体类. ConcreteSubject:具体的

  • Java事件监听机制讲解

    给组件加上监听器 定义一个类,这个类继承ActionListener pubulic class ButListener implements ActionListener{ Public void actionPerformed(ActionEvent e){ }} 给按钮添加动作监听器方法 ButListener but = new ButListen(); jbu.addActionListener(but); 加上监听机制后再监听器ButListener时间处理方法中再创建窗口即可得到点

  • 详谈Java中的事件监听机制

    鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动作发生在哪个组件上,那么该组件就是事件源对象 2.事件监听方法: addMouseListener(MouseListener ml) ;该方法主要用来捕获鼠标的释放,按下,点击,进入和离开的动作:捕获到相应的动作后,交由事件处理类(实现MouseListener接口)进行处理. addAction

  • 浅谈用java实现事件驱动机制

    由于项目需求,需要为Java提供一套支持事件驱动机制的类库,可以实现类似于C#中的event和delegate机制.众所周知,Java语言本身以及其标准库中并没有提供事件驱动机制的相关接口,虽然Swing(我且认为其不属于标准库,因为一般没人用:)中存在相关的类支持该机制以实现组件的事件处理,但它毕竟是与GUI相耦合的,而在其它类型的应用程序中使用起来显得就有些别扭,缺乏通用性.因此有必要实现一套通用的Java事件驱动机制类库,然后将其应用于通用的Java应用程序当中,虽然这并不是什么难事:)

  • Java事件机制要素及实例详解

    java事件机制中包含下述三要素: 1.事件,发生了什么事,比如用户在界面上的一个操作(手势滑动屏幕),当一个事件发生的时候,该事件用一个事件对象表示,每一个事件对象都有其对应的事件类. Java中事件一般继承自java.util.EventObject类,封装了事件源对象,以及事件的相关信息. 每一类事件有一个相应的事件监听器接口,该接口定义了接收和处理事件的抽象方法.实现该接口的类,就是监听器类.其对象可作为监听器对象向相应的组件注册.事件的类名通常为:XxxEvent ,比如下面实例中的C

  • 一文带你学会Java事件机制

    目录 委托事件模型 核心组件 总结 相信做 Java 开发的朋友,大多都是学习过或至少了解过 Java GUI 编程的,其中有大量的事件和控件的绑定,当我们需要在点击某个按钮实现某些操作的时候,其实就是为这个按钮控件注册了一个合理处理点击事件的监听器.此外,Spring Framework 中也有许多用到事件处理机制的地方,如 ApplicationContextEvent 及其子类,代表着容器的启动.停止.关闭.刷新等事件.本文会为大家介绍 Java 的事件处理机制,也会用示例来说明,如何优雅

  • 一文带你了解Java中的SPI机制

    目录 1: SPI机制简介 2: SPI原理 3: 使用场景 4: 源码论证 5: 实战 6: 优缺点 6.1 优点 6.2 缺点 1: SPI机制简介 SPI 全称是 Service Provider Interface,是一种 JDK 内置的动态加载实现扩展点的机制,通过 SPI 技术我们可以动态获取接口的实现类,不用自己来创建.这个不是什么特别的技术,只是 一种设计理念. 2: SPI原理 Java SPI 实际上是基于接口的编程+策略模式+配置文件组合实现的动态加载机制. 系统设计的各个

  • 一文带你了解Java万物之基之Object类

    目录 native方法 getClass方法 hashCode方法 equals方法 ==和equals的区别 clone方法 浅拷贝和深拷贝 toString方法 线程方法 finalize方法 Java是一门天然的面向对象的语言.而所有我们手动创造出来的类,都继承于同一个类,即Object类. 可以看一下Object类的结构 native方法 首先,超类拥有一个native方法 private static native void registerNatives(); static { re

  • 一文带你学会规则引擎Drools的应用

    目录 前言 引入依赖 Drools配置类 添加业务Model 定义drools 规则 添加Service层 添加Controller 测试一下 总结 前言 现在有这么个需求,网上购物,需要根据不同的规则计算商品折扣,比如VIP客户增加5%的折扣,购买金额超过1000元的增加10%的折扣等,而且这些规则可能随时发生变化,甚至增加新的规则.面对这个需求,你该怎么实现呢?难道是计算规则一变,就要修改业务代码,重新测试,上线吗. 其实,我们可以通过规则引擎来实现,Drools 就是一个开源的业务规则引擎

  • 一文带你学会Go select语句轻松实现高效并发

    目录 前言 select 介绍 什么是 select 为什么需要 select select 基础 语法 基本用法 一些使用 select 与 channel 结合的场景 实现超时控制 实现多任务并发控制 监听多个通道的消息 使用 default 实现非阻塞读写 select 的注意事项 总结 前言 在 Go 语言中,Goroutine 和 Channel 是非常重要的并发编程概念,它们可以帮助我们解决并发编程中的各种问题.关于它们的基本概念和用法,前面的文章 一文初探 Goroutine 与

  • 一文带你了解Java中的ForkJoin

    目录 什么是ForkJoin? ForkJoinTask 任务 ForkJoinPool 线程池 工作窃取算法 构造方法 提交方法 创建工人(线程) 例:ForkJoinTask实现归并排序 ForkJoin计算流程 前言: ForkJoin是在Java7中新加入的特性,大家可能对其比较陌生,但是Java8中Stream的并行流parallelStream就是依赖于ForkJoin.在ForkJoin体系中最为关键的就是ForkJoinTask和ForkJoinPool,ForkJoin就是利用

  • 一文带你了解Java中的Object类及类中方法

    目录 1. Object类介绍 2. 重写toString方法打印对象 3. 对象比较equals方法 4. hashCode方法 1. Object类介绍 Object是Java默认提供的一个类.Java里面除了Object类,所有的类都是存在继承关系的.默认会继承Object父 类.即所有类的对象都可以使用Object的引用进行接收. 范例:使用Object接收所有类的对象 class Person{} class Student{} public class Test { public s

  • 一文带你了解Java排序算法

    目录 一.选择排序 二.冒泡排序 三.插入排序 一.选择排序 选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度.所以用到它的时候,数据规模越小越好.唯一的好处可能就是不占用额外的内存空间了吧 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置. 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾. 重复第二步,直到所有元素均排序完毕. public static void selectSort(int[] arr) { //选择排序

  • 一文带你了解Java设计模式之原型模式

    目录 定义 解决的问题 核心要点 类图 浅复制与深复制的区别 代码实现 未使用设计模式 实现Cloneable接口 深复制-重写clone 深复制-通过对象序列化实现(推荐) 拓展 定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式其实就是从一个对象在创建另外一个可定制的对象,不需要知道任何创建的细节 解决的问题 在运行期建立和删除原型. 经常用于: 类初始化消耗资源较多 构造函数比较复杂 核心要点 1.实现cloneable 接口,重写Object的clone方法

随机推荐