【发布时间】:2013-11-20 22:19:58
【问题描述】:
假设我们有一个简单的 Java MVC 应用程序,其中包含 Model、View 和 Controller 类。 View 类直接继承自 JFrame。在classic MVC setup 中,视图具有对模型的引用,而控制器具有对视图和模型的引用。
正如我刚刚了解到的,所有与 GUI 相关的东西都应该包含在 SwingUtilities.invokeLater 或类似的东西中。现在初始化/启动这个应用程序的正确方法是什么?我认为模型和控制器的创建不应该在 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 正确指出的那样,检查了一个相关示例here。然后我扩展我的问题:基本上做了以下事情:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Model model = new Model();
View view = new View(model);
new Controller(model, view);
}
});
但是在 EDT 中运行整个应用程序不是错的吗?
【问题讨论】:
-
我会“猜测”控制器将需要某种方式来“启动”或“显示”视图...此外,您不应为此使用第二个
Thread,只需执行更新在您粘贴到SwingUtilities.invokeLater的Runnable的run方法的上下文中,以便您的所有 UI 交互都在 EDT 的上下文中进行... -
检查了一个相关的例子here。
-
查看更新后的问题。 @MadProgrammer:视图已设置并在其构造函数调用中可见。然后通过模型的事件更新它(模型扩展了 Observable 并且视图观察模型)。
-
“但是在 EDT 中运行整个应用程序不是错吗?” 这是上下文相关的。只要模型/视图/控制器不阻塞 EDT,这就是属于的地方。如果任何部分需要执行一些长时间运行的进程,那么它应该将该任务卸载到另一个线程,以免阻塞 EDT
-
直到一个 JComponent 被“实现”,即可见,你可以在任何你想要的线程上进行设置。完成所有设置,然后致电
pack()和setVisible()。许多应用程序会产生线程来设置复杂的 GUI。
标签: java swing model-view-controller thread-safety