【问题标题】:MVC Java: How does a Controller set listeners to the children classes of a ViewMVC Java:控制器如何将侦听器设置为视图的子类
【发布时间】:2013-11-30 10:17:12
【问题描述】:

我有一个控制器和一个带有许多子视图的视图,其中有孩子的孩子。 示例:JPanels 中的 JPanel 具有用于控制器传递给模型的按钮和字段。

我目前的做法是在具有动作侦听器的视图中实例化“控制器”并访问我的单例模型。这行得通 - 但它绝对不是 MVC。

所以问题是——我该怎么做?

是从控制器菊花链的唯一方法: mainview.getSubView().getSubView().getSubView().setActionListener(new AL()); 和: mainview.getSubView().getSubView().getSubView().getSomeTextFieldText();

这似乎极其不切实际[而且我看不到这种方法的好处]

任何提示或指导都会有所帮助。我没有看到任何教程解释了带有子视图的 MVC。

附带说明 - 我知道我应该让视图和模型使用 observable/observer - 但即使使用这些,我在设置动作侦听器方面也有问题。

【问题讨论】:

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


    【解决方案1】:

    我认为您在概念上将“视图”与单个 GUI 组件绑定是错误的。在 MVC 模型中确实没有“子视图”这样的概念。

    如果您有一个框架,例如,具有许多面板和子面板以及按钮等子组件,那么 整个事物 就是 MVC 中的视图/控制器接口。您的顶级框架(或一些封装类,也许您的 GUI 有很多框架,没关系)将提供到控制器(通过,比如说,事件)和视图(通过,比如说,监听器)的接口。您的 UI 的确切排列方式在其背后抽象。把你的整个 UI 想象成一个黑盒子。如何从内部组件分派/提供事件是 UI 实现的一部分,这很可能涉及事件链和委托等——但这不是视图/控制器所关心的。

    所以你最终会得到类似(概念示例):

    Model m = new Model();
    View v = new View(m);
    Controller c = new Controller(m);
    MyFrame gui = new MyFrame(v, c);
    

    然后:

    public MyFrame (View v, Controller c) {
    
       // register listeners to view, e.g.
       v.addChangeListener(this /* or some other ui component */);
    
       // send events to controller, e.g.
       addActionListener(c /* or some interface that c provides */).
    
       // or even:
       deleteButton.addActionListener(new ActionListener(){
           @Override public void actionPerformed (ActionEvent e) {
               c.doDelete();
           }
       });   
    
    }
    

    在理想情况下,您可以完全重新设计 GUI 的层次结构,拥有完全不同的组件树和组织,并且如果通过 GUI 传达的信息保持不变,视图和控制器也保持不变。

    一旦你习惯了 MVC 模式,你可能会开始到处走捷径(例如,在许多情况下,视图和/或控制器只是事件的中间人,而 GUI 本身有时最终会封装整个控制器和视图概念,只剩下一个 GUI、一个模型和一堆事件侦听器——Swing 事件架构本身就是相当 MVC),并且边界可能会变得更加模糊。没关系。但是没有理由让视图或控制器必须知道 GUI 中的结构和对象树——即使在控制器/视图只是抽象概念而不是具体类的情况下。

    有时 MVC 在使用 Swing 时会变得特别模糊,因为您最终会自然而然地以 MVC 方式做所有事情,因此当您尝试将 MVC 模式明确地强加到您的架构上时,您会想知道为什么不这样做'似乎没有太大变化(而且很难看到好处,因为你忘记了你已经在这样做了)。有时它更像是一种思考的方式,而不是一种具体的做事方式

    基本上,任何时候您的模型完全独立于您的 GUI,您正在使用 MVC 的某种化身。

    编辑:我注意到您还用“观察者模式”标记了它并简要提到了它。值得注意的是,很多时候,为基于 Swing 的 GUI 显式实现观察者模式,至少在相对简单的应用程序中,只添加了一个冗余的抽象层,因为整个 Swing API 已经从根本上基于这种设计模式(它是整个事件 -> 监听子系统)。

    我经常发现像下面这样的东西效果很好,到处使用所谓的观察者模式,其中控制器本质上只是事件侦听器的集合,例如:

     public class Controller {
         Model m;
         public ActionListener getDeleteListener () {
             return new ActionListener() {
                 @Override public void actionPerformed (ActionEvent e) {
                     m.deleteSomething();
                 }
             };
         }
     }
    

    然后 GUI 会执行以下操作:

     public class GUI extends JFrame {
         JButton deleteButton; 
         public GUI (View v, Controller c) {
             deleteButton.addActionListener(c.getDeleteListener()); 
         }
     }
    

    但是,有很多方法可以剥那只猫的皮。在那个例子中,一旦你熟悉了这个概念,如果合适的话,你可以走捷径,让 GUI 构造函数注册修改模型的侦听器。那么,如上所述,控制器就变成了一个抽象的概念。

    【讨论】:

    • 感谢您非常彻底的回复。即使仍然有点难以环绕我的头,哈哈。我想我所能做的就是练习和尝试,直到它们看起来有效并且有效。这个项目也特别难,因为它是基于现有的杂乱代码~但是你能做什么......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-02
    • 1970-01-01
    • 2015-02-09
    • 2014-10-10
    • 1970-01-01
    • 2013-11-04
    相关资源
    最近更新 更多