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

Using SwingUtilities.invokeLater() in main method

最近看到一个MVCjava应用,其中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

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