我有一个简单的 Java Swing 应用程序,它使用 zip4j 来加密和解压 zip 文件。这是由这部分代码完成的:
ZipFile zipFile = new ZipFile("dataStorage.zip");
zipFile.setPassword(password);
zipFile.setRunInThread(true);
ProgressMonitor progressMonitor = zipFile.getProgressMonitor();
if (!verify(zipFile)) {
JOptionPane.showMessageDialog(null, "You have entered incorrect password!", "ERROR", 0);
return;
}
zipFile.extractAll("./"); //runs in new thread
//After entering this while GUI freezes
while (progressMonitor.getState() == ProgressMonitor.STATE_BUSY) {
System.out.print("."); // this works normally...
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
//
}
pbEncryptionProgress.setValue(progressMonitor.getPercentDone()); //this is not updating progress bar, but getPercentDone is returning correct data
}
问题是进度条没有更新。应用程序 GUI 似乎卡住了。然而,点被打印到控制台。我该如何修复它以更新进度条?
最佳答案
请阅读Concurrency in Swing 。
您正在做的是通过 sleep 和更新耗尽 EDT 的所有资源,而不留任何时间来实际重绘您的 GUI。 EDT 用于 GUI 上的小型操作。您不应该永远在 EDT 上调用 Thread.sleep()
。
您可以做的是创建一个计时器
,每秒运行一次检查,直到检查通过。这样 EDT 就可以自由地不卡住。
更好的方法是使用 SwingWorker
。它具有执行您的特定操作的方法:
- 在后台执行的任务(在您的情况下 - 解压缩)
- 将部分结果发布到 GUI 的方法(在您的情况下为 % 完成)
- 对部分结果使用react的方法(在您的情况下 - 更新进度)
- 完成后调用的方法(在您的案例中未显示,但无论如何很有用)。
关于java - Swing GUI 未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23954284/