Java使用MVC单击计数器

时间:2012-10-08 16:30:44

标签: java model-view-controller

我正在尝试编写一个非常简单的Java示例来学习MVC。它是一个JButton,当点击时会增加一个计数器并显示到目前为止的点击次数。

我将模型,视图和控制器分成不同的类,并认为我在正确的路径上,但是当我点击按钮时,显示计数器的JLabel继续保持为0。

有人可以快速查看为什么显示点击次数的JLabel始终保持为0?

由于

View

package mvc;  
import javax.swing.JButton;  
import javax.swing.JLabel;  
import javax.swing.JTextArea;  
import javax.swing.SwingUtilities;  
import javax.swing.WindowConstants;  


public class View extends javax.swing.JFrame {  
    private JButton jButton1;  
    private JLabel jLabel1;  
    private Controller c;   
    private Model m;  

    /**
    * Auto-generated main method to display this JFrame
    */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Controller c = new Controller();    

                Model m = new Model();

                View inst = new View(c,m);
                inst.setLocationRelativeTo(null);
                inst.setVisible(true);
            }
        });
    }

    public View(Controller c, Model m) {
        super();
        this.c = c;     
        this.m = m;
        initGUI();
    }

    private void initGUI() {
        try {
            setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            getContentPane().setLayout(null);
            {
                jButton1 = new JButton();
                getContentPane().add(jButton1, "Center");
                jButton1.setText("Click");
                jButton1.setBounds(314, 180, 101, 34);
                jButton1.addActionListener(c);
            }
            {
                jLabel1 = new JLabel();
                getContentPane().add(getJLabel1());
                jLabel1.setText("Click Count = " + c.getClickCount());
                jLabel1.setBounds(439, 183, 91, 27);

            }
            pack();
            this.setSize(818, 414);
        } catch (Exception e) {
            //add your error handling code here
            e.printStackTrace();
        }
    }

    public JLabel getJLabel1() {
        return jLabel1;
    }   
}

End View

Controller class

package mvc;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Controller implements ActionListener 
{   
    Model m;
    View v;

    public Controller()
    {
        m = new Model();        
        v = new View(this, m);
    }

    @Override
    public void actionPerformed(ActionEvent arg0) 
    {
        if (arg0.getSource() == "Click")
        {
            m.addClick();
            v.getJLabel1().setText("Click count = " + getClickCount());
        }

    }

    public int getClickCount()
    {
        return m.getClicks();
    }
}

End Controller class

Model class

package mvc;

public class Model 
{
    private int clicks;

    public Model()
    {
        clicks = 0;
    }

    public void addClick()
    {
        clicks++;
    }

    public int getClicks()
    {
        return clicks;
    }
}

End Model class

5 个答案:

答案 0 :(得分:0)

有几个问题:

  • 视图显示的实际数据通常来自模型,而不是来自控制器。

    所以你的代码在视图中 jLabel1.setText("Click Count = " + c.getClickCount());
    应改为
    jLabel1.setText("Click Count = " + m.getClickCount());

  • 在Controller内部,您可以创建模式和视图的新实例,并在main()方法内再次创建控制器和视图的新实例。所以基本上Controller类正在处理不同的视图和模型对象。

总的来说,它不是一个石头标准:

  • View有一个模型,它是指控制器
  • 该模型是独立的,并且doesent指的是视图或控制器
  • 控制器同时具有视图和模型。

答案 1 :(得分:0)

if (arg0.getSource() == "Click")

==不适用于字符串(或对象)相等比较。 equals方法是您应该使用的方法。

此外,我认为您对public String getActionCommand()方法感兴趣而不是public Object getSource()

一点点测试

JButton btn = new JButton();
btn.setText("Click");       
btn.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(e.getSource());
        System.out.println(e.getActionCommand());
    }
});
btn.doClick();

和输出

javax.swing.JButton[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@1f5b0afd,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=2,right=14],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Click,defaultCapable=true]
Click

应说明原因。

<强>更新

尝试

if (arg0.getActionCommand().equals("Click"))

答案 2 :(得分:0)

我明白为什么现在。您创建了两个不同的Model对象。 一个在控制器中,一个在Main()中 - 哪一个是它?

另一个建议..创建一个MainController类。 这应该有你的Main方法。 您的main方法创建另一个Controller,负责创建您的View和Model。 使用此Controller作为桥梁。

答案 3 :(得分:0)

由于您正在更新View的错误实例,因此该数字始终保持为零。在Controller类中,您将创建另一个未显示的实例。

v = new View(this, m);

您可以通过添加setter传递主实例:

class Controller implements ActionListener {
    Model m;
    View v;

    public Controller() {
        m = new Model();
    }

    public void setView(View v) {
        this.v = v;
    }
    ...

ActionEvent.getSource()返回组件引用,但jButton1未公开显示。要修复此问题,可以为按钮添加getter或使用action命令:

if (arg0.getActionCommand().equals("Click")) {

答案 4 :(得分:0)

您可以尝试在视图类上设置按钮的访问权限:

public JButton getButton(){

返回jbutton1;

}

public void setButton(JButton button){

this.jbutton1 = button;

}

并在您的控制器类中访问您的按钮,如下所示:

if(arg0.getSource()== v.getButton()){

...

}

我总是喜欢这样,我从未犯过任何错误......