设计模式-监听器模式-java

说明

应用场景

  • 操作控件:点击按钮、输入框敲击按键、点击鼠标、移动鼠标

  • 监听值变化

三要素

监听器模式有三个要素:事件源、事件对象、监听器。

  • 监听器:事件发生后要执行的操作,一般是接口

  • 事件对象:封装事件相关的信息,比如:点击按钮,创建事件对象,封装事件发生的时间、事件类型(点击、双击)、按钮坐标等

  • 事件源:事件发生的源头,比如:按钮

执行过程

触发事件时,调用 事件源 的方法,在该方法中创建 事件对象,调用事件监听器

三者关系

事件源 与 监听器 的关系

监听器 通常是 事件源 的成员变量

事件源 可以有 一个或多个 监听器,如:单击按钮事件监听器、双击按钮事件监听器等

事件源 提供 添加 监听器 的方法

事件对象 与 监听器 的关系

监听器执行时,事件对象作为参数传入

事件源 与 事件对象 的关系

触发事件时,调用 事件源 的方法,在该方法中创建 事件对象

例子

监听器

一般是接口,只有一个方法,形参是 事件对象

package test;

public interface ButtonListener {

    public void handle(ButtonEvent e);
}

事件对象

package test;

import java.util.Date;

public class ButtonEvent {
    public static final String TYPE_CLICK="click";
    public static final String TYPE_DOUBLE_CLICK="double_click";
    /**
     * 事件源
     */
    private Object source;
    /**
     * 触发事件的时间
     */
    private Date date;
    /**
     * 事件类型
     */
    private String type;
    /**
     * 事件发生时,事件源的位置(游戏中判断是否被击中等)
     */
    private int x;
    private int y;

    /**
     *
     * @param button 事件源
     * @param type 事件类型:单击 或 双击
     */
    public ButtonEvent(MyButton button,String type) {
        this.date = new Date();
        this.source = button;
        this.type = type;
    }

    public Object getSource() {
        return source;
    }

    public Date getDate() {
        return date;
    }

    public String getType() {
        return type;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

事件源

package test;

public class MyButton {
    /**
     * 点击事件监听器
     */
    private ButtonListener clickListener;
    /**
     * 按钮上的文字
     */
    private String text;

    public MyButton(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setClickListener(ButtonListener clickListener) {
        this.clickListener = clickListener;
    }

    public void click(){
        if(clickListener !=null) {
            ButtonEvent event = new ButtonEvent(this, ButtonEvent.TYPE_CLICK);
            event.setX(10);
            event.setY(100);
            clickListener.handle(event);
        }
    }
}

主启动类

package test;


public class Main {
    public static void main(String[] args) {


        MyButton btn = new MyButton("登录");
        btn.setClickListener(new ButtonListener() {
            @Override
            public void handle(ButtonEvent e) {
                MyButton src = (MyButton)e.getSource();
                System.out.println("事件源:"+src);
                System.out.println("按钮文字:"+src.getText());
                System.out.println("事件时间:"+e.getDate());
                System.out.println("事件类型:"+e.getType());
                System.out.println("位置:"+e.getX()+","+e.getY());
            }
        });

        // 代码触发点击事件,模拟鼠标点击按钮
        btn.click();
    }
}

原文出处:/show_1GWE6KVnYUo.html