来自 EDT 问题的 Java Swing 进度条

标签 java radio-button swingworker progressdialog

这是为那里的挥杆专家准备的。我在这个问题上花了很多时间,所以我将花几行来解释这个问题。

我有一个独立的 java swing 应用程序 (java 6)。在我的应用程序中,我有一个带有单选按钮组的框架。我有一个链接到组中所有按钮的单一操作。该操作检查选择了哪个单选按钮并执行一些工作。 “工作”涉及一些背景计算以及我应用程序中其他两个框架中的一些绘画。后台计算是多线程的。

我想在用户选择其中一个单选按钮时显示一个进度条。 However, when a radio button is selected, while the action to the radio button is happening, the progress bar never appears.我已经尝试过 jdialog 类型的进度条、玻璃 Pane 等。在“工作”全部完成之前,它们都不会出现。这似乎是因为 Swing 直到相应 Action 中的“工作”完成后才完成绘制单选按钮。由于 EDT 一次只做一件事,因此永远不会显示进度条对话框(或玻璃 Pane )。

然后我尝试使用 SwingWorker 来完成所有这些“工作”。在 SwingWorker 的 done() 方法中启动进度条(或激活玻璃 Pane ),启动 SwingWorker 并关闭进度条(或停用玻璃 Pane )。这似乎可以很好地调出进度条,但是作为“工作”一部分的绘画有时没有完成,给我留下一些绘画工件(paintComponent 方法非常复杂,所以不想在这里重现)。如果我调整窗口大小,这些伪影就会消失。事实上,如果我也使用扩展 Thread 而不是 SwingWorker 的类,就会发生这种情况。这都是因为 Swing 不是线程安全的,我正在尝试从 EDT 以外的线程执行 GUI 工作。我明白那部分。

我该怎么办? “工作”大约需要 30 秒,如果不向用户显示程序正在运行的某种指示,这似乎太长了。我也曾尝试将光标更改为等待光标,但遇到了与上述相同的问题。我唯一能做的就是禁用框架并将框架的标题设置为一些文本,例如“正在工作...”

以前有人遇到过这个问题吗?

最佳答案

我认为您在 SwingWorker 线程中进行工作是正确的,但您不应该尝试在那里进行绘画。

我倾向于:

  • 让 ActionListener show() 进度条,触发 swingworker 然后退出

  • 让工作线程完成工作,并定期在进度条组件上调用 repaint()(保证线程安全)

  • 进度条有它自己的 paintComponent(它将在 EDT 上自动调用)。如有必要,这可以读取一些由工作线程更新的变量以测量进度

  • 当工作线程完成时,让它调用 invokeLater() 以在 EDT 上运行最终关闭函数,这将隐藏进度条并执行任何其他与 GUI 相关的清理/向用户等

关于来自 EDT 问题的 Java Swing 进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3472824/

相关文章:

java - 将上下文属性传递给 ServerResource

java 如何在十六进制转换中转义无法识别的字符

Angular 2 Material : can't bind to 'value' since it isn't a known property of 'md-radio-button'

java - SwingWorker, done() 在 process() 调用完成之前执行

Java SwingWorker 不能在 main 方法中工作?

java - 私有(private)静态最终字段

java - 如何使用 Google App Engine 制作客户端/服务器游戏

javascript - 将选定的单选按钮设为粗体

javascript - Angular 1 - 切换单选按钮

java - JTable 在自动刷新方案上插入数据