这个问题困扰我很久了,一直没有找到一个简捷的方法来解决。如题所述,如果有两个窗口,P1和P2,在P1里有一个按钮,点击按钮将在P2上进行操作,比如说显示一行字。传统的方法是把P2的实例输入到P1里,然后在按钮点击事件里对P2的实例进行操作,像这样:
public class MainWindow extends JPanel {
private P1 p1 = new P1();
private P2 p2 = new P2(); public void constructGUI() {
this.add(p1);
this.add(p2);
p1.setP2(p2);
}
}
public class P1 extends JPanel {
private P2 p2; public void setP2(P2 p2){
this.p2 = p2;
}
......
public void buttonClicked(...){
p2.displayText();
}
}public class P2 extends JPanel {
public void displayText(){
......
}
}
这个方法在简单的界面设计下没有任何问题,但在复杂情况下就有些力不从心了。还有一种方法是在上面例子的MainWindow里定义事件处理,这样需要P1定义一个getButton的方法来返回需要添加事件的按钮,这个方法个人认为也不是很好。在我去年的一个工程里,就遇到了这个问题,这种方法在工作中已经不能胜任,所以我用到了一个中间类来传递事件。在这种方式里,我定义一个中间类,比如说叫做MiddleActionHandler,在这个类里有P1的实例和P2的实例,然后有一个方法是p1ButtonAction(),在这个方法里执行P2上的操作。这个工程在去年完成了,事件操作上没有任何问题,代码看起来也规整得多,应该说这个方法还是可以。但是我觉得自己似乎没有找到最好的事件操作方法,所以就在这发个帖子,大家讨论一下,看看你有什么高招可以说出来让大家借鉴的。
public class MainWindow extends JPanel {
private P1 p1 = new P1();
private P2 p2 = new P2(); public void constructGUI() {
this.add(p1);
this.add(p2);
p1.setP2(p2);
}
}
public class P1 extends JPanel {
private P2 p2; public void setP2(P2 p2){
this.p2 = p2;
}
......
public void buttonClicked(...){
p2.displayText();
}
}public class P2 extends JPanel {
public void displayText(){
......
}
}
这个方法在简单的界面设计下没有任何问题,但在复杂情况下就有些力不从心了。还有一种方法是在上面例子的MainWindow里定义事件处理,这样需要P1定义一个getButton的方法来返回需要添加事件的按钮,这个方法个人认为也不是很好。在我去年的一个工程里,就遇到了这个问题,这种方法在工作中已经不能胜任,所以我用到了一个中间类来传递事件。在这种方式里,我定义一个中间类,比如说叫做MiddleActionHandler,在这个类里有P1的实例和P2的实例,然后有一个方法是p1ButtonAction(),在这个方法里执行P2上的操作。这个工程在去年完成了,事件操作上没有任何问题,代码看起来也规整得多,应该说这个方法还是可以。但是我觉得自己似乎没有找到最好的事件操作方法,所以就在这发个帖子,大家讨论一下,看看你有什么高招可以说出来让大家借鉴的。
解决方案 »
- java更改系統時間的問題
- 程序后台报错,等待高手
- 文思创新的笔试题?????将包含数字1-49个integer对象填入一个数组列表,然后对列表中的元素随机混排,并且从混排后的列表中选择开头的6个值打印出来
- 大家帮忙看看这个程序要怎么改才能从嵌套类里访问另一个类的成员变量?谢谢了。
- 一个生画图生成图片的问题!!!!
- java中怎样实现遍历,浏览文件?
- 新手问题~~~~~~~~~~~~~~~~~~~~~~~
- 关于java中日期计算的问题
- Java的稳定性
- 如何将数据库中得到的数据,存储到二维数组中?
- 怎样swt tree获取tree 结点 TreeItem的名称
- java Jslider 音量控制
我认为最好的方法应该是UI与Controller分离。两个窗口有各自的Controller,事件都在Controller之间交互。这样代码结构更清晰。
尽量多采用MVC的设计模式。
不好意思,我还是不太明白MVC的模式在Swing的GUI中能怎样的被运用。就拿我上面的例子来说吧,如果像你所说的VC分离,那应该怎么处理呢?代码将会是什么样?
其实从swing本身我们可以得到一些启发。
比如JButton例子。
我们看到很多下面的情况。
public class ButtonDemo extends JPanel
implements ActionListener
b1 = new JButton("Disable middle button", leftButtonIcon);
b1.addActionListener(this);
对于swing的组件来说,可以看到都有一个add...Listener和fire...Change的函数。
从而我可以得出一个结论,swing的组件都是一个被观察者。
b1.addActionListener(this);这句告诉被观察者有一个什么的监听器。此例是ButtonDemo的实例。
注意ButtonDemo类实现了ActionListener监听器,并且重写了actionPerform方法.
可以想象一下,组件是一个发布命令的领导,而监听器是领导手下的兵。
那么ButtonDemo的实例和b1是两个不同的类实例。
注意:当点击按钮的时候,我们触发的是ButtonDemo实例的函数。
所以对于此例。我们可以套用swing的做法使用observer模式来实现解耦。
就象下面这样:
import java.beans.*;//PropertyChangeListener;public class MainWindow extends javax.swing.JPanel {
private P1 p1 = new P1();
private P2 p2 = new P2();
public void constructGUI() {
//this.add(p1);
//this.add(p2);
//p1.setP2(p2);
p1.addPropertyChangeListener(p2);
}
public static void main(String[]args){
MainWindow main=new MainWindow();
main.constructGUI();
args=new String[]{"call function"};
if (args[0]=="call function"){
main.p1.event();
}
}
}
class P1 extends javax.swing.JPanel {
//private P2 p2;
//public void setP2(P2 p2){
// this.p2 = p2;
//}
public void event(){
System.out.println("call out.");
firePropertyChange("if your get this message,please do yourself event",1,0);
}
}class P2 extends javax.swing.JPanel implements PropertyChangeListener{
public void displayText(){
System.out.println("for me,i got the message so i need to do work.");
}
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("if your get this message,please do yourself event"))
{
displayText();
}
}
}
p1和p2没有出现套用关系。可以看到和swing做法是多么的相象。
使用中间对象listener实现解耦。在这里p1是被观察者,p2是监听者。