Java事件机制

Posted by 孟德传习录 on November 17, 2019

JAVA事件机制

java事件机制有三个要素,事件源、事件和监听器。它们的关系是,监听器注册在事件源上负责监听事件的发生,并做相应的处理;事件源的某个方法被用户触发产生事件,同时通知所有的监听器执行事件处理方法。 一个事件源可以有多个事件监听器。 github

代码实现

样例解析,一个孩子作为一个事件源,如果在学校被打了,老师监听到就会执行相应的处理:通知肇事者家长。

  1. 创建事件类 继承了EventObject,source代表事件源,同时重写了getSource方法。 这是一个孩子被打了的事件。
public class BeatMeEvent extends EventObject {

    /**
     * 封装了事件源 Object类型,这里是孩子。
     */
    private Object source;

    /**
     * Constructs a prototypical Event.
     *
     * @param source The object on which the Event initially occurred.
     * @throws IllegalArgumentException if source is null.
     */
    public BeatMeEvent(Object source) {
        super(source);
        this.source = source;
    }

    @Override
    public Object getSource() {
        return this.source;
    }

    public void setSource(Object source) {
        this.source = source;
    }
}

  1. 孩子事件源。 成员变量是监听器集合和会发生改变的状态。同时必须要有,注册监听器的方法,通知监听器处理的方法和接收 事件的方法。为了显示状态,也需要有获取状态的方法。
/**
 * @Author: Dejia Meng
 * @Date: 2019-11-15 17:39
 * 事件源
 */
public class MyChild {
    private List<ParentsListener> parentsListeners;
    /**
     * 0 健康 1 被打
     */
    private byte status;

    public MyChild() {
        this.parentsListeners = new ArrayList<>();
        this.status = 0;
    }

    public void addListener(ParentsListener parentsListener) {
        this.parentsListeners.add(parentsListener);
    }

    public void notifies() {
        Iterator<ParentsListener> iterable = parentsListeners.iterator();
        while (iterable.hasNext()) {
            ParentsListener parentsListener = iterable.next();
            // 监听器执行响应方法时,会传入事件对象,事件对象内封装了事件源对象。
            parentsListener.response(new BeatMeEvent(this));
        }
    }

    public void beingBeat() {
        this.status = 1;
        notifies();
    }

    public byte getStatus() {
        return this.status;
    }

}
  1. 监听器以及监听器执行的处理方法。它的参数是一个事件,事件内封装了事件源。 实现了EventListener这个标记接口。
/**
 * @Author: Dejia Meng
 * @Date: 2019-11-15 17:38
 */
public class ParentsListener implements EventListener {
    /**
     * 监听器的响应方法,需要传入指定类型的事件作为参数
     * @param beatMeEvent
     */
    public void response(BeatMeEvent beatMeEvent) {
        // 这里获取事件的事件源,并打印事件源改变后的状态作为对事件的处理。
        MyChild myChild = (MyChild) beatMeEvent.getSource();
        System.out.println("孩子的状态是正在被打 status=" + myChild.getStatus());
    }
}
  1. 主函数
public class Main {
    public static void main(String[] args) {
        // 事件源
        MyChild myChild = new MyChild();
        // 在事件源注册监听器
        // 匿名类的实现方式
        myChild.addListener(new ParentsListener() {
            /**
             * 触发监听器执行的函数
             * @param beatMeEvent
             */
            @Override
            public void response(BeatMeEvent beatMeEvent) {
                super.response(beatMeEvent);
            }
        });
        System.out.println("有人正在打你的儿子!");
        // 事件源上的一个方法,用于对事件源的操作,同时通知到了事件的监听器。执行监听器的相应方法。
        myChild.beingBeat();

    }
}

总结

归根结底,代码逻辑就是注册了一些监听类对象,触发时执行这些对象的事件处理方法。