如何使用Swing GUI启动Java MVC应用程序
让我们假设我们有一个简单的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
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。