【发布时间】:2014-05-08 06:33:52
【问题描述】:
我想在真正复杂的对话开始时使用进度监视器来显示进度!!!
对话框的创建是在事件调度线程中完成的。这可能需要长达 10 秒,具体取决于客户端系统。
然后我希望在前台看到一个进度监视器,它显示每个当前加载部分的状态。与此同时,对话框正在后台建立。
问题是进度监视器总是冻结,直到对话框启动。当对话启动完成时,progressmonitor 会做出反应并显示当前状态。
我尝试了很多在论坛上阅读的内容,但如果没有两个不同的主题,它就无法正常工作。这是让进度监视器和对话框创建都在 EDT 中运行的示例。
final CVProgressMonitorDialog progressMonitor = new CVProgressMonitorDialog();
progressMonitor.startPollingThread();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
startComplexDialog();
}
finally {
close(progressMonitor);
}
}
});
CVProgressMonitorDialog主要是swing自带的ProgressMonitor。
解决方案是让对话框的创建在另一个线程中运行。
final CVProgressMonitorDialog progressMonitor = new CVProgressMonitorDialog();
progressMonitor.startPollingThread();
new Thread() {
@Override
public void run() {
try {
startComplexDialog();
}
finally {
close(progressMonitor);
}
}
}.start();
由于 swing 不是线程安全的,使用第二种解决方案是否会导致潜在的麻烦?
是否有通用的解决方案来监控 EDT 内的任务?
【问题讨论】:
-
是的,第二种解决方案不安全。解决此问题的一种方法是将对话的初始化拆分为不同的任务,并将它们作为不同的块启动到 EDT,并在它们之间适当地更新进度监视器(也在 EDT 中)。如果您正在读取数据或创建内部非 Swing 相关结构,还要检查是否可以将一些工作移到 EDT 之外。
标签: java swing progressdialog swingworker event-dispatch-thread