5

MVC を学習するために、非常に単純な Java の例を作成しようとしています。クリックするとカウンターがインクリメントされ、それまでのクリック数が表示される 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
4

5 に答える 5

0

の間違ったインスタンスを更新しているため、数値は常にゼロのままですView。クラスで、Controller表示されない別のインスタンスを作成します。

v = new View(this, m);

代わりに、セッターを追加してメインインスタンスを渡すことができます。

class Controller implements ActionListener {
    Model m;
    View v;

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

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

ActionEvent.getSource()コンポーネント参照を返しますが、jButton1公開されていません。修正するには、ボタンのゲッターを追加するか、アクションコマンドを使用します。

if (arg0.getActionCommand().equals("Click")) {
于 2012-10-08T17:29:04.260 に答える
0

いくつかの問題があります:

  • ビューが表示する実際のデータは、通常、コントローラーではなくモデルから取得されます。

    したがって、ビュー内のコードは次のよう
    jLabel1.setText("Click Count = " + c.getClickCount());
    に変更する必要があります
    jLabel1.setText("Click Count = " + m.getClickCount());

  • コントローラー内でモードとビューの新しいインスタンスを作成し、main() メソッド内でコントローラーとビューの新しいインスタンスを再度作成します。したがって、基本的に Controller クラスは別のビューとモデル オブジェクトで動作します。

一般的には、石のように刻まれた標準ではありません。

  • ビューにはモデルがあり、コントローラーを参照していません
  • モデルは独立しており、ビューまたはコントローラーを参照していません
  • コントローラーにはビューとモデルの両方があります。
于 2012-10-08T16:38:34.567 に答える
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[上=2,左=14,下=2,右=14],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true ,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Click,defaultCapable=true]
クリック

理由を説明する必要があります。

アップデート

試す

if (arg0.getActionCommand().equals("Click"))
于 2012-10-08T16:38:43.740 に答える
0

理由がわかりました。2 つの異なるモデル オブジェクトが作成されました。コントローラーに 1 つ、Main() に 1 つ - どちらですか?

別のアドバイス.. MainController クラスを作成します。これには Main メソッドが必要です。メイン メソッドは、ビューとモデルの作成を担当する別のコントローラーを作成します。このコントローラーをブリッジとして使用します。

于 2012-10-08T16:39:20.150 に答える
0

ビュークラスのボタンへのアクセサを作成してみてください:

public JButton getButton(){

jbutton1 を返します。

}

public void setButton(JButton ボタン){

this.jbutton1 = ボタン;

}

コントローラークラスでは、次のようにボタンにアクセスします。

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

...

}

私はいつもそれが好きで、エラーは一度もありませんでした...

于 2013-01-04T15:14:43.263 に答える