Java 如何为我的Tic-Tac-Toe GUI游戏创建一个正确的重启按钮?

Java 如何为我的Tic-Tac-Toe GUI游戏创建一个正确的重启按钮?,java,swing,Java,Swing,我目前有一个重新启动按钮,只有在第一场比赛结束后才能正确重新启动。在第二场游戏结束后,点击重启按钮可以清除棋盘,但当用户去画“O”或“X”时,它们不会被画到棋盘上。我真的想要一个功能齐全的重启按钮,但我不确定如何创建它 // JFrame for klTicTacToe board. public class GameClass extends JFrame { // Indicate whose turn it is private char whoseTurn = 'X'; // Cell

我目前有一个重新启动按钮,只有在第一场比赛结束后才能正确重新启动。在第二场游戏结束后,点击重启按钮可以清除棋盘,但当用户去画“O”或“X”时,它们不会被画到棋盘上。我真的想要一个功能齐全的重启按钮,但我不确定如何创建它

// JFrame for klTicTacToe board.
public class GameClass extends JFrame {
// Indicate whose turn it is
private char whoseTurn = 'X';

// Cell grid 9 cells
private Cell[][] cells = new Cell[3][3];

// status label
JLabel introLabel = new JLabel("Welcome to Tic Tac Toe! X Goes First");
// restart button
JButton restart = new JButton("Restart");

// Game constructor
public GameClass() {

    // Panel to hold cells
    JPanel panel = new JPanel(new GridLayout(3, 3, 0, 0));
    for (int i = 0; i < 3; i++)
        for (int f = 0; f < 3; f++)
            panel.add(cells[i][f] = new Cell());

    panel.setBorder(new LineBorder(Color.BLACK, 5));
    introLabel.setBorder(new LineBorder(Color.BLACK, 2));
    introLabel.setFont(new Font("Times New Roman", Font.PLAIN, 20));
    introLabel.setForeground(Color.DARK_GRAY);

    restart.setBackground(Color.GREEN);
    // Restart button action listener
    restart.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {

            if (e.getSource() == restart) {

                panel.removeAll();
                // re establishes cell layout
                // Panel to hold cells
                JPanel panel = new JPanel(new GridLayout(3, 3, 0, 0));
                for (int i = 0; i < 3; i++)
                    for (int f = 0; f < 3; f++)
                        panel.add(cells[i][f] = new Cell());

                panel.setBorder(new LineBorder(Color.BLACK, 5));
                introLabel.setBorder(new LineBorder(Color.BLACK, 2));
                introLabel.setFont(new Font("Times New Roman", Font.PLAIN, 20));
                introLabel.setForeground(Color.DARK_GRAY);

                add(panel, BorderLayout.CENTER);
                add(introLabel, BorderLayout.NORTH);
                add(restart, BorderLayout.SOUTH);

                introLabel.setText("New Game! X goes First");

            }
        }
    });

    add(panel, BorderLayout.CENTER);
    add(introLabel, BorderLayout.NORTH);
    add(restart, BorderLayout.SOUTH);
}

// Determines if True, if game board is full. Otherwise, false.
public boolean isFull() {
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            if (cells[i][j].getToken() == ' ')
                return false;
    return true;
}

// Determines if a given token has won.

// Token to test for winning True, if the token has won. Otherwise, false.

public boolean isWon(char gameToken) {
    // check rows
    for (int i = 0; i < 3; i++)
        if ((cells[i][0].getToken() == gameToken) && (cells[i][1].getToken() == gameToken)
                && (cells[i][2].getToken() == gameToken)) {
            return true;
        }

    // check columns
    for (int j = 0; j < 3; j++)
        if ((cells[0][j].getToken() == gameToken) && (cells[1][j].getToken() == gameToken)
                && (cells[2][j].getToken() == gameToken)) {
            return true;
        }
    // check diagonal
    if ((cells[0][0].getToken() == gameToken) && (cells[1][1].getToken() == gameToken)
            && (cells[2][2].getToken() == gameToken)) {
        return true;
    }

    if ((cells[0][2].getToken() == gameToken) && (cells[1][1].getToken() == gameToken)
            && (cells[2][0].getToken() == gameToken)) {
        return true;
    }

    return false;
}

}您正在运行时删除和添加组件。你打电话到哪里?请尝试以下方法:

        if (e.getSource() == restart) {

            panel.removeAll();
            // re establishes cell layout
            // Panel to hold cells
            JPanel panel = new JPanel(new GridLayout(3, 3, 0, 0));
            for (int i = 0; i < 3; i++)
                for (int f = 0; f < 3; f++)
                    panel.add(cells[i][f] = new Cell());

            panel.setBorder(new LineBorder(Color.BLACK, 5));
            introLabel.setBorder(new LineBorder(Color.BLACK, 2));
            introLabel.setFont(new Font("Times New Roman", Font.PLAIN, 20));
            introLabel.setForeground(Color.DARK_GRAY);

            add(panel, BorderLayout.CENTER);
            add(introLabel, BorderLayout.NORTH);
            add(restart, BorderLayout.SOUTH);

            introLabel.setText("New Game! X goes First");
            revalidate();  // <-- add this
        }
if(例如getSource()==重新启动){
panel.removeAll();
//重新建立单元布局
//放置电池的面板
JPanel面板=新JPanel(新网格布局(3,3,0,0));
对于(int i=0;i<3;i++)
对于(int f=0;f<3;f++)
添加(单元格[i][f]=新单元格());
面板。设置顺序(新线条边框(颜色为黑色,5));
introLabel.setboorder(新的线条边框(颜色:黑色,2));
introLabel.setFont(新字体(“Times new Roman”,Font.PLAIN,20));
introLabel.setForeground(颜色:深灰色);
添加(面板、边框布局、中心);
添加(introLabel,BorderLayout.NORTH);
添加(重新启动,BorderLayout.SOUTH);
introLabel.setText(“新游戏!X先走”);

重新验证();//尝试重新启动操作仅重置电路板上的9个单元,还重置标签。
如果您有任何其他“状态”变量,也应重新初始化它们。

我会避免调用
panel.removeAll();

好的,所以我才想出来。通过在我的构造函数中抛出setUpBoard方法,我能够在其中抛出构建,然后从重新启动按钮中调用它。效果很好。

阅读这个问题,我想“你知道,我以前来过这里”。我的意思是,当您的游戏模型直接混合到GUI中时,就像您使用
Cell
类一样。根据我的经验,最好从游戏模型开始(所有功能,没有图形)编写一些JUnit测试来测试它,然后构建一个GUI并在1个组件中绘制整个游戏板。这样,在调试和调试GUI之前,你可以调试模型中的大部分错误。代码是否进入了PruttCe组件?你能调试吗?我会认真考虑一下。
        if (e.getSource() == restart) {

            panel.removeAll();
            // re establishes cell layout
            // Panel to hold cells
            JPanel panel = new JPanel(new GridLayout(3, 3, 0, 0));
            for (int i = 0; i < 3; i++)
                for (int f = 0; f < 3; f++)
                    panel.add(cells[i][f] = new Cell());

            panel.setBorder(new LineBorder(Color.BLACK, 5));
            introLabel.setBorder(new LineBorder(Color.BLACK, 2));
            introLabel.setFont(new Font("Times New Roman", Font.PLAIN, 20));
            introLabel.setForeground(Color.DARK_GRAY);

            add(panel, BorderLayout.CENTER);
            add(introLabel, BorderLayout.NORTH);
            add(restart, BorderLayout.SOUTH);

            introLabel.setText("New Game! X goes First");
            revalidate();  // <-- add this
        }