我正在尝试构建一个基于MVC的Swing用户界面,并且对该主题有几个问题。提出问题的最佳方式是借助一个简单的例子。
假设我们有一个带有一个JButton和3个JTextField的JDialog。当按下该按钮时,我想要关闭另一个JDialog,并打开另一个需要来自3个JTextFields的数据。
这样做的简单方法(只需要代码片段,不需要惹恼你):
myButton.addMouseListener(new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent evt){
firstFrame.setVisible(false);
secondFrame.setData(jTextField1.getText(),jTextField2.getText(),jTextField3.getText());//just sending the data to the new window, would be this or something similar
secondFrame.setVisible(true);
}});
或类似的东西。
第一个问题:如果我不使用匿名内部类但决定为我的Listener使用单独的类,我如何将数据从3个JTextField传递给我的mouseListener类?除了在Listener类中保留视图的引用之外,还有其他选择吗?
继续,给出MVC模式:
第二个问题:我认为听众(根据MVC的控制器)在没有模型参与的情况下调用另一个窗口是有道理的,我认为这是工作。但是需要从一个窗口传递到下一个窗口的数据(来自3JTextFields的数据)不应该通过模型吗?就像让第一个窗口在模型中保存数据一样,然后当第二个窗口需要它们时,从模型中请求它们。
第三个问题:我正在考虑使用Observer / Observable模式。如何在此示例中使用它来打开最后一个窗口?我的意思是因为(我认为)Controller是打开第二个窗口的类,这意味着必须观察监听器,第二个窗口必须是Observer,以便监听器会说
notifyObservers("openSecondWindow");
然后第二个窗口会看到并自行打开?
最后:我听说PropertyChangeListener也可以正常工作,并且它有时会优先于Observer / Observable Pattern。你对此有何看法,特别是关于我的例子。
我很困惑..
感谢您的时间。
答案 0 :(得分:0)
我不确定Java的具体方面。但谈到OOP,通过事件驱动设计使应用程序分离是非常合理的。因此,您不是直接处理组件,而是触发事件,如您所写:notifyObservers("openSecondWindow");
。
但是,您不需要通过模型层来执行此操作。相反,您应该有一个代表给定事件的event
类,并在事件类中设置所提及字段的值。
类似的东西:
exampleEvent.setProperty1('blah').setProperty2('blah2');
notify('openSecondFrame', exampleEvent);
我刚刚发布了一个有关此事件驱动内容的问题:
您可能有兴趣阅读几个链接(它是PHP,但这个概念适用于OOP)。
因此,遵循这一概念,最好创建一个EventHandler
组件来管理这些事件和信号。
但是再次考虑到我并不精通Java。这只是关于OOP。
答案 1 :(得分:0)
如果我不使用匿名内部类但决定为我的Listener使用单独的类,我将如何将数据从3个JTextField传递给我的mouseListener类?
您单独的MouseAdapter
课程会有一个构造函数,您可以将JPanel
课程中的内容传递给MouseAdapter
课程。
此代码适用于ActionListener
,但我认为总体思路将向您展示如何编写MouseAdapter
类。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import com.ggl.project.planner.model.Planner;
import com.ggl.project.planner.model.Project;
import com.ggl.project.planner.view.CreateUpdateProjectDialog;
import com.ggl.project.planner.view.ProjectPlannerFrame;
public class CreateProjectActionListener implements ActionListener {
protected Planner planner;
protected Project project;
protected ProjectPlannerFrame frame;
public CreateProjectActionListener(ProjectPlannerFrame frame,
Planner planner, Project project) {
this.frame = frame;
this.planner = planner;
this.project = project;
}
@Override
public void actionPerformed(ActionEvent event) {
CreateUpdateProjectDialog dialog =
new CreateUpdateProjectDialog(frame, project, true);
if (dialog.isOkPressed()) {
planner.setProjectOpen(true);
}
}
}
我认为听众(根据MVC的控制器)在没有模型参与的情况下调用另一个窗口是有道理的,我认为这是我的工作。但是需要从一个窗口传递到下一个窗口的数据(来自3JTextFields的数据)不应该通过模型吗?就像让第一个窗口在模型中保存数据一样,然后当第二个窗口需要它们时,从模型中请求它们。
我不确定我理解你的问题。当我构建GUI时,我有一个或多个数据模型来表示GUI中的值。这些数据模型的实例将通过构成GUI的大多数组件传递。
应用程序的其余部分通过模型访问GUI信息。
在我作为第一个问题答案的一部分发布的ActionListener
课程中,有2个数据模型,Project
和Planner
。 Project
特定于特定项目,而Planner
是GUI的全局项目。
我正在考虑使用Observer / Observable模式。如何在此示例中使用它来打开最后一个窗口?
Swing已经内置了侦听器模式。您可以将动作侦听器用于自己的操作。您甚至可以将自己的侦听器类型添加到Swing中,尽管这是一个痛苦的过程。当我将JPanel
扩展为JCroppingPanel
时,我添加了自己的侦听器类型。