正确加载大型Java Swing UI而不冻结它

时间:2018-02-07 11:30:03

标签: java multithreading swing event-dispatch-thread

我正在开发一个大型Swing应用程序,其中包含许多在应用程序启动时加载的组件。加载组件,设置其属性并将其添加到面板的过程需要几秒钟。

应用程序UI在加载应用程序期间冻结。我想在加载整个UI时显示一个启动加载屏幕,但是启动也会冻结。

如果我将UI构造移动到另一个线程,这将是EDT线程违规。

在不冻结UI的情况下加载此类Swing界面的正确方法是什么?

我已经看到了关于这个主题的现有答案,但它们涵盖了与Swing无关的外部任务阻止UI的情况,但在这里,复杂UI本身的构建阻碍了UI刷新 (启动画面进度条)。

1 个答案:

答案 0 :(得分:2)

解决这个问题有两种可能性。

  1. 您将UI初始化分成小块并使用SwingUtilities.invokeLater调用每个块。每个invokeLater触发重新绘制,因此您的GUI可以刷新。这应该是首选方式。
  2. 当您将应用程序拆分为小的独立块时遇到问题时,您可能会“错误地”Foxtrot lib为UI重新绘制提供同步中断

    public static void sleepNonBlocking(long millis) {
        Worker.post(new Job() {
    
            @Override
            public Object run() {
                try {
                    Thread.sleep(millis);
                } catch (Exception e) {
                    // nothing
                }
                return null;
            }
        });
    }
    

    您需要在应用程序的某些位置调用此方法以强制重新投影。