如何使用Swing GUI启动Java MVC应用程序

如何使用Swing GUI启动Java MVC应用程序,java,swing,model-view-controller,thread-safety,Java,Swing,Model View Controller,Thread Safety,让我们假设我们有一个简单的Java MVC应用程序,其中包含类Model、View和Controller。视图类直接继承自。与在中一样,视图具有对模型的引用,而控制器具有对视图和模型的引用。 正如我刚刚学到的,所有与GUI相关的东西都应该包装在一个或类似的文件中。现在,初始化/启动此应用程序的正确方法是什么?我认为模型和控制器的创建不应该在EDT内部,对吗?所以我会想出这样的办法: final Model model = new Model(); SwingUtilities.invokeLat

让我们假设我们有一个简单的Java MVC应用程序,其中包含类
Model
View
Controller
视图
类直接继承自。与在中一样,视图具有对模型的引用,而控制器具有对视图和模型的引用。 正如我刚刚学到的,所有与GUI相关的东西都应该包装在一个或类似的文件中。现在,初始化/启动此应用程序的正确方法是什么?我认为模型和控制器的创建不应该在EDT内部,对吗?所以我会想出这样的办法:

final Model model = new Model();
SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        final View view = new View(model);
        new Thread(new Runnable() {
            @Override
            public void run() {
                new Controller(model, view);
            }
        }).start();
    }
});
这是正确的方法和好主意还是有更好的可能性

编辑: 正如@trashgod所正确指出的那样,我们研究了一个相关的例子。然后我扩展我的问题:基本上做了以下几点:

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        Model model = new Model();
        View view = new View(model);
        new Controller(model, view);
    }
});

但是在EDT中运行整个应用程序不是不对吗?

所有创建或与Swing组件交互的代码都必须在事件调度线程上运行。因此,代码的第二种形式,即下面的代码是正确的

`SwingUtilities.invokeLater(new Runnable() {
        @Override
    public void run() {
        Model model = new Model();
        View view = new View(model);
        new Controller(model, view);
    }
});`
所有UI代码必须通过EDT或工作线程运行的原因是为了避免多线程问题。您可能会看到许多swing程序可能不在EDT中初始化代码。这完全可以。但当你的挥杆变得复杂时,就有可能出错。我自己在简单的swing应用程序中从主线程切出,我并没有面临死锁都是竞争条件。快速任务使用EDT,长时间运行的任务使用工作线程。


请让我知道如果我出错了

我会“猜测”控制器将需要某种方式来“启动”或“显示”视图……此外,您不应该为此使用第二个
线程
,只需在粘贴到
SwingUtilities.invokeLater
Runnable
方法的
上下文中执行更新即可,因此,您的所有UI交互都是在EDT上下文中进行的…我们将检查一个相关示例。请参阅更新的问题@MadProgrammer:视图已设置,并在其构造函数调用中可见。然后通过模型的事件进行更新(模型扩展了可观察性,视图观察模型)。“但是在EDT中运行整个应用程序不是不对吗?”这是上下文。只要模型/视图/控制器未阻塞EDT,这就是EDT所在的位置。如果任何部件需要执行一些长时间运行的过程,那么它应该将该任务卸载到另一个线程,以便在JComponent“实现”(即可见)之前不阻塞EDT,您可以在任何想要的线程上进行设置。执行所有设置,然后调用
pack()
setVisible()
。许多应用程序生成线程来设置复杂的GUI。