监听者模式是观察者模式实现的一种,也属于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控件,当事件源上发生操作时,它会调用时间监听器的一个方法,并将事件对象作为参数传递过去。
监听器:通常是一个接口,事件源被触发事件后作出响应,具体响应由开发人员编写实现类。
事件:发生在事件源上,持有事件源的引用。
接下来编写一个用户操作的监听器案例:
- 事件源是User,user的更新删除操作时需要被监听的事件。
- 监听器是UserListener,监听User对象,事件触发后的具体操作由开发人员编写。
- 事件是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