我在java中制作Checkers游戏,而我正试图使用GUI来实现这一目标。我得到了一个成功的构建消息,但是当我尝试运行我的程序时,它说:
线程中的异常" main"显示java.lang.NullPointerException at java.awt.Container.addImpl(Container.java:1097) 在java.awt.Container.add(Container.java:417) 在finalproject.Checkers。(Checkers.java:71) 在finalproject.Checkers.main(Checkers.java:25) Java结果:1
Checkers中的第71行:add(newGameButton);
Checkers中的第25行:Checkers content = new Checkers();
我不明白为什么main没有运行。请帮我。我还有另外两个名为" CheckerMove"和"播放"。
红色玩家== 1,黑色玩家== 2,红色王者== 3,黑色王者== 4,空白区域== 0。
package finalproject;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;
public class Checkers extends JPanel {
/**
* Main routine makes it possible to run Checkers as a stand-alone
* application. Opens a window showing a Checkers panel; the program
* ends when the user closes the window.
*/
public static void main(String[] args) {
System.out.println("Hello");
JFrame window = new JFrame("Checkers");
Checkers content = new Checkers();
window.setContentPane(content);
window.pack();
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
window.setLocation((screensize.width - window.getWidth()) / 2, (screensize.height - window.getHeight()) / 2);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.setVisible(true);
}
/**
* Nested applet class that can be used to run Checkers as an
* applet. Size of the applet should be 350-by-250
*/
public class Applet extends JApplet {
public void init() {
setContentPane(new Checkers());
}
}
public JButton newGameButton; // Button for starting a new game.
public JButton resignButton; // Button that a player can use to end
// the game by resigning.
public JLabel message; // Label for displaying messages to the user.
/**
* The constructor creates the Board (which in turn creates and manages
* the buttons and message label), adds all the components, and sets
* the bounds of the components. A null layout is used. (This is
* the only thing that is done in the main Checkers class.)
*/
public Checkers() {
setLayout(null); // I will do the layout myself.
setPreferredSize(new Dimension(350, 250));
setBackground(new Color(0, 150, 0)); // Dark green background.
/* Create the components and add them to the applet. */
Board board = new Board(); // Note: The constructor for the
// board also creates the buttons
// and label.
add(board);
add(newGameButton);
add(resignButton);
add(message);
/* Set the position and size of each component by calling
its setBounds() method. */
board.setBounds(20, 20, 164, 164); // Note: size MUST be 164-by-164 !
newGameButton.setBounds(210, 60, 120, 30);
resignButton.setBounds(210, 120, 120, 30);
message.setBounds(0, 200, 350, 30);
} // end constructor
} //end checkers class
class Board extends JPanel implements ActionListener, MouseListener {
public JButton newGameButton; // Button for starting a new game.
public JButton resignButton; // Button that a player can use to end
// the game by resigning.
public JLabel message; // Label for displaying messages to the user.
Play board; // The data for the checkers board is kept here.
// This board is also responsible for generating
// lists of legal moves.
boolean gameInProgress; // Is a game currently in progress?
/* The next three variables are valid only when the game is in progress. */
int currentPlayer; // Whose turn is it now? The possible values
// are 1 and Play.BLACK.
int selectedRow, selectedCol; // If the current player has selected a piece to
// move, these give the row and column
// containing that piece. If no piece is
// yet selected, then selectedRow is -1.
CheckerMove[] legalMoves; // An array containing the legal moves for the
// current player.
/**
* Constructor. Create the buttons and lable. Listens for mouse
* clicks and for clicks on the buttons. Create the board and
* start the first game.
*/
Board() {
setBackground(Color.BLACK);
addMouseListener(this);
resignButton = new JButton("Resign");
resignButton.addActionListener(this);
newGameButton = new JButton("New Game");
newGameButton.addActionListener(this);
message = new JLabel("", JLabel.CENTER);
message.setFont(new Font("Serif", Font.BOLD, 14));
message.setForeground(Color.green);
board = new Play();
doNewGame();
}
/**
* Respond to user's click on one of the two buttons.
*/
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource();
if (src == newGameButton) doNewGame();
else if (src == resignButton) doResign();
}
/**
* Start a new game
*/
void doNewGame() {
if (gameInProgress == true) {
// This should not be possible, but it doens't hurt to check.
message.setText("Finish the current game first!");
return;
}
board.createGame(); // Set up the pieces.
currentPlayer = 1; // RED moves first.
legalMoves = board.getLegalMoves(1); // Get RED's legal moves.
selectedRow = -1; // RED has not yet selected a piece to move.
message.setText("Red: Make your move.");
gameInProgress = true;
newGameButton.setEnabled(false);
resignButton.setEnabled(true);
repaint();
}
/**
* Current player resigns. Game ends. Opponent wins.
*/
void doResign() {
if (gameInProgress == false) {
message.setText("There is no game in progress!");
return;
}
if (currentPlayer == 1) gameOver("RED resigns. BLACK wins.");
else gameOver("BLACK resigns. RED wins.");
}
/**
* The game ends. The parameter, str, is displayed as a message
* to the user. The states of the buttons are adjusted so playes
* can start a new game. This method is called when the game
* ends at any point in this class.
*/
void gameOver(String str) {
message.setText(str);
newGameButton.setEnabled(true);
resignButton.setEnabled(false);
gameInProgress = false;
}
/**
* This is called by mousePressed() when a player clicks on the
* square in the specified row and col. It has already been checked
* that a game is, in fact, in progress.
*/
void doClickSquare(int row, int col) {
/* If the player clicked on one of the pieces that the player
can move, mark this row and col as selected and return. (This
might change a previous selection.) Reset the message, in
case it was previously displaying an error message. */
for (int i = 0; i < legalMoves.length; i++)
if (legalMoves[i].fromY == row && legalMoves[i].fromX == col) {
selectedRow = row;
selectedCol = col;
if (currentPlayer == 1) message.setText("RED: Make your move.");
else message.setText("BLACK: Make your move.");
repaint();
return;
}
/* If no piece has been selected to be moved, the user must first
select a piece. Show an error message and return. */
if (selectedRow < 0) {
message.setText("Click the piece you want to move.");
return;
}
/* If the user clicked on a squre where the selected piece can be
legally moved, then make the move and return. */
for (int i = 0; i < legalMoves.length; i++)
if (legalMoves[i].fromY == selectedRow && legalMoves[i].fromX == selectedCol && legalMoves[i].toY == row && legalMoves[i].toX == col) {
doMakeMove(legalMoves[i]);
return;
}
/* If we get to this point, there is a piece selected, and the square where
the user just clicked is not one where that piece can be legally moved.
Show an error message. */
message.setText("Click the square you want to move to.");
} // end doClickSquare()
/**
* This is called when the current player has chosen the specified
* move. Make the move, and then either end or continue the game
* appropriately.
*/
void doMakeMove(CheckerMove pMove) {
board.move(pMove);
/* If the move was a jump, it's possible that the player has another
jump. Check for legal jumps starting from the square that the player
just moved to. If there are any, the player must jump. The same
player continues moving.
*/
if (pMove.jumpMove()) {
//legalMoves = board.getLegalJumpsFrom(currentPlayer,pMove.toY,pMove.toX);
legalMoves = board.getLegalMoves(currentPlayer);
if (legalMoves != null) {
if (currentPlayer == 1) message.setText("RED: You must continue jumping.");
else message.setText("BLACK: You must continue jumping.");
selectedRow = pMove.toY; // Since only one piece can be moved, select it.
selectedCol = pMove.toX;
repaint();
return;
}
}
/* The current player's turn is ended, so change to the other player.
Get that player's legal moves. If the player has no legal moves,
then the game ends. */
if (currentPlayer == 1) {
currentPlayer = 2;
legalMoves = board.getLegalMoves(currentPlayer);
if (legalMoves == null) gameOver("BLACK has no moves. RED wins.");
else if (legalMoves[0].jumpMove()) message.setText("BLACK: Make your move. You must jump.");
else message.setText("BLACK: Make your move.");
} else {
currentPlayer = 1;
legalMoves = board.getLegalMoves(currentPlayer);
if (legalMoves == null) gameOver("RED has no moves. BLACK wins.");
else if (legalMoves[0].jumpMove()) message.setText("RED: Make your move. You must jump.");
else message.setText("RED: Make your move.");
}
/* Set selectedRow = -1 to record that the player has not yet selected
a piece to move. */
selectedRow = -1;
/* As a courtesy to the user, if all legal moves use the same piece, then
select that piece automatically so the use won't have to click on it
to select it. */
if (legalMoves != null) {
boolean sameStartSquare = true;
for (int i = 1; i < legalMoves.length; i++)
if (legalMoves[i].fromY != legalMoves[0].fromY || legalMoves[i].fromX != legalMoves[0].fromX) {
sameStartSquare = false;
break;
}
if (sameStartSquare) {
selectedRow = legalMoves[0].fromY;
selectedCol = legalMoves[0].fromX;
}
}
/* Make sure the board is redrawn in its new state. */
repaint();
} // end doMakeMove();
/**
* Draw checkerboard pattern in gray and lightGray. Draw the
* checkers. If a game is in progress, hilite the legal moves.
*/
public void paintComponent(Graphics g) {
/* Draw a two-pixel black border around the edges of the canvas. */
g.setColor(Color.black);
g.drawRect(0, 0, getSize().width - 1, getSize().height - 1);
g.drawRect(1, 1, getSize().width - 3, getSize().height - 3);
/* Draw the squares of the checkerboard and the checkers. */
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
if (row % 2 == col % 2) g.setColor(Color.LIGHT_GRAY);
else g.setColor(Color.GRAY);
g.fillRect(2 + col * 20, 2 + row * 20, 20, 20);
switch (board.getPiece(row, col)) {
case 1:
g.setColor(Color.RED);
g.fillOval(4 + col * 20, 4 + row * 20, 15, 15);
break;
case 2:
g.setColor(Color.BLACK);
g.fillOval(4 + col * 20, 4 + row * 20, 15, 15);
break;
case 3:
g.setColor(Color.RED);
g.fillOval(4 + col * 20, 4 + row * 20, 15, 15);
g.setColor(Color.WHITE);
g.drawString("K", 7 + col * 20, 16 + row * 20);
break;
case 4:
g.setColor(Color.BLACK);
g.fillOval(4 + col * 20, 4 + row * 20, 15, 15);
g.setColor(Color.WHITE);
g.drawString("K", 7 + col * 20, 16 + row * 20);
break;
}
}
}
/* If a game is in progress, hilite the legal moves. Note that legalMoves
is never null while a game is in progress. */
if (gameInProgress) {
/* First, draw a 2-pixel cyan border around the pieces that can be moved. */
g.setColor(Color.cyan);
for (int i = 0; i < legalMoves.length; i++) {
g.drawRect(2 + legalMoves[i].fromX * 20, 2 + legalMoves[i].fromY * 20, 19, 19);
g.drawRect(3 + legalMoves[i].fromX * 20, 3 + legalMoves[i].fromY * 20, 17, 17);
}
/* If a piece is selected for moving (i.e. if selectedRow >= 0), then
draw a 2-pixel white border around that piece and draw green borders
around each square that that piece can be moved to. */
if (selectedRow >= 0) {
g.setColor(Color.white);
g.drawRect(2 + selectedCol * 20, 2 + selectedRow * 20, 19, 19);
g.drawRect(3 + selectedCol * 20, 3 + selectedRow * 20, 17, 17);
g.setColor(Color.green);
for (int i = 0; i < legalMoves.length; i++) {
if (legalMoves[i].fromX == selectedCol && legalMoves[i].fromY == selectedRow) {
g.drawRect(2 + legalMoves[i].toX * 20, 2 + legalMoves[i].toY * 20, 19, 19);
g.drawRect(3 + legalMoves[i].toX * 20, 3 + legalMoves[i].toY * 20, 17, 17);
}
}
}
}
} // end paintComponent()
/**
* Respond to a user click on the board. If no game is in progress, show
* an error message. Otherwise, find the row and column that the user
* clicked and call doClickSquare() to handle it.
*/
public void mousePressed(MouseEvent evt) {
if (gameInProgress == false) message.setText("Click \"New Game\" to start a new game.");
else {
int col = (evt.getX() - 2) / 20;
int row = (evt.getY() - 2) / 20;
if (col >= 0 && col < 8 && row >= 0 && row < 8) doClickSquare(row, col);
}
}
public void mouseReleased(MouseEvent evt) {}
public void mouseClicked(MouseEvent evt) {}
public void mouseEntered(MouseEvent evt) {}
public void mouseExited(MouseEvent evt) {}
} // end class Board