Java GUI中的JProgressBar无法绘制

3
我有一个GUI问题需要解决,但我对发生的事情感到困惑,希望你们中的一位能够解释一下。代码库过于庞大,无法上传,但我会详细说明发生了什么:
我有一个名为“ProgressBar”的类,它是一个包含Swing JProgressBar的JDialog。我有一些getter和setter来更改进度条以符合我的喜好,然而问题来了。
ProgressBar在方法“myButtonActionPerformed”中生成。
myButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                myButtonActionPerformed(evt);
            }
        });

当用户点击此按钮时,处理过程开始并生成 ProgressBar

用户当前在一个 JFrame 前面,进度条会弹出在一个 JDialog 中。在 Netbeans 的调试模式中,我可以看到 JProgressBar 的值被改变了,但是当程序正在处理时,进度条的视觉效果仍然停留在 0%,然后在离开上面的 add action listener 方法时立即跳到 100%,就好像它在等待重绘直到离开该监听器。我没有理解什么?有没有什么方法可以在这个 myButtonActionPerformed 方法内部强制更新它,而不是等到它无用为止。

3个回答

5

您是否在EDT中进行耗时操作?请记住,AWT/Swing有一个专用线程负责GUI工作——处理事件处理程序、重新绘制GUI等。如果您在该线程上执行长时间运行的任务,Swing将不会重绘。

尝试在另一个线程中执行任务,并相应地更新进度条。使用SwingUtilities.invokeLaterinvokeAndWait来更新进度条,以确保GUI更新发生在EDT上。否则,事情会变得非常奇怪。


非常感谢,这听起来很合理。我查找了一些你给我的东西,并且发现以下链接对于将来在浏览此论坛帖子的其他人来说是有用的:http://java.sun.com/developer/technicalArticles/javase/swingworker/#EDT - Ryan
@Ryan:是的,我应该提到SwingWorker。抱歉。而且,我想那个链接会引导你朝着正确的方向前进。 - Joey

1
原因是您的UI线程在ActionPerformed监听器中忙于处理,因此它不会更新。如果您尝试与应用程序交互,您会注意到UI上没有响应。
解决方法是不要在UI线程上进行处理 - 启动另一个线程,在该线程上进行处理,并回调到UI线程以更新进度条。

1

首先,您的匿名ActionListener只是转发到一个名为myButtonActionPerformed的方法,因此显然问题不在发布的代码中,而是在myButtonActionPerformed内部发生或导致发生的某些事情。因此,如果可能的话,这将是要发布的相关代码。

其次,其他人可能已经解决了这个问题,因为最有可能的原因是EDT上的重度处理。可以使用SwingWorkers有效地将进度/状态更新路由到适当的GUI线程,并将后台处理移出EDT。

第三:出于兴趣,您是否使用NetBeans进行GUI设计?对我来说看起来像是自动生成的代码。


是的,我也使用NetBeans进行设计。 - Ryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接