I am trying to write a program to play chess and I am having problems with the UI.
The display is really simple. A big JLabel
that shows the current state of the chessboard occupies almost all of the window. Below it, in the same line, there are: a JLabel
indicating what player must move, a JTextArea
where he/she can write the move, a JButton
to press when the player wants to submit the move.
There is a single event handled, the pressing of the JButton
: when the button is pressed, the program excutes the move (not displayed because of SSCCE), creates a new image of the chessboard as it currently is, modifies the big JLabel
to show the new image.
The reloading of the image is contained in the method reloadImage()
. This method, among other things, calls the method setIcon()
for the big JLabel
: this in turn returns the following exception.
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at chess.ChessUI.reloadImage(ChessUI.java:145)
Anybody can help me?
SSCCE code snippet:
public class ChessUI extends JFrame {
// Swing fields
/**
*
*/
private static final long serialVersionUID = -2194112668235114615L;
// Swing fields
/** The greater {@link JPanel}. */
private JPanel contentPane;
/** The {@link ChessBoard} image. */
private JLabel boardImage;
/** The {@link ImageIcon} used in displaying the image. */
private Icon icon;
/** The text "Player moves". */
private JLabel playerIndicator;
/** The {@link JTextField} where the player can insert the move. */
private JTextField moveTextField;
/** The {@link JButton} for submitting a {@link ChessMove}. */
private JButton submitButton;
// Chess fields
// private ChessBoard board;
// private ChessImageCreator imgCreator;
private boolean whiteMoves = true;
public String path = "D:\\ChessProgram\\Board.jpg";
public String path2 = "D:\\ChessProgram\\test.png";
// =========================================================
// TODO | Constructors
/**
* Create the frame.
*/
public ChessUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, resolutionWidth, resolutionHeight);
contentPane = new JPanel();
// contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setBorder(new EmptyBorder(margin, margin, margin, margin));
setContentPane(contentPane);
contentPane.setLayout(null);
// Text
this.playerIndicator = new JLabel(" White moves. Insert move:");
playerIndicator.setBounds(0, imageResolution + margin, textWidth, buttonHeight);
contentPane.add(playerIndicator);
// Move field
moveTextField = new JTextField();
moveTextField.setBounds(textWidth + margin, imageResolution + margin, moveWidth, buttonHeight);
contentPane.add(moveTextField);
moveTextField.setColumns(10);
// Submit button
submitButton = new JButton("Submit");
submitButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) { }
} );
submitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// Acquire the input move
// ChessMove move = new ChessMove(moveTextField.getText(), board);
// If the move is acceptable...
// if( move.isValid(board.errorManager()) )
if( true ) // the condition has been changed to ensure the minimallity of the code example
{
// ...executes it...
// board.move(move);
reloadImage();
// ...changes the player...
whiteMoves = ! whiteMoves;
// ...and corrects the text specifying who can move.
playerIndicator.setText(" " + (whiteMoves ? "White" : "Black") + " moves. Insert move: ");
}
// If the move is invalid, the ErrorManager will act inside the call of the method .isValid()
}
} );
submitButton.setBounds(resolutionWidth - buttonWidth - 2*margin, imageResolution + margin, buttonWidth, buttonHeight);
contentPane.add(submitButton);
// Chess management
// this.board = new ChessBoard();
// this.imgCreator = new ChessImageCreator(board);
// ChessBoard image
// imgCreator.createImage(imageResolution/StdDraw.scale(), path);
icon = new ImageIcon(path);
JLabel lblImage = new JLabel(icon);
// lblImage.setBackground(Color.PINK);
lblImage.setBounds(0, 0, imageResolution, imageResolution);
contentPane.add(lblImage);
}
// =========================================================
// TODO | Graphic methods
public void reloadImage() {
// Recreate the image
// imgCreator.createImage(imageResolution/StdDraw.scale(), path);
// Reload the image
icon = new ImageIcon(path2); // Chosen path2 because of SSCCE
if( icon == null ) System.out.println("ICON IS NULL");
boardImage.setIcon(icon); // THIS LINE CAUSES EXCEPTION
}
// =========================================================
// TODO | Graphic setting
/** The number of pixels between the image of the {@link ChessBoard} and the {@link JFrame},
* and the number of pixels between the image and the interactive {@link JButton}. */
public int margin = defaultMargin;
/** The width and height of the image of the {@link ChessBoard}. */
public int imageResolution = defaultImageWidth;
/** The width of the window in pixel. */
public int resolutionWidth = imageResolution + 2*margin;
/** The height of the interactive {@link JButton} in pixel. */
public int buttonHeight = defaultButtonHeight;
/** The width of the interactive {@link JButton} in pixel. */
public int buttonWidth = defaultButtonWidth;
/** The width of the text "Player moves" in pixel. */
public int textWidth = defaultTextWidth;
/** The width of the field where the user can insert his/her {@link Move}. */
public int moveWidth = resolutionWidth-4*margin-textWidth-buttonWidth;
/** The height of the window in pixel. */
public int resolutionHeight = imageResolution + 2*margin + 3*buttonHeight;
/** The width of the window in pixel. */
// public int resolutionWidth = defaultFrameWidth;
/** The width and height of the image of the {@link ChessBoard}. */
// public int imageResolution = resolutionWidth - 2*margin;
// public static final int defaultFrameWidth = 612;
public static final int defaultImageWidth = 800;
public static final int defaultFrameHeight = 800;
public static final int defaultMargin = 10;
public static final int defaultButtonHeight = 25;
public static final int defaultButtonWidth = 100;
public static final int defaultTextWidth = 160;
// =========================================================
// TODO | Main
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ChessUI frame = new ChessUI();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}