Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MVC—JavaSwing中的观察者/可观察模式_Java_Swing_Model View Controller_Observer Pattern - Fatal编程技术网

MVC—JavaSwing中的观察者/可观察模式

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

我正在尝试构建一个基于MVC的Swing用户界面,并就这个主题提出了几个问题。问我问题的最好方法是借助一个简单的例子

假设我们有一个JDialog,其中有一个JButton和3个JTextFields。当按下这个按钮时,我希望这个JDialog关闭,另一个JDialog打开,它需要来自3个jtext字段的数据

简单的方法是,只需编写代码片段,无需过多地烦扰您:

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);
        }
    }

}