MVC很多视图和一个控制器

在我的应用程序中有许多视图(子组件)和只有一个控制器。 在一个视图中选择一些选项可以更改另一个视图中的组件布局和数量。 控制器初始化视图,进而创建所有子组件。

在这样的应用程序中,控制器是否需要引用所有子组件? 如在一个视图中的侦听器中调用控制器来执行操作,然后需要更新另一个视图。 我觉得控制器不应该引用所有的视图,但不知道在哪里形成。 Head第一个设计模式书中的例子只有一个视图,所以我被卡住了。

++++++++++++++++++++++++

更多详情。 我正在写的游戏是一个跳棋(草稿)游戏。 在一种情况下,当计算机对抗自身时,用户必须在游戏开始之前选择一些选项。 一个这样的选择是在游戏期间的某些时段选择游戏策略。 例如当它在板上有12到8块时它会攻击更多,在板上8到4块它将更具防御性。

目前游戏GUI的结构方式是,有一个整体的JPanel(RightContainerFrame),其中包含其他JPanel; 然后有一个JPanel(StartGamePanel),用户可以在其中配置游戏。 还有一个包含选项卡的JTabbedPane(jTabbedPane1)。 当用户在JComboBox中选择某个选项时,当前在StartGamePanel中,需要在jTabbedPane1中添加或删除选项卡。

我目前实现这一目标的方法是在StartGamePanel中

RightContainerFrame.getInstance().generateAndDisplayPlayerTwoRangeTabs(numberOfRangeTabsNeeded);

现在我知道这是完全错误的,因为我有一个视图,StartGamePanel通过调用另一个容器视图RightContainerFrame中的方法直接更改另一个视图JTabbedPane。

我对如何构建这个问题的任何建议持开放态度。

首先,我可以将jComboBox1ActionPerformed方法移动到控制器。 这可以更新jTabbedPane1的模型。 或者它可以直接在jTabbedPane1中调用方法来显示所需的选项卡数量。

Swing不是真正的MVC架构:它是一个模型/(视图+控制器) 架构 。 每个JComponent都是视图和控制器。

您需要定义与组件上的某个事件关联的回调方法(也称为事件侦听器)。 对于不同的JComponents,不同类型的事件有不同类型的事件侦听器。

这是一个示例,其中事件侦听器在按钮上注册,以便在单击它时,它会更改另一个组件(myJLabel)中的文本:

 jButton1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent event) { myJLabel1.setText("You just clicked a button."); } } // you can add other ActionListeners to the same jButton1 

您可以拥有一个处理所有事件的全局控制器,但您需要将其注册为每个组件的侦听器。 当全局控制器收到event ,它可以查询它以找出它来自哪个按钮并相应地更改其他JComponent。 所以,是的,你的全局控制器需要引用所有JComponents,除了作为监听器注册到它们之外。 全局控制器不仅需要实现ActionListener,如上所述来获取鼠标单击,还需要实现处理来自其他组件的所有其他类型事件所需的所有其他类型的EventListener。

拥有一个全局控制器可能不是一个好主意,因为它可能最终成为一个非常大的类。 让每个JComponent注册一个(或多个)直接改变其他组件的事件监听器就足够了。

编辑
我不太确定拥有一个全局控制器是一个坏主意:你最终得到了一个庞大的类,但至少所有的回调逻辑都集中在一个地方。

我还不知道的是视图如何更新其他视图。

这个简单的例子说明了观察者模式 ,它允许模型更新视图以响应控制器视图操作。 这个更详细的示例显示了听取单个模型的三个视图

老实说,我没有清楚地理解你的设计,但我在这种情况下采用的设计(假设我们正在讨论基于丰富组件的UI技术)是让View s听一个事件总线并调整他们自己的布局。在公共汽车上过境的事件。 在此上下文中,UI动作处理程序可以在总线中发布事件。 有效地将视图彼此分离以及与控制器分离。

更新:看看这里 – 谷歌的东西往往有点书呆子和过度设计的大多数中低复杂性需求,但你可以削减它以适应你的。