正确加载大 Java Swing UI 而不会冻结它
Properly to loading a large Java Swing UI without freezing it
我正在开发一个大型 Swing 应用程序,其中包含许多在应用程序启动时加载的组件。加载组件、设置它们的属性并将它们添加到面板的过程需要几秒钟。
应用程序 UI 在加载应用程序期间冻结。我想在加载整个 UI 时显示启动画面,但启动画面也冻结了。
如果我将 UI 构造移动到另一个线程,这将违反 EDT 线程。
在不冻结 UI 的情况下加载此类 Swing 界面的正确方法是什么?
我已经看到关于这个主题的现有答案,但它们涵盖了与 Swing 无关的外部任务阻塞 UI 的情况,但在这里,复杂的构造 UI 本身正在阻止 UI 刷新 (闪屏进度条)。
解决这个问题有两种可能。
- 您将 UI 初始化分成小块并使用
SwingUtilities.invokeLater
调用每个块。每个invokeLater
触发重绘,所以你的GUI可以刷新。这应该是首选方式。
当您在将应用程序拆分为独立的小块时遇到问题时,您可以"misaply" Foxtrot lib 为 UI 重绘[=14] 提供同步中断=]
public static void sleepNonBlocking(long millis) {
Worker.post(new Job() {
@Override
public Object run() {
try {
Thread.sleep(millis);
} catch (Exception e) {
// nothing
}
return null;
}
});
}
您需要在应用程序的某些地方调用此方法来强制重绘。
我正在开发一个大型 Swing 应用程序,其中包含许多在应用程序启动时加载的组件。加载组件、设置它们的属性并将它们添加到面板的过程需要几秒钟。
应用程序 UI 在加载应用程序期间冻结。我想在加载整个 UI 时显示启动画面,但启动画面也冻结了。
如果我将 UI 构造移动到另一个线程,这将违反 EDT 线程。
在不冻结 UI 的情况下加载此类 Swing 界面的正确方法是什么?
我已经看到关于这个主题的现有答案,但它们涵盖了与 Swing 无关的外部任务阻塞 UI 的情况,但在这里,复杂的构造 UI 本身正在阻止 UI 刷新 (闪屏进度条)。
解决这个问题有两种可能。
- 您将 UI 初始化分成小块并使用
SwingUtilities.invokeLater
调用每个块。每个invokeLater
触发重绘,所以你的GUI可以刷新。这应该是首选方式。 当您在将应用程序拆分为独立的小块时遇到问题时,您可以"misaply" Foxtrot lib 为 UI 重绘[=14] 提供同步中断=]
public static void sleepNonBlocking(long millis) { Worker.post(new Job() { @Override public Object run() { try { Thread.sleep(millis); } catch (Exception e) { // nothing } return null; } }); }
您需要在应用程序的某些地方调用此方法来强制重绘。