我开发了一个用于创建和提取存档的 Java 应用程序 - 例如 WinRAR。您可以使用多线程同时创建多个存档。最近,我想在每次创建存档时在新的 JFrame 中以 JProgressBar 的形式添加一个信息状态。
但我的问题是在新的状态框架和创建存档的线程中生成信息。这就是为什么我在存档线程中创建 JFrame 以当前更新进度条。
但就像我可以在不同的信息源和您的答案/评论中阅读它一样,它是反对 Java 摇摆和性能;我无法在 EDT 之外的其他地方创建 swing 对象。
但那么,我该如何解决我的问题呢?如何在存档的写入与其状态 JFrame(使用 JProgressBar)之间建立通信?
编辑:
我实现了 SwingWorker 来管理应用程序中的 GUI。现在完成了,我还有一个问题:
使用 SwingWorker,如何通过状态框架按钮上的事件来处理后台任务? (例如:暂停压缩或停止压缩。)
I developed a Java application for creating and extracting an archive - like WinRAR. You can create several archives at the same time with multithreading. And recently, I wanted to add an information status during the archive creation in the form of JProgressBar in a new JFrame at every creation.
But my problem is generating information in the new status frame and the thread which create the archive. That's why I create the JFrame in the archive thread for updating the progress bar currently.
But like I could read it in a diverse information source and on your answers/comments, it's against Java Swing and performance; I can't create swing object elsewhere that the EDT.
But then, how should I solve my problem? How can I etablish communication between the writing of my archive and its status JFrame (with JProgressBar)?
EDIT:
I implemented SwingWorker to manage the GUI in my application. Now it's done, I have an other question:
With SwingWorker, how do I act on the background task with an event on status Frame's button? (Example: pause compression or stop it.)
发布评论
评论(3)
正如其他人所建议的,最好的方法是使用
SwingWorker
。SwingWorker
属性是可侦听的,并且侦听器始终在 EDT 中调用,因此,您可以执行以下操作:然后您可以根据需要使用
ArchivingWorker
:As suggested by others, the best way is to use
SwingWorker
.SwingWorker
properties are listenable and listeners are always called in the EDT, thus, you could do something like:Then you can use
ArchivingWorker
as you need it:在 JProgressBar "http://download.oracle.com/javase/tutorial/uiswing/components/dialog.html" rel="nofollow">JDialog,并且不要创建新的 顶级容器。创建一次并重复使用
长时间且繁重的代码将更好地重定向到后台任务
您可以继续前进来自后台任务的
JProgressBar
仅当 GUI 相关代码在 EDT 上完成时,更多 并发在 Swing 中
有两种正确的方法
通过使用SwingWorker
来自
Runnable#Thread
,但 GUI 相关代码必须包装到invokeLater()
Put and display JProgressBar in a JDialog, and don't create a new Top-Level Container. Create that once and re-use that
Long timed and heavy code would be better redirected to the BackGround Task
You can move with progress in
JProgressBar
from a background taskonly if GUI related code is done on EDT more Concurrency in Swing
and there are two correct ways to do it
by using SwingWorker
from
Runnable#Thread
but GUI rellated code must be wrapped intoinvokeLater()
@mKorbel 提供的答案很好,但实际上没有必要使用另一个顶级容器(例如
JDialog
)来显示进度条。相反,您可以使用JFrame
实例。The answer provided by @mKorbel is fine, but there really is no need to use another top-level container (e.g. a
JDialog
) to display the progress bar. Instead, you can use the Glass Pane of theJFrame
instance.