【问题标题】:In Model-View-Controller, Why change in model, doesn't trigger the change in view?在 Model-View-Controller 中,为什么更改模型,不会触发视图更改?
【发布时间】:2011-12-06 05:13:09
【问题描述】:

我目前正在开发自己的扫雷器。 Swing 遵循模型-视图-控制器设计模式。在MVC中,我了解到只要模型发生变化,控制器也会触发视图变化。但在这个例子中,我无法追踪如何在 setTitlesetInfo 中进行更改以反映在视图中。

在这里,当我设置对话框的标题时,实际的内容(模型)正在改变,但输出(视图)没有相应的变化。

//InfoDisplayer is inner class of class MenuActionListener
class InfoDisplayer extends JDialog { 
    JLabel info;
    BorderLayout infoBorderLayout = new BorderLayout();

    public InfoDisplayer(JFrame ownerFrame) {
        super(ownerFrame,true); 
        info = new JLabel();
        setFocusable(false);                        
        setSize(300,400);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setLayout(infoBorderLayout);
        add(info,BorderLayout.SOUTH);
        setVisible(true);
    }

    void setInfo(JLabel info) {
        this.info = info;
    }

    public void setTitle(String title) {
        super.setTitle(title);
    }                                   
}

if ((event.getActionCommand()).equals("HowToPlay")) {
    InfoDisplayer instructionsDisplay = new InfoDisplayer(gUIManagerFrame); 
    //gUIManagerFrame is an object of its outer class,MenuActionListener
    instructionsDisplay.setTitle("INSTRUCTIONS");
    instructionsDisplay.setInfo(new JLabel("<html><h1><B>INSTRUCTIONS</B></h1></html>"));
} else {// if about is clicked!!
    InfoDisplayer aboutDisplay = new InfoDisplayer(gUIManagerFrame);
    aboutDisplay.setTitle("MineSweeper v0.1");
    aboutDisplay.setInfo(new JLabel("<html><h1><B>MineSweeperv1.0</B></h1> </html>"));
}           

【问题讨论】:

    标签: java model-view-controller swing design-patterns jdialog


    【解决方案1】:

    每当 model 发生变化时,controller 都会触发 view 的变化。

    Model–View–Controller pattern中,当controller更新model时,model会通知view ,通常使用observer pattern,然后 view 会自行更新。 view 可以询问 model 并处理任何产生的更新。有更详细的答案和例子here

    【讨论】:

      【解决方案2】:

      您需要删除旧的 jlabel 并将新的 jlabel 添加到框架中。

      虽然将文本设置在现有标签上而不是全新的标签上可能更有意义。

      【讨论】:

      • 两种方法都不起作用。您将如何删除旧的 JLabel 并添加新的?第一个:“void setInfo(JLabel info){ remove(this.info); this.info.setText(info.toString()); add(this.info,BorderLayout.SOUTH); }”第二个:“void setInfo(JLabel info){ remove(this.info); this.info = info; add(info,BorderLayout.SOUTH); }"
      • +1 表示更新而不是替换;更多关于 MVC here.
      【解决方案3】:

      Swing 确实有模型和视图的一面。例如,在 JTable 中,JTable 是视图,TableModel 是模型。当您构造 JTable 时,您需要在构造期间或使用 setter 将模型传递给它。然后,JTable 将向模型添加一个侦听器,以获取有关任何模型更改的通知。您可以将此侦听器视为控制器。

      但是,这并不意味着当您使用 Swing 类的任意组合时,它们会自动神奇地获知彼此的更改。在您的情况下,标签当然不是您的对话框的“模型”,并且您的标签和对话框之间没有“控制器”之类的东西。当您进行此类更改时,您需要自己通知对话框(并且可能还将标签添加到您的对话框中)。

      哦,我建议将您的 setTitle 方法更改为

      public void setTitle( String aTitle ){
          super.setTitle( aTittle );
      }
      

      或将其完全删除。这将避免 StackOverflowException

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2012-07-17
      • 1970-01-01
      • 2018-06-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多