Hey all,
I have been busy building my own chess game and as of now im a bit stomped.

Well you see i have an object Board, this object will be initiated and it will create a new frame with various panels one of them being the panel which holds the squares of the board, inside that panel i create a grid of panels, with pictures as backgrounds(blocks for the chess board either black or white), and to each of those panels i add a jlabel, which in the future will hold the image of the piece on the board. Now when creating the panels i labeled them so i may know what co-ordinates of the piece are i.e A-H and 1-8. I lable the usingthe setName() method, each of the ImagePanels and labels are declared globally.

The problem is that i have a method -listLabelNames() that will list the names of the lables/panels ie A1-H8. When i call the method from within the instance after the frame has added all its components, the method works fine and prints out the array of the panels/labels names. However when i iniate board and call the listLabelNames() method from the object which iniated board the array returns a null pointer.

My thoughts are that in the calling class the statement which creates a new instance of board doesnt wait until the instnce/frame is fully created... And then when i call listLabelNames() the array isnt yet filled. I cant seem to find an answer/solution:

    package chess;

    import java.awt.*;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;

    /**
     * Board.java 
     * Purpose: This will set up the Board for the game to be played,
     * ,passed by the Game.java, like setting up appropriate board style, setting
     * pieces in correct place and style according to colour chosen by Player etc,
     * Also Board class shares calling classes instance as the calling class has the
     * necessary methods needed to check if the player move is acceptable, and
     * enforce rules etc on actions like moving a piece from one block to another
     *
     *
     * @author David Kroukamp
     * @version 1.0 3/11/2012
     */
    public class Board extends Main {

        private Image boardImage1;
        private Image boardImage2;

        private JPanel centerPanel = new JPanel();
        private JPanel southPanel = new JPanel();
        private JPanel eastPanel = new JPanel();
        private JPanel westPanel = new JPanel();

        private JLabel[] labels = new JLabel[64];
        private ImagePanel[] panels = new ImagePanel[64];

        public Board(Image boardImage1, Image boardImage2) {
            this.boardImage1 = boardImage1;
            this.boardImage2 = boardImage2;

            //Schedule a job for the event-dispatching thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    createAndShowGUI();
                }
            });
        }

        /**
         * Create the GUI and show it; for thread safety, this method should be
         * invoked from the event-dispatching thread.
         */
        private void createAndShowGUI() {

            //Create and set up the window with title.APP_NAME + " " + VERSION_ID + " by " + AUTHOR
            setTitle(APP_NAME + " " + VERSION_ID + " by " + AUTHOR);

            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

            //Set up the content pane.
            addComponentsToPane(getContentPane());

            //Size and display the window.
            setSize(800, 600);

            //center JFrame.
            setLocationRelativeTo(null);

            //makes frame non-resizable
            setResizable(false);

            //shows the frame
            setVisible(true);
        }

        /**
         * Adds all the necessary components to the content pane of the JFrame, and
         * adds appropriate listeners to components.
         */
        private void addComponentsToPane(Container contentPane) {

            BorderLayout borderLayout = new BorderLayout(10, 10);
            GridLayout gridLayout = new GridLayout(8, 8);


            contentPane.setLayout(borderLayout);
            centerPanel.setLayout(gridLayout);


            addLabelsToSouthPanel();

            addLabelsToWestPanel();

            addPanelsAndLabels();

            contentPane.add(centerPanel, BorderLayout.CENTER);
            contentPane.add(southPanel, BorderLayout.SOUTH);
            contentPane.add(eastPanel, BorderLayout.EAST);
            contentPane.add(westPanel, BorderLayout.WEST);


            listLabelNames//works when i call from here prints fine
        }

        private void addLabelsToSouthPanel() {

            GridLayout gridLayout = new GridLayout(0, 8);

            southPanel.setLayout(gridLayout);
            JLabel[] lbls = new JLabel[8];
            String[] label = {"A", "B", "C", "D", "E", "F", "G", "H"};
            for (int i = 0; i < 8; i++) {
                lbls[i] = new JLabel(label[i] + "");
                southPanel.add(lbls[i]);
            }
        }

        private void addLabelsToWestPanel() {

            GridLayout gridLayout = new GridLayout(8, 0);

            westPanel.setLayout(gridLayout);
            JLabel[] lbls = new JLabel[8];
            int[] num = {8, 7, 6, 5, 4, 3, 2, 1};
            for (int i = 0; i < 8; i++) {
                lbls[i] = new JLabel(num[i] + "");
                westPanel.add(lbls[i]);
            }
        }

        private void addPanelsAndLabels() {

            addPanelsAndImages();

            for (int i = 0; i < panels.length; i++) {
                labels[i] = new JLabel();
                labels[i].setName(panels[i].getName());//used to know the postion of the label on the board
                panels[i].add(labels[i]);
                centerPanel.add(panels[i]);
                //System.out.println(panels[i].getName());//works when i call from here prints fine
                //System.out.println(labels[i].getName());//works when i call from here prints fine
           System.out.println("done");
            }
        }

        private void addPanelsAndImages() {
            int count = 0;

            String[] label = {"A", "B", "C", "D", "E", "F", "G", "H"};
            int[] num = {8, 7, 6, 5, 4, 3, 2, 1};

            for (int row = 0; row < 8; row++) {
                for (int col = 0; col < 8; col++) {
                    if (row % 2 == 0) {
                        if ((col + row) % 2 == 0) {
                            panels[count] = new ImagePanel(boardImage1);
                        } else {
                            panels[count] = new ImagePanel(boardImage2);
                        }
                    } else {
                        if ((col + row) % 2 == 0) {
                            panels[count] = new ImagePanel(boardImage1);
                        } else {
                            panels[count] = new ImagePanel(boardImage2);
                        }
                    }
                    panels[count].setName(label[col] + " " + num[row]);

                    count++;
                }
            }
        }
        //method sets image of a label at a certain position in the board according to the block name i.e D4

        public void listLabelNames() {
            for (int s = 0; s < labels.length; s++) {

                System.out.println(labels[s].getName());
            }
        }

    //nested class used to set the background of frame contenPane
        class ImagePanel extends JPanel {

            private Image image;

            /**
             * Default constructor used to set the image for the background for the
             * instance
             */
            public ImagePanel(Image img) {
                image = img;
            }

            @Override
            protected void paintComponent(Graphics g) {
                //draws image to background to scale of frame
                g.drawImage(image, 0, 0, null);
            }
        }
    }

and in the calling class i call board like this:
public void startGame() {

        Image boardImage1 = new ImageIcon(boardImages + "wBlock.jpg").getImage();
        Image boardImage2 = new ImageIcon(boardImages + "bBlock.jpg").getImage();

        Board board = new Board(boardImage1, boardImage2);

       board.listLabelNames();//returns null pointer here but not when called from within the instance
        /*
        while(checkmate!=true||stalemate!=true||surrender!=true) {

        }

        */
    }

Recommended Answers

All 2 Replies

Try debugging your code by adding println() statements to show execution progress and how variable values are changing. For example:
Add a: System.out.println("var=" + var);
after every line where a variable is changed by an assignment statement or read into.

The printout should show you in what order the methods are called and when values are given to variables.

Your diagnosis sounds probable to me.
Rather than using invokeLater in the constructor, why not move that up to startGame() so all the startup code runs on the same (swing) thread?

commented: Thank you James, that was spot on +0
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.