非阻塞的模态Swing进度对话框

16
一个傻瓜问题,但我真的无法使其工作: 我在一个Swing应用程序中拥有一些长时间运行的进程,可能需要几分钟。我希望在该过程进行时向用户显示进度对话框。我还想防止用户执行进一步的操作,例如按下按钮,而此时进程正在进行中。
如果我在EDT上执行进程,这显然会阻止最终用户在进程进行时做任何事情。但是由于EDT正在忙于处理,因此它永远不会渲染对话框内容,所以我只能得到对话框的轮廓。
但是,如果我在工作线程中执行进程,则最终用户可以单击按钮并导致EDT在同时操纵工作器也在操纵状态,从而导致不良结果。如果我将对话框设置为模态,那就不会发生这种情况,但在Swing中,“模态”也意味着“阻塞”,因此一旦调用setVisible(true),线程就会永久阻塞。
因此,我目前的“解决方案”是使用工作线程,然后生成一个专门用于吸收setVisible阻塞性质的单独线程。肯定还有更好的解决方案!
那么,我如何获得一个对话框,它可以防止用户与系统的其余部分进行交互(模态),但不会阻塞导致其可见的线程?

参见:https://dev59.com/o1HTa4cB1Zd3GeqPPjME - Zarkonnen
2个回答

15
您应该使用GlassPane来防止用户进行交互。好消息是,这对于用户而言是模态的,而不是您的程序,因此您的线程不会被阻塞。
更好的消息是,您还可以将其用于酷炫的GUI效果,例如在GUI部分繁忙时进行着色,用户无法进行交互。您还可以在GlassPane中显示繁忙的gif图像。
链接:-
  1. GlassPane的官方教程
  2. 一些有用的教程
  3. 另一个教程
  4. Oreilly's Swing Hacks非常棒。

0

你可能做错了某些事情。请参照如何使用进度条教程。如果你可以理解教程中的代码是如何工作的,那么它应该能够指导你实现所需功能。

注意,进度条通常是模态的。


教程中的代码没有生成模态进度条/对话框。在SwingWorker中运行过程时,我仍然可以操作GUI。 - Zarkonnen
@Zarkonnen,我想你指的是ProgressMonitor演示。尝试在模态对话框中使用JProgressBar。 - Andrew Thompson
已经这样做了。但是如果您运行演示,仍然可以在进度监视器显示时操作主窗口。如果我替换进度监视器,它将停止工作,因为EDT再次被卡在等待setVisible返回的状态。 - Zarkonnen

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