-1

*Note: * I'm new here. If you're going to downvote please tell me why.

I'm writing a java chess program using swing. I'm able to display the board, initialize pieces, and store them in a two dimensional array. However, I can't figure out how to display the pieces on my canvas. I keep getting a null pointer error on line 65 of class Piece.

*Update: * I've included some of the suggested changes. The null pointer error has cleared up, but I'm still having trouble getting the pieces to display. I don't think I've correctly pointed them at the canvas I created in class Chess.

My program is broken into three classes as follows:

Class Chess

   import java.util.Scanner;

    import javax.swing.*;
    //import java.awt.*;


    public class Chess {
        public static final int WINDOW_WIDTH=600;
        public static final int WINDOW_HEIGHT=600;
        public static final int SQUARE_WIDTH = (WINDOW_WIDTH-10)/8;
        public static final int SQUARE_HEIGHT = (WINDOW_HEIGHT-40)/8;

        public static int position[][] = {};

        public BoardComponent mycanvas= new BoardComponent(this);

        public Chess()
        {

            JFrame mywindow;
            mywindow=new JFrame("ChessMaster 2012");
            mywindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mywindow.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);

            //BoardComponent mycanvas= new BoardComponent(this);    
            mywindow.add(mycanvas);
            mywindow.setVisible(true);              //window appears here
        }

        public static void main(String[] args) {
            position = new int [8][8];

            new Chess();
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;

import javax.swing.ImageIcon;

public class Piece extends JPanel{

    Piece[]  mypiece;

    public ImageIcon piece; 
    int nextID = 0;
    BoardComponent board;
    Chess chess;
    public int locx, locy;

    public void setCanvas(BoardComponent board)
    {
        this.board=board;
    }

    public Piece(char color, char Type, int posX, int posY){
        // each piece assigned a PK on creation, beginning sequentially from top left 
        // and looping back to the beginning of each row
        int pieceID = nextID;
        char pieceColor = color;
        char pieceType = Type;

        posX = locx;
        posY = locy;

        // P = pawn, K = knight, R = Rook, B = Bishop, Q = Queen, 
        //S = king (can't reuse K, so we use S instead)
        if (pieceType == 'P'){
            new Pawn(pieceColor);
        }
        else if (pieceType == 'K'){
            new Knight(pieceColor);
        }
        else if (pieceType == 'R'){
            new Rook(pieceColor);
        }
        else if (pieceType == 'B'){
            new Bishop(pieceColor);
        }
        else if (pieceType == 'Q'){
            new Queen(pieceColor);
        }
        else if (pieceType == 'S'){
            new King(pieceColor);
        }
        nextID ++;
        Chess.position[posX][posY] = pieceID;
        setCanvas(board);
        repaint();
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        drawPiece(g);
    }

    public void drawPiece(Graphics g){
        g.drawImage(piece.getImage(),(locx*Chess.SQUARE_WIDTH),(locy*Chess.SQUARE_HEIGHT),null);

    }

    public class Pawn{

        public Pawn(char color){
            if(color == 'w'){
                piece = new ImageIcon("src/gfx/wpawn.gif");
            }
            else{
                piece = new ImageIcon("src/gfx/bpawn.gif");
            }
        }
    }   

    public class Knight{

        public Knight(char color){
            if(color == 'w'){
                piece = new ImageIcon("src/gfx/wknight.gif");
            }
            else{
                piece = new ImageIcon("src/gfx/bknight.gif");
            }
        }
    }   

    public class Rook{
        public Rook(char color){
            if(color == 'w'){
                piece = new ImageIcon("src/gfx/wrook.gif");
            }
            else{
                piece = new ImageIcon("src/gfx/brook.gif");
            }
        }
    }

    public class Bishop{
        public Bishop(char color){
            if(color == 'w'){
                piece = new ImageIcon("src/gfx/wbishop.gif");
            }
            else{
                piece = new ImageIcon("src/gfx/bbishop.gif");
            }
        }
    }

    public class Queen{
        public Queen(char color){
            if(color == 'w'){
                piece = new ImageIcon("src/gfx/wqueen.gif");
            }
            else{
                piece = new ImageIcon("src/gfx/bqueen.gif");
            }
    }
    }

    public class King{
        public King(char color){
            if(color == 'w'){
                piece = new ImageIcon("src/gfx/wking.gif");
            }
            else{
                piece = new ImageIcon("src/gfx/bking.gif");
            }
        }
    }

    }

Class BoardComponent:

    import java.awt.*;
import javax.swing.*;

//This class draws the board and places the initial pieces
public class BoardComponent extends JComponent{
    Chess chess;

    public BoardComponent(Chess chessobject)
    {
        super();
        chess=chessobject;
    }

    @Override
    public void paintComponent(Graphics g)
    {
    super.paintComponent(g);
    int rowCount = 0;
    int highCount = 0;
    int wideCount = 0;
    int squareCount = 0;
    ImageIcon piece;
    for(rowCount = 0; rowCount<8;rowCount++){

        for(int i = 0; i < 8; i++){
            if(squareCount%2==1){
                g.setColor(Color.ORANGE);
            }
            else{
                g.setColor(Color.darkGray);
            }
            g.fillRect(wideCount,highCount, Chess.SQUARE_WIDTH-5, Chess.SQUARE_HEIGHT-5);
            squareCount = squareCount + 1;
            wideCount = wideCount + Chess.SQUARE_WIDTH;
            g.setColor(Color.RED);
        }
        squareCount +=1;
        wideCount = 0;
        highCount = highCount + Chess.SQUARE_HEIGHT;
    }
    }
}

Class Piece:

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;

import javax.swing.ImageIcon;

public class Piece extends JPanel{

Piece[]  mypiece;

public ImageIcon piece; 
int nextID = 0;
BoardComponent board;
Chess chess;
public int locx, locy;

public void setCanvas(BoardComponent board)
{
    this.board=board;
}

public Piece(char color, char Type, int posX, int posY){
    // each piece assigned a PK on creation, beginning sequentially from top left 
    // and looping back to the beginning of each row
    int pieceID = nextID;
    char pieceColor = color;
    char pieceType = Type;

    posX = locx;
    posY = locy;

    // P = pawn, K = knight, R = Rook, B = Bishop, Q = Queen, 
    //S = king (can't reuse K, so we use S instead)
    if (pieceType == 'P'){
        new Pawn(pieceColor);
    }
    else if (pieceType == 'K'){
        new Knight(pieceColor);
    }
    else if (pieceType == 'R'){
        new Rook(pieceColor);
    }
    else if (pieceType == 'B'){
        new Bishop(pieceColor);
    }
    else if (pieceType == 'Q'){
        new Queen(pieceColor);
    }
    else if (pieceType == 'S'){
        new King(pieceColor);
    }
    nextID ++;
    Chess.position[posX][posY] = pieceID;
    setCanvas(board);
    repaint();
}

@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    drawPiece(g);
}

public void drawPiece(Graphics g){
    g.drawImage(piece.getImage(),(locx*Chess.SQUARE_WIDTH),(locy*Chess.SQUARE_HEIGHT),null);

}

public class Pawn{

    public Pawn(char color){
        if(color == 'w'){
            piece = new ImageIcon("src/gfx/wpawn.gif");
        }
        else{
            piece = new ImageIcon("src/gfx/bpawn.gif");
        }
    }
}   

public class Knight{

    public Knight(char color){
        if(color == 'w'){
            piece = new ImageIcon("src/gfx/wknight.gif");
        }
        else{
            piece = new ImageIcon("src/gfx/bknight.gif");
        }
    }
}   

public class Rook{
    public Rook(char color){
        if(color == 'w'){
            piece = new ImageIcon("src/gfx/wrook.gif");
        }
        else{
            piece = new ImageIcon("src/gfx/brook.gif");
        }
    }
}

public class Bishop{
    public Bishop(char color){
        if(color == 'w'){
            piece = new ImageIcon("src/gfx/wbishop.gif");
        }
        else{
            piece = new ImageIcon("src/gfx/bbishop.gif");
        }
    }
}

public class Queen{
    public Queen(char color){
        if(color == 'w'){
            piece = new ImageIcon("src/gfx/wqueen.gif");
        }
        else{
            piece = new ImageIcon("src/gfx/bqueen.gif");
        }
}
}

public class King{
    public King(char color){
        if(color == 'w'){
            piece = new ImageIcon("src/gfx/wking.gif");
        }
        else{
            piece = new ImageIcon("src/gfx/bking.gif");
        }
    }
}

}

I'm fairly new to java, and this is really throwing me for a loop. Can anyone help?

Thanks!

Ein_Bear
  • 47
  • 1
  • 7
  • Where are you getting the Null Pointer error? Be more specific. – hesson Dec 03 '12 at 08:40
  • Line 65 of Class Piece. It's commented in the code, but I'll edit the post too. – Ein_Bear Dec 03 '12 at 08:43
  • It's hard for me to figure out what line 65 is. Can you point it out with a comment in the code? – hesson Dec 03 '12 at 08:45
  • It's in there. Here's the relevant block: `Graphics g; g = board.getGraphics(); // null pointer here g.drawImage(piece.getImage(),(locx*Chess.SQUARE_WIDTH),(locy*Chess.SQUARE_HEIGHT),null);` – Ein_Bear Dec 03 '12 at 08:51

2 Answers2

3
  • Dont call drawPiece() from your constructor for what reason? I think repaint() might be what you need.

  • dont use getGraphics() as it wont be initialized yet until the panel is added and first repaint is done if im not mistaken.

  • Also never forget to honor paint chain and have super.paintComponent(..) as your first call in your overridden paintComponent(..) method of panel.

  • Rather extend JPanel and not JComponent

I think you meant to call drawPiece() in paintComponent(..) in which place you should just pass the Graphics object to drawPiece() from paintComponent(..) like so:

public class Piece extends JPanel{



    public Piece(char color, char Type, int posX, int posY){

        // each piece assigned a PK on creation, beginning sequentially from top left 
        // and looping back to the beginning of each row
        ....

        // P = pawn, K = knight, R = Rook, B = Bishop, Q = Queen, 
        //S = king (can't reuse K, so we use S instead (from Shah, the historical name)) 
        ....
            nextID ++;
            Chess.position[posX][posY] = pieceID;
            repaint();
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        drawPiece(g);
    }

    public void drawPiece(Graphics g){
        g.drawImage(piece.getImage(),(locx*Chess.SQUARE_WIDTH),(locy*Chess.SQUARE_HEIGHT),null);
    }
}

Other suggestions:

  • Create JFrame and other Swing components on EDT by wrapping UI creation code in

    SwingUtilities.invokeLater(new Runnable(){
        @Override 
        public void run() {
           //create ui here
        }
    });
    
  • Dont call setSize(...) on JFrame

rather override JPanel getPreferredSize() and return an appropriate size which fits components etc than you can remove setSize call on JFrame and call pack() on JFrame instance before setting visible

David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
0

It seems like your variable board is not initialized yet. You need to call setCanvas() first to initialize it, then you can call drawPiece().

hesson
  • 1,812
  • 4
  • 23
  • 35