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