0

I'm currently working on a project to predict moves in chess based on the position, I am using an action listener for my array of buttons (like JButton[][]).

Below is the error I'm getting...

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "javax.swing.JButton.getIcon()" because "this.chessboardButtons[cord_x][cord_y]" is null
at Homework6_Alex.ChessBoard.actionPerformed(ChessBoard.java:151)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6614)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
at java.desktop/java.awt.Component.processEvent(Component.java:6379)
at java.desktop/java.awt.Container.processEvent(Container.java:2263)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4990)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4822)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4919)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4548)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4489)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2769)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4822)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Below this is the code I'm working with for the ActionListener portion. Any ideas on how I can solve this?

@Override
public void actionPerformed(ActionEvent e){
        if (e.getSource() instanceof JButton) {
            //System.out.println(chessboardButtons[((JButton)e.getSource()).getX()][((JButton) e.getSource()).getY()].getLocation());
            int x = ((JButton) e.getSource()).getX();
            int y = ((JButton) e.getSource()).getY();

            int cord_y = (y /8)/8;
            int cord_x = (x /8)/8;

            System.out.println(cord_x + " " + cord_y);

            if (chessboardButtons[cord_x][cord_y].getIcon() == whiteKingIcon) {
                System.out.println("Nothing");
            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == whiteQueenIcon) {
                System.out.println("Nothing");
            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == whiteBishop1Icon) {
                System.out.println("Nothing");
            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == whiteRook1Icon ) {
                System.out.println("Nothing");
            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == whitePawn1Icon) {
                chessboardButtons[cord_x +1][cord_y].setBackground(Color.red);
                chessboardButtons[cord_x +1][cord_y].setOpaque(true);
                chessboardButtons[cord_x +2][cord_y].setBackground(Color.red);
                chessboardButtons[cord_x +2 ][cord_y].setOpaque(true);
            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == whiteKnight1Icon) {
                System.out.println("Nothing");
            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == null) {
                //Instructions instructions = new Instructions();
                System.out.println("rules");
            }
        }

Additional Side Note: when using the .getLocation() for buttons my point I get are increases of 75, from X 0 - 525 to Y 0-525 so a board of 525, 525. I am using a gridLayout 8,8.

Below is my whole class for more information:

public class ChessBoard extends JFrame implements ActionListener{

JLayeredPane layeredpane;
JPanel chessboard;
JButton[][] chessboardButtons;
Color black;


JLabel whiteKing;
JLabel whiteQueen;
JLabel whiteRook1;
JLabel whiteRook2;
JLabel whiteBishop1;
JLabel whiteBishop2;
JLabel whiteKnight1;
JLabel whiteKnight2;
JLabel whitePawn1;
JLabel whitePawn2;
JLabel whitePawn3;
JLabel whitePawn4;
JLabel whitePawn5;
JLabel whitePawn6;
JLabel whitePawn7;
JLabel whitePawn8;

ImageIcon whiteKingIcon = new ImageIcon("/Users/aengelsr/Cs245intellij/src/Homework6_Alex/Icons/white_king.jpeg");
ImageIcon whiteQueenIcon = new ImageIcon("/Users/aengelsr/Cs245intellij/src/Homework6_Alex/Icons/white_queen.jpeg");
ImageIcon whiteRook1Icon = new ImageIcon("/Users/aengelsr/Cs245intellij/src/Homework6_Alex/Icons/white_rook.jpeg");
ImageIcon whiteBishop1Icon = new ImageIcon("/Users/aengelsr/Cs245intellij/src/Homework6_Alex/Icons/white_bishop.jpeg");
ImageIcon whiteKnight1Icon = new ImageIcon("/Users/aengelsr/Cs245intellij/src/Homework6_Alex/Icons/white_knight.jpeg");
ImageIcon whitePawn1Icon = new ImageIcon("/Users/aengelsr/Cs245intellij/src/Homework6_Alex/Icons/white_pawn.jpeg");

ArrayList<ImageIcon> whitelist;
List<Integer> blackPeices;


UIManager Ui;


ChessBoard() throws IndexOutOfBoundsException {
    Dimension Size = new Dimension(600, 600);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    setResizable(true);
    setLocationRelativeTo(null);

    setSize(600, 600);
    setTitle("Chess Board");

    layeredpane = new JLayeredPane();
    getContentPane().add(layeredpane);
    layeredpane.setPreferredSize(Size);

    chessboard = new JPanel();
    layeredpane.add(chessboard, JLayeredPane.DEFAULT_LAYER);
    chessboard.setLayout(new GridLayout(8, 8));
    chessboard.setPreferredSize(Size);
    chessboard.setBounds(0, 0, Size.width, Size.height);

    Ui = new UIManager();
    chessboardButtons = new JButton[9][9];
    black = Color.black;


    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {

            chessboardButtons[i][j] = new JButton();
            chessboardButtons[i][j].setBorderPainted(false);
            //chessboardButtons[i][j].setText(String.valueOf(i * 8 + j));

            if ((i + j) % 2 != 0) {
                chessboardButtons[i][j].setBackground(black);
                chessboardButtons[i][j].setOpaque(true);
            }
            chessboard.add(chessboardButtons[i][j]);
            chessboardButtons[i][j].addActionListener(this);

        }
    }


    whitelist = new ArrayList<ImageIcon>();
    whitelist.add(whiteKingIcon);
    whitelist.add(whiteQueenIcon);
    whitelist.add(whiteRook1Icon);
    whitelist.add(whiteBishop1Icon);
    whitelist.add(whiteKnight1Icon);
    whitelist.add(whitePawn1Icon);


    blackPeices = new ArrayList<>();


    Collections.shuffle(whitelist);
    Collections.shuffle(blackPeices);

    System.out.println(whitelist);


    for(int i = 0; i < whitelist.size(); i++) {
        int random_x = (int) (Math.random() * 8);
        int random_y = (int) (Math.random() * 8);
        chessboardButtons[random_x][random_y].setIcon(whitelist.get(i));
    }
    for(int i = 0; i < whitelist.size(); i++) {
        int random_x = (int) (Math.random() * 8);
        int random_y = (int) (Math.random() * 8);
        chessboardButtons[random_x][random_y].setIcon((new ImageIcon("/Users/aengelsr/Cs245intellij/src/Homework6_Alex/Icons/white_pawn.jpeg")));
    }

        setVisible(true);
        pack();

    }


@Override
public void actionPerformed(ActionEvent e){



        if (e.getSource() instanceof JButton) {
            //System.out.println(chessboardButtons[((JButton)e.getSource()).getX()][((JButton) e.getSource()).getY()].getLocation());
            int x = ((JButton) e.getSource()).getX();
            int y = ((JButton) e.getSource()).getY();


            int cord_y = (y /8)/8;
            int cord_x = (x /8)/8;

            System.out.println(cord_x + " " + cord_y);


            if (chessboardButtons[cord_x][cord_y].getIcon() == whiteKingIcon) {
                System.out.println("Nothing");

            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == whiteQueenIcon) {
                System.out.println("Nothing");

            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == whiteBishop1Icon) {
                System.out.println("Nothing");

            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == whiteRook1Icon ) {
                System.out.println("Nothing");

            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == whitePawn1Icon) {
                chessboardButtons[cord_x +1][cord_y].setBackground(Color.red);
                chessboardButtons[cord_x +1][cord_y].setOpaque(true);
                chessboardButtons[cord_x +2][cord_y].setBackground(Color.red);
                chessboardButtons[cord_x +2 ][cord_y].setOpaque(true);


            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == whiteKnight1Icon) {
                System.out.println("Nothing");


            }
            if (chessboardButtons[cord_x][cord_y].getIcon() == null) {
                //Instructions instructions = new Instructions();
                System.out.println("rules");

            }
        }

    }


}

Thank you!

My chessboard with random placement

My chessboard when clicking a pawn and the expected output- we are supposed to highlight all possible moves

and finally a another note - we don't actually have to get this to play chess, only show visually possible moves of each peice even if there a another "peice" in the way, that in real life would make the move impossible

aengelsr
  • 1
  • 1
  • `ImageIcon whiteKingIcon = new ImageIcon("/Users/aengelsr/Cs245intellij/src/Homework6_Alex/Icons/white_king.jpeg");` should become something more like `ImageIcon whiteKingIcon = new ImageIcon(ImageIO.read(getClass().getResource("/Homework6_Alex/Icons/white_king.jpeg"));`. `ImageIO` will throw an exception if the the image can't be loaded for some reason – MadProgrammer Dec 15 '21 at 03:55
  • You are using 8 for either cord_x or cord_y. What does your println say? – tgdavies Dec 15 '21 at 03:55
  • I would also decouple the "visual" from the "data" state. Instead, the "game" should just contain information about the current state and the you should have a rendering workflow which renders that state - so you're not then doing `if (chessboardButtons[cord_x][cord_y].getIcon() == whiteKingIcon)` – MadProgrammer Dec 15 '21 at 03:56
  • Also how do you expect `chessboardButtons[cord_x +2 ][cord_y].setOpaque(true);` to work with cord_x+2? – tgdavies Dec 15 '21 at 03:57
  • madProgrammer - for the ImageIcon - they are just images I have stored in the project folder, nothing special, to use as. the icons, I will attach a screenshot of the board with the icons. TgDavies - for the cord_x/cord_y I am dividing the number 8 times to get within the index of 8 that I have set, becuase when I don't do this I get locations/points. of 0-525 increasing by 75's in both x and Y – aengelsr Dec 15 '21 at 04:59
  • *"they are just images I have stored in the project folder, nothing special,"* What @MadProgrammer was alluding to, is that these images will become embedded resources that **need** to be accessed by URL rather than File (as the code is now doing) and that `ImageIO` will produce helpful output if the images are not found, as opposed the current method which could fail silently (until an NPE later). BTW: Given it is a chessboard, see also [this answer](https://stackoverflow.com/a/21142687/418556). – Andrew Thompson Dec 15 '21 at 05:09
  • @aengelsr I understand, but you should avoid using them as mechanism to track the state of play - the images should represent the model, not be part of the model, and Andrew has also highlighted the other issue – MadProgrammer Dec 15 '21 at 06:54

0 Answers0