Swing MVC - 事件传播和数据共享

时间:2013-03-08 09:54:16

标签: java swing model-view-controller observer-pattern mediator

我正在尝试在swing应用程序中应用MVC模式。但是,鉴于您具有嵌套的面板层次结构,我面临两个主要问题,例如家长 - >孩子 - >大孩子 - >大孙子。

问题1:如果有这样的层次结构,如何在控制器和视图之间传输数据?如果我将数据从父母传递给孩子,那么就会有很多重复,如果我改变一个孩子,所有父母都需要改变。我不希望视图直接从数据库访问数据,我希望数据只通过控制器传输到视图。

问题2:如何在这种层次结构中将事件从视图传播到控制器? 我正在考虑使用PropertyChangeListener。如果控制器必须采取任何操作,则将查看firePropertyChange事件。控制器将监听这些事件并执行某些操作。但是,如果我为层次结构执行此操作,则会出现代码重复。

我有三个可能有用的想法:

  1. 为每个面板使用控制器,但这样我最终会得到很多控制器。
  2. 使用Mediator设计模式,提供视图和控制器之间的通信。
  3. 使用Central Reciever&通知程序将从视图中侦听所有属性更改事件,并将通知感兴趣的控制器。但这只会解决我的第二个问题:
  4. 请参考下图了解第3个想法的图片。如果是第二个,调解员将进入中心。

    如果有人以更好的方式实施此类问题,请评估并告诉我。

    enter image description here

3 个答案:

答案 0 :(得分:1)

我对你的问题1有一个建议:

您可以拥有一个包含另一个View Model属性的ViewModel。在您的控制器方法上,您只需要接收父ViewModel,因为模型绑定器将为您绑定所有属性。

public class GrandChildViewModel{
    public Int32 SelectedDropDownItem { get; set; }
    public List<Foo> ListOfFoo { get; set; }
}

public class ChildViewModel{
    public String Name { get; set; }
    public Int32 Age { get; set; }
}
public class FatherViewModel{
    public ChildViewModel Child { get; set; }
    public GrandChildViewModel GrandChild { get; set; }
}

这是层次结构的一个示例。您的视图将仅引用FatherViewModel。并且您的控制器也将接收FatherViewModel。 如果您创建HTML,则modelBinder将自动完成其工作:

@Html.TextBoxFor(m => m.Child.Name)

它将呈现输入:

<input type="text" id="Child_Name" name="Child_Name" />

答案 1 :(得分:1)

  

问题1:如何在控制器和视图之间传输数据   有这样的等级?如果我将数据从父母传递给孩子那么   会有很多重复,如果我改变了一个孩子   父母需要改变。我不希望视图直接访问   来自db和我的数据希望数据通过传输到视图   仅控制器。

如何通过使用相关控制器注册视图来忽略层次结构并采用更线性的方法?数据可以通过模型获得,其中的变更将通过ObserverListener模式触发。

通过这种方式,您不会发生任何重复。一切都集中在一个模型或一系列模型中。在用户操作或外部事件发生后,控制器或控制器可以在已注册视图列表上运行通知。

此外,视图绝对不应该像您所说的那样访问数据源。这里至少应该有一层抽象。如果您的控制器使用中介模式,我会通过将请求转发到额外数据层中的接口来处理此问题。

进一步思考,我认为通过视图完成注册是不是一个好主意。所以我会把它分开。手动初始化视图或找到迭代所需视图的方法。也许通过一种自动执行此步骤的工厂来获取您的观点。

  

问题2:如何将事件从视图传播到控制器   层次?我正在考虑使用PropertyChangeListener。查看会   firePropertyChange事件,如果控制器必须采取任何操作。   控制器将监听这些事件并执行某些操作。但   再次,如果我为层次结构执行此操作,则会出现代码重复。

同样,您可以采用线性方法。注册视图后,Controller可以向其添加侦听器。或者您可以让视图发送一些语义样式消息(例如:doAction(“保存”)),这些消息可以通过调度机制来处理。将让您决定如何转发参数。

是否需要PropertyChangeListeners?我的意思是,你需要那种粒度吗?

  

我有三个可能有用的想法:

     

要为每个面板使用控制器,但这样我就会结束   有很多控制器。使用Mediator设计模式   提供视图和控制器之间的通信。使用中心   接收者&amp;通知器将监听所有属性更改事件   从视图中,将通知感兴趣的控制器。但是这个   只会解决我的第二个问题:

这听起来像HMVC。通过这种方法,您可以为每个子系统提供模型 - 视图 - 控制器三元组。这是一个有趣的想法,但可能会很混乱,并且不清楚层次结构应该如何解决以及如何实现协调/从属。

也许你可以为你的应用程序的每个模块/子系统设置第四个中性类,如果其中一个缺失或不正确,你可以插入一个视图,模型和控制器,抛出异常。

或者,遵循中央通知程序的概念,您可以将中央控制器作为其他特定功能控制器的路由机制或更多基本操作。如何将消息重新路由到这些消息取决于您。注意线程化,因为集中化将使这个类的设计变得必不可少。

无论你做什么,都要尽量让事情变得简单。您应该可以使用模型和控制器进行测试视图,而不必过于烦恼。

答案 2 :(得分:1)

当我最终使用 this HMVC Pattern时,我遇到了类似的问题。是的,你是正确的,因为会有很多控制器。但它确实会为您提供代码中关注点的清晰分离。您可以通过创建一些特定于应用程序的高级复合窗口小部件来限制控制器的数量。在这种情况下,层次结构最多可以限制为2或3级,并且可以将控制器链接到将事件委托给任何父/子。

从服务器加载数据后,您还可以维护会话地图以获得快速和easy access to frequently required data的一些缓解 - 但我不太喜欢它。

如果开发团队理解并正确地遵循它,该模式的效果非常好。