2010-08-12 26 views
6

这是针对挥杆专家的。我在这个问题上花费了相当多的时间,所以这需要我用几行来解释这个问题。来自EDT问题的Java swing进度条

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

我想在用户选择其中一个单选按钮时显示一个进度条。 但是,当选择单选按钮时,在单选按钮的动作发生时,进度条从不出现。我试过jdialog类型的进度条,玻璃窗格等等,直到“工作”完成才显示出来。这似乎是因为Swing没有完成绘制单选按钮,直到相应动作中的“工作”完成。而且由于EDT一次只能处理一件事情,因此不会显示进度条对话框(或玻璃窗格)。

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

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

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

回答

4

我认为你是正确的做SwingWorker线程的工作,但你不应该试图在那里做你的画。

我会倾向于:

  • 拥有的ActionListener秀()的进度条,掀起那么SwingWorker的退出

  • 有工作线程做的工作,并定期调用在进度条组件上重画()(这保证是线程安全的)

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

  • 当工作线程完成时,让它调用invokeLater()在EDT上运行最终关闭函数,这将隐藏进度条和做任何其他GUI相关的清理/显示完成消息给用户等

+0

如何确保EDT在SwingWorker线程的工作完成之前不会执行任何其他绘画? 可以在背景中完成的工作必须在我的框架再次绘制之前完成。 – Anu 2010-08-13 19:41:57

+0

谢谢!我得到了这个工作。 – Anu 2010-08-13 20:31:29

4

当你将作品从EDT搬到摆动工作人员(这是正确的事情)时,听起来像工作和绘画都被搬到了摆动工作人员身上。这幅画仍然应该在美国东部时间发生。您可以通过使用SwingUtilities.invokeLater来调用来自后台线程的重绘或使用SwingWorker.publish(V...)来实现此目的,该工具将从工作线程接收通知,并通过SwingWorker.process(V...)模板方法(您可以覆盖)在EDT上使其可用。您的覆盖可以通过重新绘制屏幕的一部分,更新进度或根据需要采取其他适当的操作来处理中间通知。在这里完成的任何UI更改都将可见,而无需等待剩下的工作完成。

+0

谢谢,我Mikera的解决方案的工作,但你对已经移动了画到EDT评论也刺激了我改变了事情! – Anu 2010-08-13 20:32:16

+0

我认为在工作线程上使用SwingWorker.publish()是一种可行的方法。 – keuleJ 2010-10-18 19:19:03