MVC—JavaSwing中的观察者/可观察模式
我正在尝试构建一个基于MVC的Swing用户界面,并就这个主题提出了几个问题。问我问题的最好方法是借助一个简单的例子 假设我们有一个JDialog,其中有一个JButton和3个JTextFields。当按下这个按钮时,我希望这个JDialog关闭,另一个JDialog打开,它需要来自3个jtext字段的数据 简单的方法是,只需编写代码片段,无需过多地烦扰您:MVC—JavaSwing中的观察者/可观察模式,java,swing,model-view-controller,observer-pattern,Java,Swing,Model View Controller,Observer Pattern,我正在尝试构建一个基于MVC的Swing用户界面,并就这个主题提出了几个问题。问我问题的最好方法是借助一个简单的例子 假设我们有一个JDialog,其中有一个JButton和3个JTextFields。当按下这个按钮时,我希望这个JDialog关闭,另一个JDialog打开,它需要来自3个jtext字段的数据 简单的方法是,只需编写代码片段,无需过多地烦扰您: myButton.addMouseListener(new MouseAdapter(){ @Override pub
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);
}});
或者类似的
第一个问题:如果我不使用匿名内部类,而是决定为我的侦听器使用单独的类,那么如何将数据从3个JTextFields传递到我的mouseListener类?除了在Listener类中保留视图的引用之外,还有其他选择吗
在MVC模式下继续:
第二个问题:我想监听器控制器根据MVC调用另一个窗口而不涉及模型是有意义的,我想这是我的工作。但是需要从一个窗口传递到下一个窗口的数据来自3JTextFields的数据不应该通过模型吗?就像让第一个窗口将数据保存在模型中,然后在第二个窗口需要数据时从模型中请求数据一样
第三个问题:我正在考虑使用观察者/可观察模式。在本例中,如何使用该选项打开最后一个窗口?我的意思是,既然我认为控制器是打开第二个窗口的类,那么这是否意味着监听器必须被观察,而第二个窗口必须是观察者,这样监听器才会说
notifyObservers("openSecondWindow");
然后第二个窗口会看到它并自动打开
最后:我听说PropertyChangeListener也可以工作,它有时优先于观察者/可观察模式。你对此有什么想法,特别是关于我的例子
我很困惑
谢谢您的时间。我不确定Java的具体方面。但说到OOP,通过事件驱动设计使应用程序解耦是非常合理的。因此,您将不直接处理组件,而是触发事件,如您所写:notifyObserversopenSecondWindow 但是,这样做不需要通过模型层。相反,您应该有一个表示给定事件的事件类,并在事件类中设置所述字段的值 比如:
exampleEvent.setProperty1('blah').setProperty2('blah2');
notify('openSecondFrame', exampleEvent);
我刚才发布了一个关于事件驱动的问题:
这里有几个链接,您可能对阅读它的PHP感兴趣,但是这个概念适用于OOP
因此,遵循这个概念,最好创建一个EventHandler组件来管理这些事件和信号
但是,再次考虑到我不精通Java。这只是关于OOP的问题。第一个问题
如果我不使用匿名内部类,但决定为我的侦听器使用单独的类,那么如何将数据从3个JTextFields传递到我的mouseListener类
单独的MouseAdapter类将有一个构造函数,您可以在其中将所需内容从JPanel类传递到MouseAdapter类
这段代码是为ActionListener编写的,但我认为总体思路将向您展示如何编写MouseAdapter类
第二个问题
我想,根据MVC,监听器控制器调用另一个窗口而不涉及模型是有意义的,我想这就是我的工作。但是需要从一个窗口传递到下一个窗口的数据来自3JTextFields的数据不应该通过模型吗?就像让第一个窗口将数据保存在模型中,然后在第二个窗口需要数据时从模型中请求数据一样
我不确定我是否理解你的问题。当我构建GUI时,我有一个或多个数据模型来表示GUI中的值。这些数据模型的实例通过构成GUI的大多数组件传递
应用程序的其余部分通过模型访问GUI信息
在我作为第一个问题答案的一部分发布的ActionListener类中,有两个数据模型:Project和Planner。Project是特定于特定项目的,而Planner是GUI的全局
第三项质询
我正在考虑使用观察者/可观察模式。在本例中,如何使用该选项打开最后一个窗口
Swing已经内置了侦听器模式。您可以为自己的操作使用操作侦听器。您甚至可以将自己的侦听器类型添加到Swing,尽管这是一个痛苦的过程。有一次,我在扩展JPanel以创建JCroppingPanel时添加了自己的侦听器类型。这里有一个属性更改示例。我想说的是,我没有更改属性,我只是尝试打开一个新窗口。我想我可以用房地产来做
HangListener,但是在这个动作中使用它真的有意义吗?哦,我会使用CardPanel,引用,而不是打开一个新窗口。编辑:另外,试着集中在一个问题上。我知道卡片布局,谢谢。对于这个问题,让我们假设我选择不使用一个窗口,让一个窗口打开一个完全不同的窗口,然后我会看到一个对话框或一个完全不同的设计。另一方面,PropertyChangeListener只是实现观察者模式的一种方法;其他的都提到了。谢谢,这其实很有用。我将尝试创建一些我自己的事件,看看这种方式对我来说是否更好。在爪哇,考虑EnvithListNeList.
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);
}
}
}