3

我开发了一个用于创建和提取存档的Java应用程序 - 例如WinRAR。您可以使用多线程同时创建多个存档。最近,我想在创建档案的过程中以JProgressBar的形式在每次创建时在新的JFrame中添加信息状态。在多任务应用程序中管理GUI和EDT

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

但是就像我可以在不同的信息源和你的答案/评论中阅读它,这是针对Java Swing和性能;我无法在EDT的其他地方创建摆动物体。

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


编辑:

我实现的SwingWorker来管理我的应用程序的GUI。现在完成了,我还有其他问题:

使用SwingWorker时,如何在状态为Frame的按钮的事件上对后台任务执行操作? (实施例:暂停压缩或停止它。)在一个JDialog

回答

5

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

SwingWorker性能可听和听众总是堪称EDT,因此,你可以这样做:

public class ArchivingWorker extends SwingWorker<Void, Void> { 
    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(); 
+0

+1如果你对Swing有最深的了解 – mKorbel

+0

我真的忘了问你,你知道一些关于http://stackoverflow.com/questions/7053865/cant-get-arrayindexoutofboundsexception-from-future-and-swingworker-如果线程 – mKorbel

+0

@mKorbel不,但我会学习。我想它谈论的是摆动工作者的配合。 – damson

5
  1. PUT和显示JProgressBar,并且不产生新的Top-Level Container。创建一次,并重新使用该

  2. 朗定时和重码会更好重定向到后台任务

  3. 你可以进步JProgressBar从后台任务只移动

    • 如果与GUI相关的代码在EDT上完成更多Concurrency in Swing

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

      • 使用SwingWorker

      • Runnable#Thread但GUI rellated代码必须被包裹成invokeLater()

+1

@annonymous_up -voter谢谢,10k !!! – mKorbel

+0

我想我理解挥杆表现的一致性。我开始用SwingUtilities(invokeLater/isEventDispatchThread)开发一个新的实现,但代码太重,状态GUI有一些bug和冻结。我将尝试与SwingWorker。 – damson

+0

最简单和完全可管理的是通过使用Runnable#线程 – mKorbel

1

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

+0

感谢您的答案。 关于顶级容器,我没有任何使用它的选择,因为JDialog全面关注应用程序,多任务变得毫无用处。 (我不知道我是否可以理解;告诉我,如果我不知道) – damson

+0

@damson,没有......没有什么意义。 – mrkhrts

相关问题