(这是我对swing mvc探讨的体会之一)
一、子组件与父组件的强关联问题
子组件如果要操作父组件的话,按照一般的编程方法是,将子组件里面实现对父组件的引用。就是这种引用,就把子组件与父组件(以及父组件的关联组件)强关联起来。
有了这种关联的存在,子组件就失去了自由了。
二、swing事件注入的脱藕解决方案
如果是事件是采用运行时“注入”的方式,在运行时由父组件将事件注入子组件。
子组件里面没有出现父组件的直接引用,子组件相对于父组件就是独立的,因此子组件被复用成为可能。
既然是子组件,必然存在与父组件的关联,我这里只讨论事件问题,子组件如何执行父组件的控制(事件)呢?
三、例子
1、先说子组件自己的事件,例如,点击按钮后,按钮闪动一下。显然按钮组件自己可以完成。并且可以不涉及的父(其他)组件。
public class Buttonex extends JButton implements MouseListener {
public Buttonex() {
super();
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("我用自己的事件我晃动了一下!");
}
}
2、与父组件的交互:
例如把按钮放到父组件JPanel中,父组件中有其他组件,点击按钮后,就更改其中的另外一个组件jLabel1的text。
A、如果按照类继承方式来做的话,首先扩展JButton,里面添加 对父组件的引用JPanel jPanel,然后通过扩展JButton事件jPanel.jLabel1
public class Buttonex2 extends JButton implements MouseListener {
JPanel jPanel; //这事父组件的引用
public Buttonex2(JPanel 父组件) {
jPanel=父组件;
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("我晃动了一下");
jPanel.jLabel1.setText("改变了");
}
}
从上面的代码可以看到,Buttonex以后可能就再也不能用了,因为他与jPanel强关联了。
B、下面我们利用swing的事件机制来说明如何脱耦,我们的目的是:最好不要再去动Buttonex,上层组件jPanel的事情自己做。不要干扰其他组件。
public class NewJPanel extends javax.swing.JPanel {
private Buttonex jButton1;
private JLabel jLabel1=new JLabel("我是父组件的其他组件!");
public NewJPanel() {
jButton1 = new Buttonex(this);//吧父组件引入子组件
this.add(jButton1);
jButton1.setText("jButton1");
jButton1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("我是父组件添加的事件,我没有直接在子组件中编码。");
//下面操作jButton1的父组件
jLabel1.setText("我被父组件注入到子组件的事件修改了。");
}
});
this.add(jLabel1);
}
}
以上代码不需要修改Buttonex源码,子组件关联父组件的事件是在运行时才注入的,代码是在父组件中完成的,与子组件原有代码无关,可以看到了父子组件代码在编码阶段是没有关联,只在运行时才出现关联。
一、子组件与父组件的强关联问题
子组件如果要操作父组件的话,按照一般的编程方法是,将子组件里面实现对父组件的引用。就是这种引用,就把子组件与父组件(以及父组件的关联组件)强关联起来。
有了这种关联的存在,子组件就失去了自由了。
二、swing事件注入的脱藕解决方案
如果是事件是采用运行时“注入”的方式,在运行时由父组件将事件注入子组件。
子组件里面没有出现父组件的直接引用,子组件相对于父组件就是独立的,因此子组件被复用成为可能。
既然是子组件,必然存在与父组件的关联,我这里只讨论事件问题,子组件如何执行父组件的控制(事件)呢?
三、例子
1、先说子组件自己的事件,例如,点击按钮后,按钮闪动一下。显然按钮组件自己可以完成。并且可以不涉及的父(其他)组件。
public class Buttonex extends JButton implements MouseListener {
public Buttonex() {
super();
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("我用自己的事件我晃动了一下!");
}
}
2、与父组件的交互:
例如把按钮放到父组件JPanel中,父组件中有其他组件,点击按钮后,就更改其中的另外一个组件jLabel1的text。
A、如果按照类继承方式来做的话,首先扩展JButton,里面添加 对父组件的引用JPanel jPanel,然后通过扩展JButton事件jPanel.jLabel1
public class Buttonex2 extends JButton implements MouseListener {
JPanel jPanel; //这事父组件的引用
public Buttonex2(JPanel 父组件) {
jPanel=父组件;
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("我晃动了一下");
jPanel.jLabel1.setText("改变了");
}
}
从上面的代码可以看到,Buttonex以后可能就再也不能用了,因为他与jPanel强关联了。
B、下面我们利用swing的事件机制来说明如何脱耦,我们的目的是:最好不要再去动Buttonex,上层组件jPanel的事情自己做。不要干扰其他组件。
public class NewJPanel extends javax.swing.JPanel {
private Buttonex jButton1;
private JLabel jLabel1=new JLabel("我是父组件的其他组件!");
public NewJPanel() {
jButton1 = new Buttonex(this);//吧父组件引入子组件
this.add(jButton1);
jButton1.setText("jButton1");
jButton1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("我是父组件添加的事件,我没有直接在子组件中编码。");
//下面操作jButton1的父组件
jLabel1.setText("我被父组件注入到子组件的事件修改了。");
}
});
this.add(jLabel1);
}
}
以上代码不需要修改Buttonex源码,子组件关联父组件的事件是在运行时才注入的,代码是在父组件中完成的,与子组件原有代码无关,可以看到了父子组件代码在编码阶段是没有关联,只在运行时才出现关联。