【问题标题】:How to organize the controller of a MVC-based program with multiple screens/panels?如何组织具有多个屏幕/面板的基于 MVC 的程序的控制器?
【发布时间】:2009-01-06 14:37:16
【问题描述】:

我目前正在从事一个用 Java 编写的业余项目,其中包含大约两个不同的 JFrame,每个 JFrame 大约有 3-4 个 JPanel。我面临的问题是我不太确定如何处理与控制器和不同视图类的交互。

例如,我有一篇 Sun 在 Java App. design with MVC 上的文章,其中列出了让模型和视图之间的所有通信都通过控制器作为最现代的选项,这是我被教导的一种策略很好,应该做得很好。但是,它并没有深入解释如何处理所有元素和不同面板所涉及的所有 ActionListener。

到目前为止,我学到的“方法”是使用一个控制器并通过 getter 将 ActionListener 设置为各种对象并跟踪活动面板。我很棒的 Java 书给出的替代方案是只为每个视图类坚持内部类。任何一种方法似乎都会导致非常讨厌的代码,而我更喜欢一个或多个控制器,尽可能减少臃肿。

我的问题当然是;如何在保持控制器可用的同时尽可能简洁高效地分配 ActionListener?

【问题讨论】:

    标签: java model-view-controller generics


    【解决方案1】:

    尽管 Markus 的解决方案仍然是我迄今为止见过的最简洁的解决方案,但我还是做了一些细微的改动,希望在原作者眼中也能有所改进;)。

    如果您根据事件添加/删除列表中的项目,则可能会同时更改列表;该事件已处理,但如果在捕获事件之后还有更多项目,则循环将继续。

    因此需要使用稍微不同的方法。我决定使用 ListIterator.add() 方法,因为该方法支持在遍历列表项时对列表进行修改。可能有更优雅的解决方案可用,但这个解决方案做得相当不错。

    如果对他人有帮助;修改后的代码类似如下:

    ListIterator<ActionListener> iterator = mActionListeners.listIterator();
    
    public void actionPerformed(ActionEvent e)
    {
        iterator = mActionListeners.listIterator();
        while (iterator.hasNext()) 
        {
            ActionListener actionListener = (ActionListener)iterator.next();
            actionListener.actionPerformed(e);
        }
    }
    
    public void addListener(ActionListener listener)
    {
        iterator.add(listener);
    }
    
    public void removeListener(ActionListener listener)
    {
        iterator.remove(listener);
    }
    

    如果有更好的解决方案或改进,我也会很高兴听到这些。

    【讨论】:

      【解决方案2】:

      控制器可以实现 ActionListener 并包含一个 ActionListener 列表。

      您必须添加到 3-4 顶部面板动作侦听器的控制器。 现在您可以将任何您想要的 ActionListener 添加到控制器操作侦听器列表中。

      public void addListener(ActionListener listener)
      {
         mActionListeners.add(listener);
      }
      
      public void removeListener(ActionListener listener)
      {
         mActionListeners.remove(listener);
      }
      

      当控制器动作监听器被调用时,你必须调用所有在控制器列表中的动作监听器。

      public void actionPerformed(ActionEvent e) {
         List listeners = mActionListeners; // Edit 20090903
         for (Iterator iterator = listeners .iterator(); iterator.hasNext();) {
          ActionListener actionListener = (ActionListener)iterator.next();
          actionListener.actionPerformed(e);
         }
      }
      

      【讨论】:

      • 非常感谢,这可能是迄今为止我见过的最优雅的解决方案,并且可能会。非常感谢。
      • 别提了。当您找到更好的解决方案时,请在此处发布并告诉我。
      • 我不确定当它是后续答案而不是评论时您是否也会收到通知,所以我们开始吧;)
      猜你喜欢
      • 2013-05-31
      • 2012-10-21
      • 2016-02-11
      • 2016-06-21
      • 2017-10-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多