Java事件机制

作者: Mr_Puff | 来源:发表于2017-06-15 17:18 被阅读0次

事件机制的三个角色

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

在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();
        }
    }
}

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

相关文章

网友评论

    本文标题:Java事件机制

    本文链接:https://www.haomeiwen.com/subject/xvkuqxtx.html