ars*_*265 2 java concurrency swing multithreading swingworker
首先,我最近一直在使用Java的Concurrency软件包,但我发现了一个问题,我被困在了.我想拥有和应用程序和应用程序可以有SplashScreen
一个状态栏和其他数据的加载.所以我决定使用SwingUtilities.invokeAndWait( call the splash component here )
.在SplashScreen
随后与出现JProgressBar
并运行一组线程.但我似乎无法很好地处理事情.我已经查看SwingWorker
并尝试将其用于此目的,但线程只是返回.这是一些伪代码.以及我正在努力实现的目标.
SplashScreen
在加载信息时有一个暂停的应用程序SplashScreen
SplashScreen
Update-able 的进度条在所有线程完成之前都不会退出.启动启动画面
try {
SwingUtilities.invokeAndWait( SplashScreen );
} catch (InterruptedException e) {
} catch (InvocationTargetException e) { }
Run Code Online (Sandbox Code Playgroud)
飞溅屏幕结构
SplashScreen extends JFrame implements Runnable{
public void run() {
//run threads
//while updating status bar
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了很多东西,包括SwingWorkers
使用CountDownLatch的Threads等等.CountDownLatch实际上以我想要处理的方式工作但我无法更新GUI.当使用SwingWorkers
任一invokeAndWait
已基本作废(这是他们的目的),或者使用时,它不会甚至仍在更新GUI PropertyChangedListener
.如果其他人有一些想法,那么听听他们会很棒.提前致谢.
我实际上准备好发布更好的代码来帮助我找到我的解决方案.感谢所有帮助过的人.
要在后台运行一系列操作并报告进度,请使用SwingWorker.
该background
方法进行后台处理.
使用该publish
方法发布定期状态更新.
覆盖process
方法以处理更新(process
始终在EDT上执行).
progressBar = new JProgressBar();
sw = new SwingWorker<Boolean,Integer>() {
protected Boolean doInBackground() throws Exception {
// If any of the operations fail, return false to notify done()
// Do thing 1
publish(25); // 25% done
// Do thing 2
publish(50); // 50% done
// Do thing 3
publish(75); // 75% done
// Do thing 4
return true;
}
protected void process(List<Integer> chunks) {
for (Integer i : chunks)
progressBar.setValue(i);
}
protected void done() {
try {
boolean b = get();
if (b)
progressBar.setValue(100); // 100% done
else
// Notify the user processing failed
}
catch (InterruptedException ex) {
// Notify the user processing was interrupted
}
catch (ExecutionException ex) {
// Notify the user processing raised an exception
}
}
};
Run Code Online (Sandbox Code Playgroud)
附录:
这可以扩展到多个任务,只需要更改设置进度条的方法.这就是我想到的:
有一个完成计数器阵列,每个任务一个.
int[] completions = new int[numTasks];
Arrays.fill(completions,0);
Run Code Online (Sandbox Code Playgroud)
启动SwingWorkers,每个都传递一个索引号.该process
或done
方法,然后调用这样的更新总体进度条.
void update(int index, int percComplete) {
completions[index] = percComplete;
int total = 0;
for(int comp: completions)
total += comp/numTasks;
overallPB.setValue(total);
}
Run Code Online (Sandbox Code Playgroud)
(可选)为每个任务显示JProgressBar.
附录2:
如果任务的完成时间不同(例如,缓存命中与缓存未命中),您可能需要调查ProgressMonitor.这是一个进度对话框,仅当任务需要超过一些(可配置的,默认的500毫秒)时间时才会出现.