gpt4 book ai didi

具有可更新的 JProgressBar 的 Java Swing 线程

转载 作者:行者123 更新时间:2023-11-30 06:36:10 25 4
gpt4 key购买 nike

首先,我最近一直在使用 Java 的 Concurrency 包,但我发现了一个让我卡住的问题。我想要一个应用程序,该应用程序可以有一个带有状态栏和加载其他数据的 SplashScreen。所以我决定使用 SwingUtilities.invokeAndWait(在这里调用启动组件)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 >。如果其他人有一些想法,很高兴听到他们的意见。提前致谢。

我实际上已经准备好发布更好的代码来提供帮助并找到了我的解决方案。我感谢所有提供帮助的人。

最佳答案

要在后台运行一系列操作并报告进度,请使用 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,每一个传递一个索引号。 processdone 方法然后调用类似这样的方法来更新整体进度条。

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 毫秒)时间量时才会出现。

关于具有可更新的 JProgressBar 的 Java Swing 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5163508/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com