dam*_*son 3 java user-interface swing multithreading event-dispatch-thread
我开发了一个用于创建和提取存档的Java应用程序 - 比如WinRAR.您可以使用多线程同时创建多个归档.最近,我希望在每个创建时在新的JFrame中以JProgressBar的形式在存档创建期间添加信息状态.
但我的问题是在新的状态框架和创建存档的线程中生成信息.这就是我在存档线程中创建JFrame以更新当前进度条的原因.
但就像我可以在各种信息源和你的答案/评论中阅读它一样,它反对Java Swing和性能; 我无法在EDT的其他地方创建摆动对象.
但那么,我该如何解决我的问题呢?如何在存档的写入和状态JFrame(使用JProgressBar)之间建立通信?
编辑:
我实现了SwingWorker来管理我的应用程序中的GUI.现在已经完成了,我还有一个问题:
使用SwingWorker,如何使用状态框架按钮上的事件对后台任务执行操作?(示例:暂停压缩或停止压缩.)
将JProgressBar放在JDialog中并显示,不要创建新的顶级容器.创建一次并重复使用它
长时间和繁重的代码将更好地重定向到BackGround任务
您可以JProgressBar从后台任务进度移动
并且有两种正确的方法可以做到这一点
通过使用SwingWorker
从Runnable#Thread但GUI rellated代码必须被包裹成invokeLater()
正如其他人所说,最好的方法是使用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
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以ArchivingWorker根据需要使用它:
ArchivngWorker worker = new ArchivingWorker(...);
worker.execute();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1255 次 |
| 最近记录: |