2

I was going through my simple game application streamlining everything from 700 lines down to 177 getting rid of repetition. When I try running my application I get a Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException thrown at me. I know what it means (from reading this) and I know it has something to do with how I'm doing the actionListener but i don't know exactly how.

I followed all the tutorials I came across dealing with Arrays and JButtons but there must be something little going wrong. private JButton[][] blocks = new JButton[rows][cols] is being declared correctly so it's not that and I didn't change how I did blocks[i][j].addActionListener(this) from a previous version of my code except for the fact that I changed block1, block2... etc with block[i][j].

Here is what was thrown at me:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at blox.Blox.game(Blox.java:105)
    at blox.Blox.access$000(Blox.java:25)
    at blox.Blox$1.run(Blox.java:173)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:688)
    at java.awt.EventQueue$3.run(EventQueue.java:686)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

And here is my code:

public class Blox implements ActionListener {

  private final String gameVersion = "Blox - v1.0.2";
  private final int rows = 7;
  private final int cols = 7;

  // Board Inits
  private ImageIcon purpleBlock = new ImageIcon();
  private ImageIcon redBlock = new ImageIcon();
  private ImageIcon blueBlock = new ImageIcon();
  private ImageIcon greenBlock = new ImageIcon();
  private ImageIcon closeImage = new ImageIcon();
  private JButton[][] block = new JButton[rows][cols];
  private JPanel boardBg = new JPanel();

  // Error console init
  private JLabel errorMessage = new JLabel();
  private JPanel errorBg = new JPanel();
  private JButton closeError = new JButton();

  // Score/UI Inits
  private JButton resetBoard = new JButton("Reset Board");

  /**
   *  700 x 480 Frame Size
   *  Sets Up and displays initial scene.
   *
   */
  private void game() {

    // Initialize mainFrame
    JFrame mainFrame = new JFrame(gameVersion);
    Dimension minSize = new Dimension(700,480);
    mainFrame.setMinimumSize(minSize);
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainFrame.setLayout(null);
    mainFrame.setResizable(false);
    try {
      mainFrame.setContentPane(new JLabel(new ImageIcon(
          ImageIO.read(new File("bggrad.jpg")))));
    } catch (IOException e) {
      e.printStackTrace();
    }

    // Setup block Images
    try {
      purpleBlock.setImage(ImageIO.read(new File("purpleBlock.png")));
      redBlock.setImage(ImageIO.read(new File("redBlock.png")));
      blueBlock.setImage(ImageIO.read(new File("blueBlock.png")));
      greenBlock.setImage(ImageIO.read(new File("greenBlock.png")));
      closeImage.setImage(ImageIO.read(new File("close.jpg")));
    } catch (IOException e) {
      e.printStackTrace();
    }

    // Sets up error message panel
    // Only displayed if error occurs on ActionListener
    errorMessage.setText("");
    errorMessage.setForeground(Color.black);
    Font newLabelFont = new Font(errorMessage.getFont().getName(),
        Font.BOLD,errorMessage.getFont().getSize());
    errorMessage.setFont(newLabelFont);
    closeError.setIcon(closeImage);
    closeError.setBounds(0,0,24,24);
    errorBg.setBounds(0,430,700,30);
    errorBg.setBackground(Color.lightGray);
    errorBg.add(closeError);
    errorBg.add(errorMessage);
    errorBg.setVisible(false);

    // Sets up Score/UI Portions of Screen
    resetBoard.setBounds(60,363,175,25);
    resetBoard.setVisible(true);
    resetBoard.addActionListener(this);

    // Set Up Board
    boardBg.setLayout(new GridLayout(rows,cols));
    boardBg.setBounds(300,50,350,350);
    for(int i=0; i<rows; i++) {
      for(int j=0; i<cols; j++) {
        block[i][j].setIcon(randomizer());
        block[i][j].addActionListener(this);
        boardBg.add(block[i][j]);
      }
    }

    mainFrame.getContentPane().add(boardBg);
    mainFrame.getContentPane().add(errorBg);
    mainFrame.getContentPane().add(resetBoard);

    //mainFrame.pack();
    mainFrame.setVisible(true);
  }


  /**
   *  Checks onClick event for which JButton was clicked
   *  and changes JButton.setIcon() accordingly.
   *
   *  @param  none
   *  @return none
   *  @see    java.awt.event.*
   *  @see    JButton
   *  @see    setIcon()
   *  @see    getIcon()
   *
   */
  public void actionPerformed(ActionEvent e) {

    if(e.getSource()==resetBoard) {
      System.out.println("Resetting");
      gameReset();
    }

    if(e.getSource()==errorBg || e.getSource()==errorMessage) {
      errorBg.setVisible(false);
    }
  }

  public void gameReset() {

    for(int i=0; i<rows; i++) {
      for(int j=0; i<cols; j++) {
        block[i][j].setIcon(randomizer());
      }
    }
  }

  public ImageIcon randomizer() {

    Random r = new Random();
    int rNum = r.nextInt(4);

    if(rNum==0) {
      return purpleBlock;
    } else if(rNum==1) {
      return redBlock;
    } else if(rNum==2) {
      return greenBlock;
    } else {
      return blueBlock;
    }
  }

  public static void main(String[] args) {

    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new Blox().game();
      }
    });
  }
}
Community
  • 1
  • 1
pattmorter
  • 991
  • 9
  • 21

1 Answers1

4

The problem probably comes from your loops:

    for(int i=0; i<rows; i++) {
        for(int j=0; i<cols; j++) {
            block[i][j].setIcon(randomizer());
            block[i][j].addActionListener(this);
            boardBg.add(block[i][j]);
        }
    }

block[i][j] are not initialized. Initialize them first like this:

    for(int i=0; i<rows; i++) {
        for(int j=0; i<cols; j++) {.
            block[i][j] = new JButton();
            block[i][j].setIcon(randomizer());
            block[i][j].addActionListener(this);
            boardBg.add(block[i][j]);
        }
    }
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • I didn't know that even though i did `JButton[][] block = new JButton[rows][cols]` that I still had to do `block[i][j] = new JButton();` within the loop. I added that new line in but nothing changed. Still the same exact error. – pattmorter Feb 22 '13 at 17:31
  • 1
    @pattmorter Yes when you initiate an array, you still have to create each individual instances of the array. Allocating the array only provides memory space to hold the pointers of the individual instances. As for your issue, the error is not the same: `ArrayIndexOutOfBoundsException` is not the same thing as `NullPointerException`. The problem comes from your inner-loop which has an incorrect condition: `i < cols` should actually be `j < cols`. You are mixing your increments `i` and `j` – Guillaume Polet Feb 22 '13 at 17:51
  • Wow. I did not even notice that. In these fixed width fonts sometimes its hard to notice that stuff. – pattmorter Feb 22 '13 at 19:27