用于在工作线程中阻止Java Swing用户的模式

Ral*_*lph 6 java concurrency swing

正如大多数Java程序员所知,Swing GUI的更新只应在AWT事件调度线程上完成,建议在"工作"线程上执行长时间运行的进程,并使用SwingUtilities.invokeAndWait()或将更新发送到事件调度线程SwingUtilities.invokeLater().

在长时间运行的过程完成后,如何阻止用户继续执行应用程序?你是否使控件灰显,然后让工作线程使用SwingUtilities上面提到的调用重新启用它们?

有更好的替代模式吗?

bar*_*jak 4

我会考虑3种解决方案:

  • 禁用面板的组件:这通常是我所做的。不幸的是,Swing 没有提供一种简单的方法来禁用面板及其所有子面板,但很容易进行递归(请参阅其他 SO 答案)。另一个问题是某些 Swing 组件在启用和禁用时看起来相同(例如 JList)
  • 隐藏带有 CardLayout 的面板:在带有 的面板中CardLayout,添加 2 个组件。第一个是托管要停用的组件的面板,第二个是显示“正在加载”或“请等待”消息的面板。一个简单的JLabelaGridbaglayout就可以了。然后,您只需从一种切换到另一种即可。我将这种技术用于要显示计算/请求结果的地方。
  • 将某种组件放在消耗鼠标事件的面板顶部:您可以使用 自己完成LayeredPane,也可以使用专用实用程序。JXLayer可以做到这一点(我读到 JXLayer 将包含在 Java 7 中,因此这可能成为此类问题的“标准”解决方案)。