监听者模式

监听者模式是观察者模式实现的一种,也属于Publish/Subscribe模式,被监听者触发某一事件后向监听者发送通知。在java中最常用的就是在编写GUI程序时,控件的事件监听了。

通常在编写java的GUI程序时,需要在控件上注册一个监听器,这个监听器需要开发人员自己编写,当控件被监听的事件触发后,监听器也会做出响应的反应。


Frame frame = new Frame("java");
frame.setBounds(400, 300, 300, 200);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e) {
        Frame f = (Frame) e.getSource();
        f.dispose();
    }
});

控件的关闭按钮默认并不会将窗口关闭,这需要开发人员编写关闭窗口的代码,WindowAdapter是实现了WindowListener接口所有方法的一个适配器类,但是所有方法都没有具体的代码,这样开发人员就可以只针对特定的事件进行监听,其他的事件即使触发了也不会做任何反应。

在实现监听者模式之前需要清楚,监听者模式设计的三个对象:事件源(Source)监听器(Listener)事件(Event)

事件源:发生事件的主体,上面的例子中是Frame控件,当事件源上发生操作时,它会调用时间监听器的一个方法,并将事件对象作为参数传递过去。

监听器:通常是一个接口,事件源被触发事件后作出响应,具体响应由开发人员编写实现类。

事件:发生在事件源上,持有事件源的引用。

接下来编写一个用户操作的监听器案例:

  1. 事件源是User,user的更新删除操作时需要被监听的事件。
  2. 监听器是UserListener,监听User对象,事件触发后的具体操作由开发人员编写。
  3. 事件是UserEvent,持有对事件源User对象的引用。

事件源:User.java


public class User {
public String name;

public User(String name) {
    this.name = name;
}

public void updateUser() {
    if (userListener != null) {
        userListener.updateUser(new UserEvent(this));
    }
    System.out.println("更新用户" + this.name);
}

public void deleteUser() {
    if (userListener != null) {
        userListener.deleteUser(new UserEvent(this));
    }
    System.out.println("删除用户" + this.name);
}

public IUserListener userListener;

public void addListener(IUserListener userListener) {
    this.userListener = userListener;
}
}

监听器接口:IUserListener.java


public interface IUserListener {
public void updateUser(UserEvent e);
public void deleteUser(UserEvent e);
}

事件:UserEvent.java


public class UserEvent {
private Object source;

public UserEvent(Object source) {
    this.source = source;
}

public Object getSource() {
    return source;
}

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

}

实现一个监听器类:UserListener


public class UserListener implements IUserListener{
@Override
public void updateUser(UserEvent e) {
    User user = (User) e.getSource();
    System.out.println("监听到用户" + user.name + "的更新操作。。。");
}
public void deleteUser(UserEvent e) {
    //...
}
}

测试:App.java


public class App {
public static void main(String[] args) {
    User user = new User("张三");
    //user.addListener(new UserListener());//也可以通过匿名内部类的方式实现监听器类
    user.addListener(new IUserListener(){
        public void updateUser(UserEvent e) {
            User user = (User) e.getSource();
            System.out.println("监听到用户" + user.name + "的更新操作。。。");
        }
        public void deleteUser(UserEvent e) {
            User user = (User) e.getSource();
            System.out.println("监听到用户" + user.name + "的删除操作。。。");
        }

    });
    user.deleteUser();
}
}

运行结果:

监听到用户张三的更新操作。。。
更新用户张三
监听到用户张三的删除操作。。。
删除用户张三

不添加监听器的运行结果:

更新用户张三
删除用户张三


JDK中awt包下的图形控件的监听事件源码

java.util.EventObject


public class EventObject implements java.io.Serializable {
    private static final long serialVersionUID = 5516075349620653480L;
    protected transient Object  source;
    public EventObject(Object source) {
        if (source == null)
            throw new IllegalArgumentException("null source");

        this.source = source;
    }
    public Object getSource() {
        return source;
    }
    public String toString() {
        return getClass().getName() + "[source=" + source + "]";
    }
}

java.awt.Window


public class Window extends Container implements Accessible {
    ...
    ...
    protected void processWindowEvent(WindowEvent e) {
        WindowListener listener = windowListener;
        if (listener != null) {
            switch(e.getID()) {
                case WindowEvent.WINDOW_OPENED:
                    listener.windowOpened(e);
                    break;
                case WindowEvent.WINDOW_CLOSING:
                    listener.windowClosing(e);
                    break;
                case WindowEvent.WINDOW_CLOSED:
                    listener.windowClosed(e);
                    break;
                case WindowEvent.WINDOW_ICONIFIED:
                    listener.windowIconified(e);
                    break;
                case WindowEvent.WINDOW_DEICONIFIED:
                    listener.windowDeiconified(e);
                    break;
                case WindowEvent.WINDOW_ACTIVATED:
                    listener.windowActivated(e);
                    break;
                case WindowEvent.WINDOW_DEACTIVATED:
                    listener.windowDeactivated(e);
                    break;
                default:
                    break;
            }
        }
    }
    ...
    ...
}

java.awt.event.WindowListener


public interface WindowListener extends EventListener {
    public void windowOpened(WindowEvent e);
    public void windowClosing(WindowEvent e);
    public void windowClosed(WindowEvent e);
    public void windowIconified(WindowEvent e);
    public void windowDeiconified(WindowEvent e);
    public void windowActivated(WindowEvent e);
    public void windowDeactivated(WindowEvent e);
}
时间: 2024-10-09 00:33:15

监听者模式的相关文章

设计模式(二)观察者监听者模式

基于MAP线程安全的观察者监听者模式 1 #include<map> 2 #include<string> 3 #include<vector> 4 #include<iostream> 5 #include<memory> 6 using namespace std; 7 8 class Listener 9 { 10 public: 11 Listener(string name):_name(name){} 12 virtual void

[设计模式]Netd中的命令设计模式,NetworkManagementService中的监听者模式

命令模式中有如下的角色: (1)调用者(invoker) (2)命令接收者(receiver) (3)客户端(client) (4)命令对象(command) 1 public interface Command { 2 public void execute(); 3 } 4 public class ConcreteCommand implements Command { 5 6 private Receiver receiver = null; 7 private String state

设计模式之监听者模式

package listenermode; public class Button { //在类中定义接口对象 ,都是button的行为 public interface OnClickListener { public void onClickListener (); } private OnClickListener listener =null; public void setOnClickListener(OnClickListener cbl){ this.listener = cbl

KVO监听者

监听者模式方便的监听所需要的值得变化 @implementation ViewController - (IBAction)Buton:(id)sender { self.view.backgroundColor=[UIColor redColor]; } - (void)viewDidLoad { [super viewDidLoad]; self.model=[[Model alloc]init]; //第一个参数是 被监听者 //第二个参数是  监听者 //第三个参数是  监听内容 //第

设计模式之监听模式(观察者模式与监听模式区别)

一,类的四大基本关系:  a.关联关系:如A类调用B类. b.继承关系:如A类是B类的父类. c.聚合关系:如装橘子的箱子,箱子是否存在与里面装没装橘子没有任何关系,也就是说橘子不会影响箱子的存在. d.组合关系:如一个小组,小组是否存在与小组中是否有组员是息息相关的,如果没有组员,小组就不存在了. 监听器模式:事件源经过事件的封装传给监听器,当事件源触发事件后,监听器接收到事件对象可以回调事件的方法 观察者模式:观察者(Observer)相当于事件监听者,被观察者(Observable)相当于

EntityFramework之监听者判断SQL性能指标

前言 当我们利用EF这个ORM框架时,我们可能会利用LINQ或者原生的SQL语句来进行数据操作,此时我们无法确定我们的代码是否会给数据库带来一定的负载,当给数据库带来一定的压力时,由于项目中对数据进行相应的操作实在是太多,我们无法准确的去进行定位,又或者我们不是专业的DBA,无法准确的去分析SQL性能的优劣,此时该怎么办呢?我们完全不需要DBA,我们可以通过相应的操作来判断一段SQL代码的好坏,这就是我们本节需要讲的内容,利用EF中监听者来判断SQL性能,在之前系列中也有提到,可以参考之前系列.

Kali2.0在使用aircrack-ng破解无线密码时网卡监听模式问题

在使用Kali2.0 aircrack-ng破解需先密码时执行以下命令后会发现无法启用网卡的监听模式airmon-ng start wlan0执行以下命令后报错airodump-ng mon0 出现以上问题原因是因为系统本身问题,网卡并未进入监听模式 解决办法: ifconfig wlan0 down iwconfig wlan0 monitor ifconfig wlan0 up 再次执行 airmon-ng start wlan0 airodump-ng mon0 网卡进入监听模式

监听者

在web系统中,HttpServletRequest.HttpSession.ServletContext对象在web容器中遵循生成.运行.销毁这样的生命周期.当进行相关的监听配置后,web容器就会调用监听器上的方法,进行对应的事件处理. 1.监听接口和事件类 2.如何告诉容器有一个监听者 有两种方法可以进行监听者的配置,一种是在DD中配置,如果需要上下文初始化参数,也要在DD中配置: 在servlet 3.0中,可以利用注入的方式注入监听类(虽然监听器和过滤器不是servlet,但是它们都在同

Web应用中监听者的通知顺序按照DD中的定义顺序

Web应用中监听者的通知顺序按照DD中的定义顺序: XML: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http:/