在多任务应用程序中管理GUI和EDT

我开发了一个用于创建和提取存档的Java应用程序 – 比如WinRAR 。 您可以使用multithreading同时创建多个归档。 最近,我希望在每次创建时在新的JFrame中以JProgressBar的forms在存档创建期间添加信息状态。

但我的问题是在新的状态框架和创建存档的线程中生成信息。 这就是我在存档线程中创建JFrame以更新当前进度条的原因。

但就像我可以在各种信息源和你的答案/评论中阅读它,它反对Java Swing和性能; 我不能在EDT的其他地方创建摆动对象。

但那么,我应该如何解决我的问题呢? 如何在存档的写入和状态JFrame(使用JProgressBar)之间建立通信?


编辑:

我实现了SwingWorker来管理我的应用程序中的GUI。 现在已经完成,我还有一个问题:

使用SwingWorker,如何使用状态框架按钮上的事件对后台任务执行操作? (示例:暂停压缩或停止压缩。)

正如其他人所建议的那样,最好的方法是使用SwingWorker

SwingWorker属性是可听的,并且总是在EDT中调用侦听器,因此,您可以执行以下操作:

 public class ArchivingWorker extends SwingWorker { JProgressBar progressBar = null; // Other members here... ... public ArchivingWorker(...) { // Any specific initialization here (in EDT) addPropertyChangeListener(new PropertyChangeListener() { @Override void propertyChange(PropertyChangeEvent e) { if ( "state".equals(e.getPropertyName()) && e.getNewValue() == StateValue.STARTED) { // Background thread has just started, show a progress dialog here progressBar = new JProgressBar(); ... } else if ("progress".equals(e.getPropertyName())) { // Update progress bar here with e.getNewValue() ... } } }); } @Override protected Void doInBackground() { // Archiving process here and update progress from time to time setProgress(progress); return null; } @Override protected void done() { // Ensure that archiving process worked correctly (no exception) try { get(); } catch (Exception e) { // Handle exception (user feedback or whatever) } finally { // Close progress dialog ... } } } 

然后,您可以根据需要使用ArchivingWorker

 ArchivngWorker worker = new ArchivingWorker(...); worker.execute(); 
  1. 将JProgressBar放在JDialog中并显示,不要创建新的顶级容器 。 创建一次并重新使用它

  2. 长时间和繁重的代码将更好地重定向到BackGround任务

  3. 您可以从后台任务中移动JProgressBar进度

    • 只有在与EDT完成GUI相关的代码时才能在Swing中实现更多的并发性

    • 并且有两种正确的方法可以做到这一点

      • 通过使用SwingWorker

      • 来自Runnable#Thread #Thread但GUI相关代码必须包装到invokeLater()

@mKorbel提供的答案很好,但实际上不需要使用另一个顶级容器(例如JDialog )来显示进度条。 相反,您可以使用JFrame实例的Glass Pane 。