正如大多数 Java 程序员所知,对 Swing GUI 的更新应该只在 AWT 事件调度线程上完成,建议长时间运行的进程在“工作”线程上执行,更新发送到事件调度线程使用SwingUtilities.invokeAndWait()
或 SwingUtilities.invokeLater()
。
当长时间运行的进程完成时,您如何阻止用户继续使用应用程序?您是否将控件灰显,然后让工作线程使用上面提到的 SwingUtilities
调用重新启用它们?
是否有更好的替代模式?
最佳答案
我会考虑 3 种解决方案:
- 禁用面板的组件:这通常是我所做的。不幸的是,Swing 没有提供一种简单的方法来禁用面板及其所有子面板,但是很容易进行递归(参见 this other SO answer)。另一个问题是一些 Swing 组件在启用和禁用时看起来是一样的(例如 JList)
- 使用 CardLayout 隐藏面板:在使用
CardLayout
的面板中,添加 2 个组件。第一个是托管要停用的组件的面板,第二个是显示“正在加载”或“请稍候”消息的面板。Gridbaglayout
中的一个简单的JLabel
就可以达到目的。然后,您只需要从一个切换到另一个。我将这种技术用于要显示计算/请求结果的地方。 - 将某种组件放在使用鼠标事件的面板顶部:您可以使用
LayeredPane
自己完成,也可以使用专用实用程序。 JXLayer可以做到这一点(我读到 JXLayer 将包含在 Java 7 中,因此这可能成为解决此类问题的“标准”解决方案)。
关于java - 在工作线程中阻塞 Java Swing 用户的模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5418739/