首先,我最近一直在使用Java的Concurrency软件包,但是我发现了一个问题,我被困在了。我想拥有,应用程序和应用程序可以有SplashScreen
状态栏和其他数据的加载。所以我决定使用SwingUtilities.invokeAndWait( call the splash component here )
。然后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的Threads等等。 CountDownLatch实际上以我想要处理的方式工作但我无法更新GUI。使用SwingWorkers
时,invokeAndWait
基本上无效(这是他们的目的),或者即使使用PropertyChangedListener
也不会更新GUI。如果其他人有一些想法,那么听听他们会很棒。提前谢谢。
我实际上已准备好发布更好的代码来帮助并找到我的解决方案。感谢所有帮助过的人。
答案 0 :(得分:5)
要在后台运行一系列操作并报告进度,请使用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
}
}
};
<强>附录:强>
这可以扩展到多个任务,只需要更改设置进度条的方法。这就是我想到的:
有一个完成计数器数组,每个任务一个。
int[] completions = new int[numTasks];
Arrays.fill(completions,0);
启动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);
}
(可选)显示每个任务的JProgressBar。
附录2:
如果任务的完成时间不同(例如,缓存命中与缓存未命中),您可能需要调查ProgressMonitor。这是一个进度对话框,仅当任务需要超过一些(可配置的,默认的500毫秒)时间时才会出现。
答案 1 :(得分:0)
无需在invokeAndWait中调用框架,但您应该像这样更新进度条状态。
try {
SwingUtilities.invokeAndWait( new Runnable() {
public void run() {
//update state of the progress bar here
}
});
} catch (InterruptedException e) {
} catch (InvocationTargetException e) { }