2


的Java Swing进度监控对于GUI创建(EDT)

我想用一个进度监视器一个真正复杂的对话开始时显示进度!

对话框创建在事件分派器线程内完成。根据客户端系统的不同,最多可能需要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(); 

使用第二种解决方案会导致潜在的麻烦,因为摆动不是线程安全的吗?
是否有一个通用的解决方案来监控EDT内的任务?

+0

是的,第二种解决方案不安全。解决这个问题的一种方法是将对话的初始化分解为不同的任务,然后将它们作为不同的块加载到EDT中,并在它们之间更新进度监视器(也在EDT中)。如果您正在读取数据或创建内部非Swing相关结构,请检查您是否可以将部分工作移至EDT之外。 – DSquare

回答

1

幽州:

对话框创建是事件调度线程中完成的。根据客户端系统的不同,最多可能需要10秒。

还有你的问题。您需要在后台线程(如SwingWorker提供的后台线程)中运行任何非Swing长时间运行的代码,但请注意确保在事件线程上完成了更改可见Swing组件状态的任何代码。

然后,我希望在前台看到一个进度监视器,它显示了每个当前加载部件的状态。同时该对话框正在后台建立。

再次,做一个SwingWorker的衍生后台线程你的工作,更新的SwingWorker的进度属性作为创作的进行,并使用一个PropertyChangeListener添加到您的SwingWorker监控和显示变化的进展。

0

正如另一个答案所述,你不应该在美国东部时间做冗长的操作。但是如果你很急,我使用模态JDialog来管理类似的情况。当模态对话框变得可见时,它将阻塞进行setVisible(true)调用的线程并获得它自己的调度线程。它可以独立于EDT进行更新。在其中一个进度条上进行,应该没问题。