监听器模型 ——通信层与界面层分离
监听器模型1:
界面上添加组件,组件上add监听器,监听器中实现响应。
比如:点击按钮,在界面上显示一行字,则需要把界面传至监听器中。
弊端:耦合度强,不适合以后扩展。如若界面上又要添加一个组建,而该组建在监听器中又要用到,则需修改界面和监听器中的代码。
监听器模型2:
界面层与通信层分离,高内聚,低耦合,适合扩展。
实例:界面上有一个接受文本按钮和一个接收图片按钮,以后可能还要继续添加接收文件,音频等按钮。
实现方法:
1 定义接口,里面为需要重写的接收方法。
2 把组建(按钮)当做消息监听器,继承JButton,实现接口,则成了一个消息监听器。
3 把通信类当做消息事件源,在这个类中有一个监听器队列,队列中每一个监听器都能监听该通信类中事件的发生。
4 实例化一个通信类对象,给它注册监听器。
另一实例:
public interface ImsgReciverListener { public void rece(Msg m);//接收消息的方法 }
//把自己写 的JTree作为消息监听器 public class NetJavaJTree extends JTree implements ImsgReciverListener{ @Override public void rece(Msg m) { //取得这个树上的根节点 DefaultMutableTreeNode root =(DefaultMutableTreeNode)this.getModel().getRoot(); //将消息对象包装为新建的节点 DefaultMutableTreeNode newnode = new DefaultMutableTreeNode(m); root.add(newnode);//将新建的节点加载树上 SwingUtilities.updateComponentTreeUI(this);//刷新界面 } }
/* * 模拟通信层的消息接收,相当于消息事件源 */ public class NetConnector extends Thread{ public void run() { int t=0; while(true) { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t++; Msg m = new Msg(); m.setId(t); m.setContent("第"+t+"条消息"); //分发这条消息给它的监听器 fireMsgRec(m); } } //给该对象增加一个监听器 public void addListener(ImsgReciverListener listener) { list.add(listener); } //将接收到的消息通知队列中的所有监听器去处理 public void fireMsgRec(Msg m) { for(int i=0;i<list.size();i++) { list.get(i).rece(m); } } //保存消息监听器的队列 private List<ImsgReciverListener> list = new ArrayList(); }
//主界面 public class MainUI extends JFrame{ public static void main(String[] args) { MainUI mu = new MainUI(); NetConnector con = new NetConnector(); con.start(); //创建只有一个跟节点的树,加到界面上 DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("根节点"); DefaultTreeModel dm = new DefaultTreeModel(rootNode); //创建树对象,为一个消息监听器 NetJavaJTree tree = new NetJavaJTree(); tree.setModel(dm);//设置树模型为自己定义的dm con.addListener(tree);//注册消息监听器 mu.setupUP(tree);//显示主界面 } public void setupUP(NetJavaJTree tree) { this.setTitle("测试界面"); this.setLayout(new FlowLayout()); this.setDefaultCloseOperation(3); this.setSize(200,200); this.add(tree); this.setVisible(true); } }
简单说:按笔者理解,核心就是组件与监听器绑定,因此只需要给通信模型注册该组建,即实现了一种功能。当以后要添加别的组建时,只需要实现接口,重写接口中的方法,并把它注册到该通信类就可以。
注意:java有设计模式,但我们不能限于模式;有模型,但也不能陷于模型。比如,此种第二种监听器模型在界面上的组建不相互调用时好用,但若界面上的组件会相互调用,就还有待进一步研究。
下一篇:
原型与原型链详解(带图方便理解)