具有可更新 JProgressBar 的 Java Swing 线程
首先,我最近一直在使用 Java 的并发包,但我发现了一个我遇到的问题。我想要一个应用程序,并且该应用程序可以有一个带有状态栏和加载其他数据的 SplashScreen
。所以我决定使用SwingUtilities.invokeAndWait(在此处调用splash组件)。然后,SplashScreen
会与 JProgressBar
一起出现,并运行一组线程。但我似乎无法很好地处理事情。我查看了 SwingWorker
并尝试使用它来实现此目的,但线程只是返回。这是一些伪代码。以及我想要实现的目标。
- 拥有一个
SplashScreen
的应用程序,该应用程序在加载信息时暂停 - 能够在
SplashScreen
下运行多个线程 - 具有
SplashScreen
更新的进度条- 可以但在所有线程完成之前不会退出。
启动启动屏幕
try {
SwingUtilities.invokeAndWait( SplashScreen );
} catch (InterruptedException e) {
} catch (InvocationTargetException e) { }
启动屏幕构造
SplashScreen extends JFrame implements Runnable{
public void run() {
//run threads
//while updating status bar
}
}
我尝试了很多东西,包括 SwingWorkers
、使用 CountDownLatch 的线程等等。 CountDownLatch 实际上按照我想要的方式工作,但我无法更新 GUI。使用 SwingWorkers
时,invokeAndWait
基本上无效(这就是它们的目的),或者即使使用 PropertyChangedListener
也不会更新 GUI >。如果其他人有一些想法,那么很高兴听到它们。提前致谢。
我实际上已经准备好发布更好的代码来帮助解决并找到了我的解决方案。我感谢所有提供帮助的人。
First off I've been working with Java's Concurrency package quite a bit lately but I have found an issue that I am stuck on. I want to have and Application and the Application can have a SplashScreen
with a status bar and the loading of other data. So I decided to use SwingUtilities.invokeAndWait( call the splash component here )
. The SplashScreen
then appears with a JProgressBar
and runs a group of threads. But I can't seem to get a good handle on things. I've looked over SwingWorker
and tried using it for this purpose but the thread just returns. Here is a bit of pseudo code. and the points I'm trying to achieve.
- Have an Application that has a
SplashScreen
that pauses while loading info - Be able to run multiple threads under the
SplashScreen
- Have the progress bar of the
SplashScreen
Update-able yet not exit until all threads are done.
Launching splash screen
try {
SwingUtilities.invokeAndWait( SplashScreen );
} catch (InterruptedException e) {
} catch (InvocationTargetException e) { }
Splash screen construction
SplashScreen extends JFrame implements Runnable{
public void run() {
//run threads
//while updating status bar
}
}
I have tried many things including SwingWorkers
, Threads using CountDownLatch's, and others. The CountDownLatch's actually worked in the manner I wanted to do the processing but I was unable to update the GUI. When using the SwingWorkers
either the invokeAndWait
was basically nullified (which is their purpose) or it wouldn't update the GUI still even when using a PropertyChangedListener
. If someone else has a couple ideas it would be great to hear them. Thanks in advance.
I actually got ready to post better code to help out and found my solution. I thank you for all who helped.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
要在后台运行一系列操作并报告进度,请使用 SwingWorker。
background
方法进行后台处理。使用
publish
方法发布定期状态更新。重写
process
方法来处理更新(process
始终在 EDT 上执行)。附录:
这可以扩展到多个任务,它只需要改变设置进度条的方式。我想到的是:
有一组完成计数器,每个任务一个。
启动SwingWorkers,每个都传递一个索引号。然后,
process
或done
方法调用类似的方法来更新整体进度条。(可选)为每个任务显示一个 JProgressBar。
附录 2:
如果任务的完成时间不同(例如,缓存命中与缓存未命中),您可能需要调查ProgressMonitor。这是一个进度对话框,仅当任务花费超过一定时间(可配置,默认 500 毫秒)时才会出现。
For running a series of operations in the background and reporting progress, use SwingWorker.
The
background
method does the background processing.Use the
publish
method to post periodic status updates.Override the
process
method to handle the updates (process
always executes on the EDT).Addendum:
This can be extended to multiple tasks, it just requires changing how you approach setting the progress bar. Here's what comes to mind:
Have an array of completion counter, one per task.
Start the SwingWorkers, each passed an index number. The
process
ordone
methods then call something like this to update the overall progress bar.Optionally, display a JProgressBar per task.
Addendum 2:
If the tasks vary in completion time (eg, cache hit vs cache miss), you may want to investigate ProgressMonitor. It's a progress dialog that only appears if the task takes more than some (configurable, default 500ms) amount of time.
无需在 invokeAndWait 中调用框架,但您应该像这样更新进度条状态。
No need to call the frame inside invokeAndWait but you should update progress bar state like this.