views:

125

answers:

5

I'm working through a JPanel exercise in a Java book. I'm tasked with creating a 5x4 grid using GridLayout.

When I loop through the container to add panels and buttons, the first add() throws the OOB exception. What am I doing wrong?

package mineField;

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

@SuppressWarnings("serial")

public class MineField extends JFrame {

private final int WIDTH = 250;
private final int HEIGHT = 120;
private final int MAX_ROWS = 5; 
private final int MAX_COLUMNS = 4;

public MineField() {

    super("Minefield");

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Container mineFieldGrid = getContentPane();
    mineFieldGrid.setLayout(new GridLayout(MAX_ROWS, MAX_COLUMNS));

    // loop through arrays, add panels, then add buttons to panels.
    for (int i = 0; i < MAX_ROWS; i++) {
        JPanel[] rows = new JPanel[i];

        mineFieldGrid.add(rows[i], rows[i].getName());
        rows[i].setBackground(Color.blue);

        for (int j = 0; j < MAX_COLUMNS; j++) {
            JButton[] buttons = new JButton[i];             
            rows[i].add(buttons[j], buttons[j].getName());
        }
    }

    mineFieldGrid.setSize(WIDTH, HEIGHT);
    mineFieldGrid.setVisible(true);

}

public int setRandomBomb(Container con)
{

    int bombID;

    bombID = (int) (Math.random() * con.getComponentCount());
    return bombID;


}
/**
 * @param args
 */
public static void main(String[] args) {

    //int randomBomb;
    //JButton bombLocation;

    MineField minePanel = new MineField();
    //minePanel[randomBomb] = minePanel.setRandomBomb(minePanel);

}

}

I'm sure I'm over-engineering a simple nested for loop. Since I'm new to Java, please be kind. I'm sure I'll return the favor some day.

+2  A: 

This part doesn't really make sense:

  for (int j = 0; j < MAX_COLUMNS; j++) {
        JButton[] buttons = new JButton[i];
        rows[i].add(buttons[j], buttons[j].getName());
  }

You're creating an array of i JButtons, and trying to add the jth to rows, which makes little sense and won't work if j >= i. You probably meant to do:

  JButton[] buttons = new JButton[MAX_COLUMNS];
  for (int j = 0; j < MAX_COLUMNS; j++) {
        rows[i].add(buttons[j], buttons[j].getName());
  }

But the array still doesn't contain any buttons, all you did is initialize it. There's really no reason for the array at all; this actually works:

  for (int j = 0; j < MAX_COLUMNS; j++) {
        JButton button = new JButton("foo");
        rows[i].add(button, button.getName());
  }
Michael Mrozek
A: 

The problem is that your button array is of size i, but j can be larger than i. For instance, the first time through, you are making an empty array here:

JButton[] buttons = new JButton[i];

because i is equal to 0. You then attempt to access it at index 0, which doesn't exist (since the array has no size) and you get your exception. Should you instead be doing something like:

JButton[] buttons = new JButton[MAX_COLUMNS];

That way you will have a button for each array location. Also, you will probably need to initialize the individual buttons - i.e. something like this:

for (int k = 0; k < MAX_COLUMNS; k++) {
    buttons[k] = new JButton();
}

(disclaimer: code not tested, but pulled out of you-know-where for example purposes only. There could be typos or unseen bugs.)

Good luck.

aperkins
+1  A: 
JPanel[] rows = new JPanel[i];

When i is 0, you create an array with 0 elements. You then try to access that array, but it has no elements in it.

dcp
A: 

It looks like you're creating way too many arrays. You're creating your arrays INSIDE the loops, so instead of creating 5 rows, you're creating 5 rows 5 times, or 25 rows.

The other problem is that you aren't actually creating any objects, only the array to hold the objects. For each object in your array, you need another "button[j] = new JButton()" line.

brydgesk
+2  A: 

JPanel[] rows = new JPanel[i];

i is 0 in the first iteration, which isn't what you want. Make that:

JPanel[] rows = new JPanel[MAX_ROWS];

Also, I think you want to take that completely outside the for loop, since you seem to be using its elements, which would be uninitialised...

This is also wrong:

JButton[] buttons = new JButton[i];

i can be 0 when j is 2 for example, in which case there's no such thing as a buttons[j]. Make them all MAX_* and I think you want to take them out of the loop, since I don't see the point in recreating them at every iteration. Also, you need to instantiate the individual array elements as well.

IVlad
Ok, so I allocate the JPanel[] array w/ MAX_ROWS. How do I initialize a JPanel array and with what values?
Mike
`JPanel[k] = new JPanel()` for each `k` between 0 and `MAX_ROWS - 1`.
IVlad
Ignore that last. So JPanel[] rows = new JPanel[MAX_ROWS] declares and allocates memory to my array. Now, how do I initialize the array with JPanel objects? I'll assume I then assign JButtons with rows[i].add(), right?
Mike
Maybe I'm being thick about this. This doesn't work. What am I missing?for (int i = 0; i < MAX_ROWS; i++) { JPanel[i] = new JPanel[];}
Mike
Yea, I knew it. I was being think. It should read rows[i] = new JPanel(). doh!
Mike