2015-12-07 18 views
1

我目前有一個重啓按鈕,只有在第一個遊戲結束後才能正確重啓。第二局比賽結束後再次打開重啓按鈕可清除棋盤,但當用戶畫出「O」或「X」時,它們不會被拉到棋盤上。我真的想要一個功能齊全的重啓按鈕,但我不確定如何創建它。如何爲我的Tic Tac Toe GUI遊戲製作正確的重新啓動按鈕?

// 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; 
} 

休息的代碼:

// Defines a cell in a TicTacToe game board. 
public class Cell extends JPanel 
// token of this cell 
private char token = ' '; 

    // Cell constructor 
    public Cell() { 
     setBorder(new LineBorder(Color.black, 5)); 
     addMouseListener(new MyMouseListener()); 
    } 

    // Gets the token of the cell. 
    public char getToken() { 
     return token; 
    } 

    // Sets the token of the cell. 
    // Character to use as token value. 
    public void setToken(char f) { 
     token = f; 
     repaint(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     // Draws "X" and "O" 
     if (token == 'X') { 
      Graphics2D g2 = (Graphics2D) g; 
      g.setColor(Color.BLUE); 
      g2.setStroke(new BasicStroke(5)); 
      g.drawLine(10, 10, getWidth() - 10, getHeight() - 10); 
      g.drawLine(getWidth() - 10, 10, 10, getHeight() - 10); 

     } 

     else if (token == 'O') { 
      Graphics2D g2 = (Graphics2D) g; 
      g.setColor(Color.RED); 
      g2.setStroke(new BasicStroke(5)); 
      g.drawOval(10, 10, getWidth() - 20, getHeight() - 20); 
     } 
    } 

    private class MyMouseListener extends MouseAdapter { 
     @Override 
     public void mouseClicked(MouseEvent e) { 

      // if the cell is empty and the game is not over 
      if (token == ' ' && whoseTurn != ' ') 
       setToken(whoseTurn); 

      // Check game status 
      if (isWon(whoseTurn)) { 
       introLabel.setText(whoseTurn + " has won! Game over! Press Restart to Play Again"); 
       whoseTurn = 'X'; 

      } else if (isFull()) { 
       introLabel.setText("Tie game! Game over! Press Restart to Play Again"); 
       whoseTurn = ' '; 

      } else { 
       whoseTurn = (whoseTurn == 'X') ? 'O' : 'X'; 
       introLabel.setText(whoseTurn + "'s turn."); 
      } 
     } 
    } 
} 

// Driver Class for Tic Tac Toe 
public class TicTacToeGame { 
    public void main(String[] args) { 
     JFrame ticTacToe = new GameClass(); 
     ticTacToe.setTitle("TicTacToe Game"); 
     ticTacToe.setSize(700, 700); 
     ticTacToe.setLocationRelativeTo(null); 
     ticTacToe.setVisible(true); 
     ticTacToe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
} 

}

+0

閱讀這個問題,我想「你知道,我以前來過這裏」。我的意思是當你的遊戲模型直接混合到你的GUI中時,就像你在使用'Cell'類一樣。根據我的經驗,最好從遊戲模型開始(所有的功能,都不​​是圖形),編寫一些JUnit測試來測試,然後構建一個GUI,並將整個遊戲板繪製成1個組件。通過這種方式,您可以在開始和調試GUI之前調試模型中的大部分/所有錯誤。 – ControlAltDel

+0

代碼是否進入paintComponent?你能調試嗎? –

+0

我認真考慮看看[如何使用CardLayout](http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) – MadProgrammer

回答

0

好吧,所以我只是想通了。通過在我的構造函數中拋出一個setUpBoard方法,我能夠將構建內置到其中,然後在重啓按鈕中調用它。偉大的作品

1

您要刪除和運行過程中添加成分。你打給revalidate()的電話在哪裏?請嘗試以下操作:

 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 
     } 
0

嘗試重新啓動操作即可重置電路板上的9個單元格,並重置標籤。
如果您有任何其他「狀態」變量 - 它們也應該重新初始化。
我會避免打電話panel.removeAll();