Java Swing GUI未更新
我有一个简单的JavaSwing应用程序,它使用zip4j加密和解压zip文件。这是由这部分代码完成的:Java Swing GUI未更新,java,swing,event-dispatch-thread,Java,Swing,Event Dispatch Thread,我有一个简单的JavaSwing应用程序,它使用zip4j加密和解压zip文件。这是由这部分代码完成的: ZipFile zipFile = new ZipFile("dataStorage.zip"); zipFile.setPassword(password); zipFile.setRunInThread(true); ProgressMonitor progressMonitor = zipFile.getProgressMonitor(); if (!verify(zipFile))
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似乎已冻结。然而,圆点被打印到控制台上。如何修复它以更新进度条?包装调用
pbEncryptionProgress.setValue(progressMonitor.getPercentDone())请阅读SwingUtilities.invokeAndWait中的code>
您正在做的是通过睡眠和更新来使用EDT的所有资源,而不是留出任何时间让它实际重新绘制您的GUI。EDT用于GUI上的小型操作。您应该永远不要在EDT上调用Thread.sleep()
你所能做的就是制作一个计时器
,它将每秒运行一次检查,直到检查通过。这样EDT就可以自由地不冻结
更好的方法是使用SwingWorker
。它有一些方法可以完成您的特定任务:
- 要在后台执行的任务(在您的案例中-解压)
- 将部分结果发布到GUI的方法(在您的情况下为%done)
- 对部分结果作出反应的方法(在您的案例中-更新进度)
- 完成时要调用的方法(在您的案例中未显示,但无论如何都很有用)
您不应该在event dispacher线程上执行压缩操作(这是所有事件处理发生的地方)。创建一个SwingWorker
或类似的工具,将繁重的任务转移到一个单独的处理线程上,然后通知进度条,该进度条可以在EDT上更新。对于您的解决方案,只有在EDT再次空闲时,即zip操作完成后,才能处理对进度条的所有更新。这可能会有所帮助。错误:无法从事件分派器线程调用invokeAndWait
,然后不要使用thread.sleep()来避免事件分派器线程阻塞。改为定义javax.swing.Timer,并在计时器的actionPerformed()中更新进度call@StanislavL也许他/她是对的,调用EANDWAIT不应该从EDT中调用???,否则重新绘制经理是对的***/blocked@mKorbel从方法的javadoc来看,当应用程序线程需要更新GUI时,应该使用此方法。不应从事件调度线程调用它。