Swing:JDialog如何与JFrame进行通信

6
我正在构建我的第一个Swing应用程序,试图弄清楚当用户选择JMenuItem时如何更新JFrame中主客户端区域的组件,该JDialog仅在这种情况下调用。以下是我想出的设计,但不确定它是否:(1)非常糟糕,(2)不是标准(因此最好)的方法,或者(3)我完全错了。非常感谢您的任何建议。
基本上,用户选择JMenuItem,然后启动一个JDialog。用户与对话框中的组件交互,然后单击“完成”。如果一切都有效,则JDialog关闭,我希望父窗口(JFrame)的状态更新(并最终扩展到其组件)。
我的设计:
有一个AppStateController,它是JFrame子类(我的应用程序)的成员。然后创建一个AppStateChangeListener和AppStateChange EventObject子类,以便每当对话框验证并关闭时,它就会触发一个AppStateChange事件。由于父JFrame是唯一注册的监听器,所以可以定义一个处理程序将事件传递给它。我会确保AppStateChangeEvent具有足够的元数据来描述所有可能的更改。
理论上,我喜欢这种方法:它应该是干净的,没有“意大利面”类型的多个控件调用,无论何时不同的事件触发。但是,我担心这可能过度设计。
在这里有什么最佳实践吗?我不是一个GUI的人!

好问题,我曾经也遇到过这种情况,后来发现我花费了太多时间。关键是,你真的打算/需要重复使用那个对话框吗? - fredcrs
1个回答

5

Java有几种实现观察者模式的方法,这里讨论了其中几种方法

EventListenerList规定的机制可能是最通用的,因为它允许您定义自己的事件和监听器类型,并且对Swing程序员来说很熟悉。不要使JFrame成为监听器,让最高级别的JComponent这样做。每个JComponent实例都有一个适当的protected成员listenerList

绑定属性也是一个很好的选择,如此处所示。

如果您选择Observable,您需要使用委托。

附录:具体例子,使用EventListenerList方案来管理图表、数据集和系列事件。相比之下,使用bean属性来通知监听器小部件选择。


太棒了,@trashgod的回答非常好!谢谢!不过,这个EventListenerList让我感到困惑:如果我将我的最高级JComponent设置为唯一的监听器,并且该JComponent属于我的JFrame,那么我的对话框如何获取EventListenerList以便它们可以调用fireFooXXX(...)方法?我应该缓存这个列表,还是只需调用myHighJComponent.fireFooXXX(...)即可? - IAmYourFaja
将监听器添加到最高级别的JComponent符合您提出的设计,但是应用程序中的_任何_JComponent都可以监听AppStateChangeEvent。每个这样的组件都必须实现相关的fireAppStateChange()方法,并将组件传递给对话框。 AbstractButton中的fireActionPerformed()是一个很好的例子。 - trashgod

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