java - Swing GUI 未更新

标签 java swing event-dispatch-thread

我有一个简单的 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/

相关文章:

java - 如何为 Sun App Server 8.2 设置 JNDI

java - 创建一个具有 gui 的服务器应用程序

Java Swing 在不同选项卡中重用按钮

Java 图形用户界面倒计时

java - 如有必要,在 Java Swing EDT 中运行函数

java - Android中如何将数据从一个应用程序传输到另一个应用程序

java - 在 libgdx 中,如何为 box2d Body 对象添加摩擦力?

java - Eclipse RCP 3.X 到 4——经典 CSS

java - 如何通过关闭JFrame直接关闭JOptionPane?

Java Swing Dialog,如何在捕获WindowClosing事件时调用wait方法