2

Tic Tac Toe ゲームを Java で実装していますが、プログラムを実行してボタンを押すと、クリック メソッドが原因で例外が発生します。どういうわけか、JLabel が初期化されていないようです。なんで?

package piskvorky;

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

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Piskvorky extends JFrame {
    String[] tahy = {"O", "X"};
    int tah = 0;
    JButton[][] buttons;
    JLabel stav;
    int x, y;

    public Piskvorky(int x, int y) {
        this.x = x;
        this.y = y;

        setTitle("Piskvorky");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        getContentPane().setLayout(new GridLayout(x, y+1));

        JButton[][] buttons = new JButton[x][y];

        for (int i = 0; i < x; ++i) {
            for (int j = 0; j < y; ++j) {
                buttons[i][j] = new JButton();
                buttons[i][j].setPreferredSize(new Dimension(50, 50));
                buttons[i][j].addActionListener(new MyTextListener());
                add(buttons[i][j]);
            }
        }

        JLabel stav = new JLabel();
        add(stav);

        pack();
    }

    class MyTextListener implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            JButton kliknute = (JButton) e.getSource();
            setProperties(kliknute);
        }
    };

    private void setProperties(JButton source)
    {
        source.setText(tahy[tah]);
        source.setEnabled(false);
        tah = 1-tah;
        if(tah == 0)
            stav.setText("Current player: o");
        else
            stav.setText("Current player: x");
    }

    public static void main(String[] args) {
        new Piskvorky(10, 10).setVisible(true);
    }

}
4

2 に答える 2

7

コンストラクターでstav変数を再宣言することにより、stav変数をシャドウイングしているため、stavクラスフィールドはnullです。解決策:確かに、コンストラクターでstavを初期化しますが、そこで再宣言しないでください。

編集:imxylzのコメントによると、他の変数もシャドウイングしています。可変シャドウイングについて学ぶ時間です。これに関するウィキペディアの記事またはグーグルの記事を確認してください。これは、回避する方法を学び、学ぶための重要な概念です。

于 2013-01-28T02:57:38.867 に答える
2
JLabel stav = new JLabel();

上記の線はローカル宣言として表されます。しかし、あなたは使用しています、

stav.setText("Current player: o");

setPropertiesメソッドで。だからあなたはを取得していNPEます。そこでreclrationを削除しstav、ローカル変数ではなくインスタンス変数として使用します。のローカル宣言を削除した後は、正常に機能しますstav

于 2013-01-28T03:41:13.567 に答える