我开发了一个Java应用程序,用于创建和提取类似于WinRAR的存档。您可以同时使用多线程创建多个档案。最近,我想在归档创建期间以每次创建的新JFrame中的JProgressBar形式添加信息状态。
但是我的问题是在新的状态框架和创建档案的线程中生成信息。这就是为什么我在存档线程中创建JFrame以便当前更新进度条。
但是就像我可以在各种信息源中以及您的答案/评论中阅读它一样,它与Java Swing和性能背道而驰;我不能在EDT的其他地方创建swing对象。
但是,我该如何解决我的问题呢?如何建立归档文件及其状态JFrame(使用JProgressBar)之间的通信?
编辑:
我实现了SwingWorker来管理应用程序中的GUI。现在完成了,我还有另一个问题:
使用SwingWorker,如何通过状态框架按钮上的事件来执行后台任务?(例如:暂停压缩或停止压缩。)
正如其他人所建议的,最好的方法是使用SwingWorker。
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根据需要使用:
ArchivingWorker
ArchivngWorker worker = new ArchivingWorker(...); worker.execute();