在模型 - 视图 - 控制器中,为什么更改模型,不会触发视图中的更改?

时间:2011-12-06 05:13:10

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

我目前正在开发自己的扫雷艇。 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>"));
}           

3 个答案:

答案 0 :(得分:3)

  

每当模型发生更改时,控制器将在视图中触发该更改。

Model–View–Controller pattern中,当控制器更新模型时,模型将通知视图,通常使用observer pattern视图然后自行更新。 视图可以询问模型并处理任何结果更新。有一个更详细的答案和示例here

答案 1 :(得分:1)

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

虽然在现有标签上设置文字而不是整个新标签更有意义。

答案 2 :(得分:1)

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

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

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

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

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