在主方法中使用 SwingUtilities.invokeLater()

问题描述

最近看到一个MVC java应用,里面的main方法是这样写的:

    public static void main(String[] args) 
    {
        SwingUtilities.invokelater(new Runnable() 
        {
            public void run() 
            {
                View view = new View();
                Model model = new Model();
                Controller controller = new Controller(view,model);
                controller.start();
            }
        });
    }

这不会使所有程序(包括模型和控制器,与 Swing 完全无关)一直运行到代码在 AWT 事件调度线程而不是主线程中结束?

如果最后一个是真的,那么这对应用程序来说真的很糟糕,因为它会阻止 EDT 执行它需要的任务(例如,调度事件,因为模型可能正在计算其他任务)。正确吗?


一个类似的 old post(不是这个的重复)可以表明上面提到的代码是一种很好的做法,所以它让我更加困惑。

解决方法

您展示的代码片段的目的是创建 Swing UI 和模型并将它们连接在一起。

没有 Swing 更新(在对用户输入做出反应方面),因为在 run() 方法结束之前不能有任何用户输入。

虽然您可以在主线程和 EDT 之间拆分这些任务(并且可能会在第一次显示 UI 之前获得几毫秒的时间),但它也会使应用程序的设计复杂化(多线程不是一个简单的话题)并且将代码库乱扔垃圾invokeLater() 调用。除非有人证明这是必要的,否则我不会这样做。


恕我直言,EDT 任何 GUI 应用程序中的主线程。对用户输入的每一次反应都从这个线程开始,UI 的每一次更新都必须在这个线程中完成。

长时间运行的任务应该在后台线程中完成 - 这通常意味着需要超过几毫秒的时间。

如果创建模型需要几秒钟怎么办?

在那种情况下,我会尝试将模型创建分为两部分:

  • 创建所需的最小部分,以便可以显示 UI。这应该在 EDT 中完成(因为用户无论如何都必须等待这部分的完成 - 在显示 UI 之前,他无法与之交互)
  • 在后台线程中完成剩余的、长时间运行的部分。

如果不能这样做怎么办?(即在模型完全初始化之前无法显示 UI)

在这种情况下,用户必须等待模型的完全初始化,然后才能看到和使用 UI。所以这个初始化是在 EDT 还是在主线程上运行都没有关系。因此,请使用更简单的解决方案:EDT 上的所有内容。

但是通过显示 splash screen

来提示用户您的应用程序正在启动

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...