1

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

假设我们有一个带有一个 JButton 和 3 个 JTextField 的 JDialog。当按下该按钮时,我希望此 JDialog 关闭并打开另一个需要来自 3 个 JTextField 的数据的按钮。

这样做的简单方法(只需要代码片段,不需要太烦你)是:

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 个 JTextFields 传递到我的 mouseListener 类?除了在 Listener 类中保留视图的引用之外,还有其他选择吗?

继续,给定 MVC 模式:

第二个问题:我想监听器(根据 MVC 的控制器)在不涉及模型的情况下调用另一个窗口是有意义的,我猜这是工作。但是需要从一个窗口传递到下一个窗口的数据(来自 3JTextFields 的数据)不应该通过模型吗?就像让第一个窗口将数据保存在模型中,然后当第二个窗口需要它们时从模型中请求它们。

第三个问题:我正在考虑使用 Observer/Observable 模式。在此示例中如何使用它来打开最后一个窗口?我的意思是,因为(我认为)Controller 是打开第二个窗口的类,这是否意味着 Listener 必须被 Observed 并且第二个窗口必须是 Observer 以便 Listener 会说

 notifyObservers("openSecondWindow");

然后第二个窗口会看到它并自行打开?

最后:我听说 PropertyChangeListener 也可以工作,而且有时它优于观察者/可观察模式。你对此有何看法,尤其是关于我的例子。

我很困惑..

感谢您的时间。

4

2 回答 2

0

我不确定 Java 的特定方面。但是谈到 OOP,让您的应用程序通过事件驱动设计解耦是非常合理的。因此,您不会直接处理组件,而是触发事件,正如您所写notifyObservers("openSecondWindow");

但是,您不需要通过模型层来执行此操作。相反,您应该有一个event代表给定事件的类,并在事件类中设置提到的字段的值。

就像是:

exampleEvent.setProperty1('blah').setProperty2('blah2');
notify('openSecondFrame', exampleEvent);

不久前,我发布了一个关于这个事件驱动的东西的问题:

PHP:我是否将事件驱动编程与信号感知接口(信号和插槽/观察者模式)混为一谈?

您可能有兴趣阅读几个链接(它是 PHP,但该概念适用于 OOP)。

因此,遵循这个概念,创建一个EventHandler组件来管理这些事件和信号是一个好主意。

但同样,考虑到我不精通 Java。这只是关于 OOP。

于 2012-09-08T16:45:50.930 回答
0

第一个问题

如果我不使用匿名内部类但决定为我的 Listener 使用单独的类,我将如何将数据从 3 个 JTextFields 传递到我的 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,尽管这是一个痛苦的过程。当我扩展 aJPanel以制作JCroppingPanel.

于 2012-09-11T17:13:56.910 回答