我在这里收到一个空指针异常,我不知道为什么。
import cs251.lab2.GomokuGUI;
import cs251.lab2.GomokuModel;
public class Gomoku implements GomokuModel {
public Square[][] gameBoard;
public static void main(String[] args) {
Gomoku game = new Gomoku();
if (args.length > 0) {
game.setComputerPlayer(args[0]);
}
GomokuGUI.showGUI(game);//This calls newGame().
}
@Override
public void newGame() { //Generic constant values.
this.gameBoard = new Square[NUM_HSQUARES][NUM_VSQUARES];
// For every block
for (Square[] s : gameBoard)
// And every element of that block
for (Square ss : s)
// Reset to empty.
{ss = Square.EMPTY;}
}
@Override
public String boardString() {
String output = "";
//This is where the problem is!!
for (Square[] s : this.gameBoard) // For every block
{
//output appends either " ", "x" or "o" accordingly.
for (Square ss : s)//For every element of the block.
{output += ss.toChar();}
// Must be time for a new row already!
output += "\n";
}
//output should now be some big nasty string of love xoxo\n baby.
return output;
}
}
存在以下行,并通过GomokuGUI.class
调用public static void showGUI(final GomokuModel model) {
// For thread safety, invoke GUI code on event-dispatching thread
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new GomokuGUI(model);
}
});
}
..... .....
private GomokuGUI ( GomokuModel gomokuModel ) {
model = gomokuModel;
model.newGame ( );
//Buncha GUI code...
}
如果我删除了这个。参考我仍然收到错误。也许我误解了这个?我想通过在newGame()中创建大小我创建了一个与这个游戏实例相关的独特对象gameBoard,通过调用game.gameBoard(函数中的this.gameBoard),我可以看看它的元素。 / p>
package cs251.lab2;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* This is the graphical user interface for the Gomoku game.
*/
public class GomokuGUI {
/**
* Class used to display the Gomoku game board
*/
private class BoardPanel extends JPanel {
/** Used to shut up the compiler */
private static final long serialVersionUID = 1L;
/**
* Draws the x's and o's on the game board in the right places.
* @param g Graphics context for the component
*/
public void drawBoard ( Graphics2D g ) {
// Read the string from the model so I know what to draw,
// convert to lowercase just in case.
String s = model.boardString().toLowerCase();
// Split board into rows
String[] rowStrings = s.split("\\n");
// Figure out number of rows and columns
int numRows = rowStrings.length;
int numCols = rowStrings[0].length();
// Use a somewhat wide pen based on size of box
int offset = SQUARE_SIZE / 5;
int x2offset = 2 * offset;
g.setStroke ( new BasicStroke ( offset ) );
// Draw the signs on the board (within the squares)
for ( int row = 0; row < numRows; row++ ) {
for ( int col = 0; col < numCols; col++ ) {
// Choose what to do depending on the character in the string I got
switch ( rowStrings[row].charAt(col) ) {
case 'o': // Draw a ring
g.setColor ( Color.BLUE );
g.drawOval ( col * SQUARE_SIZE + offset,
row * SQUARE_SIZE + offset,
SQUARE_SIZE - x2offset,
SQUARE_SIZE - x2offset );
break;
case 'x': // Draw an X
g.setColor ( Color.RED );
g.drawLine ( col * SQUARE_SIZE + offset,
row * SQUARE_SIZE + offset,
( col + 1 ) * SQUARE_SIZE - offset,
( row + 1 ) * SQUARE_SIZE - offset );
g.drawLine ( ( col + 1 ) * SQUARE_SIZE - offset,
row * SQUARE_SIZE + offset,
col * SQUARE_SIZE + offset,
( row + 1 ) * SQUARE_SIZE - offset );
break;
}
}
}
}
/**
* Mainly used to redraw the grid on the board, so that it's always there.
*/
@Override
public void paintComponent ( Graphics g ) {
g.setColor ( Color.BLACK );
int width = getWidth ( );
int height = getHeight ( );
for ( int row = 0; row <= GomokuModel.NUM_VSQUARES; row++ ) {
int line = row * SQUARE_SIZE;
// Draw the vertical lines
g.drawLine ( 0, line, width, line );
// Draw the horizontal lines
g.drawLine ( line, 0, line, height );
}
// Then draw the contents
drawBoard ( (Graphics2D) g );
}
}
/**
* Handles a mouse click on the board.
* @param x X position of the click
* @param y Y position of the click
*/
private void doMouseClick(int x, int y) {
int row = y / SQUARE_SIZE;
int col = x / SQUARE_SIZE;
boolean gameOver = true;
// Check current status and decide what to do
GomokuModel.Outcome outcome = model.doClick ( row, col );
// Better repaint so that the latest move shows up
boardFrame.repaint ( );
// If necessary present a dialog box
switch ( outcome ) {
case DRAW:
JOptionPane.showMessageDialog ( null, "Draw Game!", "Game Over",
JOptionPane.INFORMATION_MESSAGE );
break;
case CROSS_WINS:
JOptionPane.showMessageDialog ( null, "Cross Wins!", "Game Over",
JOptionPane.INFORMATION_MESSAGE );
break;
case RING_WINS:
JOptionPane.showMessageDialog ( null, "Ring Wins!", "Game Over",
JOptionPane.INFORMATION_MESSAGE );
break;
default:
// No action to take. Either game is over or someone clicked on the wrong spot.
gameOver = false;
break;
}
if ( gameOver ) {
// Question user about another game, and either quit or restart
int choice = JOptionPane.showConfirmDialog ( null, "Play again?", "Play again?",
JOptionPane.YES_NO_OPTION );
if ( choice == JOptionPane.NO_OPTION ) {
System.exit ( 0 );
} else {
model.newGame();
}
}
// Repaint after user choose a new game as otherwise we'll still see the old
// contents of the board, and that's no fun.
boardFrame.repaint();
}
/** Size in pixels of each square */
public static final int SQUARE_SIZE = 20;
/** Reference to the model class */
private final GomokuModel model;
/** Reference to my board */
private final JFrame boardFrame;
/**
* Constructor for the GUI.
* @param gomokuModel Reference to a model that correctly
* implements the interface, so that I know that all methods are
* there.
*/
private GomokuGUI ( GomokuModel gomokuModel ) {
model = gomokuModel;
model.newGame ( );
// Create the frame
boardFrame = new JFrame ( );
boardFrame.setTitle ( "Gomoku" );
// Create the board
BoardPanel boardPanel = new BoardPanel ( );
boardPanel.setPreferredSize ( new Dimension (
GomokuModel.NUM_HSQUARES * SQUARE_SIZE + 1,
GomokuModel.NUM_VSQUARES * SQUARE_SIZE + 1 ) );
boardPanel.addMouseListener ( new MouseAdapter() {
@Override
public void mouseClicked ( MouseEvent e ) {
int x = e.getX ( );
int y = e.getY ( );
doMouseClick(x, y);
}
});
// Create status panel for new game and quit buttons
JPanel statusPanel = new JPanel ( new FlowLayout ( ) );
statusPanel.setPreferredSize ( new Dimension (
GomokuModel.NUM_HSQUARES * SQUARE_SIZE, 50 ) );
// Create a new New Game Button
JButton newGameButton = new JButton ( "New Game" );
newGameButton.addActionListener ( new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
model.newGame ( );
boardFrame.repaint ( );
}
} );
statusPanel.add ( newGameButton );
// Create a nice quit button
JButton quitButton = new JButton ( "Quit" );
quitButton.addActionListener ( new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
System.exit ( 0 );
}
} );
statusPanel.add ( quitButton );
// Add the panels to the frame
boardFrame.add ( statusPanel, BorderLayout.NORTH );
boardFrame.add ( boardPanel, BorderLayout.CENTER );
// Make sure it looks good
boardFrame.pack ( );
boardFrame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
boardFrame.setLocationRelativeTo ( null );
boardFrame.setResizable ( false );
boardFrame.setVisible ( true );
}
/**
* Construct and display GUI for a Gomoku game
* @param model Reference to a model that correctly
* implements the interface, so that I know that all methods are
* there.
*/
public static void showGUI(final GomokuModel model) {
// For thread safety, invoke GUI code on event-dispatching thread
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new GomokuGUI(model);
}
});
}
}
答案 0 :(得分:3)
// For every block
for (Square[] s : gameBoard)
for (Square ss : s)
// Reset to empty.
{ss = Square.EMPTY;}
此循环不执行任何操作。它等同于:
// For every block
for (Square[] s : gameBoard) {
for(int i = 0; i < s.length; i++) {
Square ss;
ss = s[i];
ss = Square.EMPTY;
}
}
您可以看到的实际上并没有改变电路板。
相反,这样做:
for(Square[] s : gameBoard)
for(int i = 0; i < s.length; i++)
s[i] = Square.EMPTY;
或者:(并导入java.util.Arrays)
for(Square[] s : gameBoard)
Arrays.fill(s, Square.EMPTY);