Elliot King
Elliot King

Reputation: 92

How do I Use a For Loop with GridBagLayout

I am wondering if there is any way in java to make a for loop place components onto a JFrame using GridBagLayout. I know, I could just use GridLayout, but I don't know how to make bigger buttons or components using a for loop. How would I use GridBagLayout and for loop to make different size buttons? Here is what I came up with, but it doesn't even print out multiple rows and doesn't work:

        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.weightx = 1;
        c.weighty = 1;
        for(int j = 0; j <= 2; j++) {
            c.fill = GridBagConstraints.BOTH;
            c.gridy = j;
            for(int i = 0; i < 4; i++) {
                c.gridx = i;
                panel.add(buttons.get(i), c);
            }

        }

I know, I did not add different size buttons, but I wanted to add that and also make this current program work

Upvotes: 0

Views: 811

Answers (2)

Boris
Boris

Reputation: 24453

It is possible to place components using GridBagLayout and a for loop and set different sizes, here is a working example:

JFrame frame = new JFrame();
frame.setSize(500, 500);
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.weightx = 0.2;
c.weighty = 0.25;
for (int row = 1; row <= 3; row++) {
    c.gridy = row;
    for (int column = 1; column <= 4; column++) {
        c.gridx = column;
        c.ipadx = row * 2;
        c.ipady = row * column * 10;
        JButton button = new JButton("Button " + row + "," + column);
        panel.add(button, c);
    }
}
frame.add(panel);
frame.setVisible(true);

GridBagLayout example

More info on how to use GridBagLayout.

Upvotes: 0

MarsAtomic
MarsAtomic

Reputation: 10696

Your sample code doesn't work, but it has nothing to do with GridBagLayout. Let's take a closer look at your nested loops:

for(int j = 0; j <= 2; j++) {
    c.fill = GridBagConstraints.BOTH;
    c.gridy = j;
    for(int i = 0; i < 4; i++) {
        c.gridx = i;
        panel.add(buttons.get(i), c); // <---- Do you see the problem?
    }
}

See my comment in your code. You presumably have an ArrayList with twelve buttons in it, and you want it arranged in three rows of four columns each, but according to you, your code "doesn't even print out multiple rows."

You've set your variable i to increment from 0 to 3, and on each iteration of the outer loop, it resets with the loop, going from 0 to 3 all over again. This means that you're adding the first four buttons from your ArrayList three times, instead of adding each of the twelve buttons once.

You can solve this problem by adding an index field which increments on each combined iteration of the outer and inner loops, like this:

int index = 0; // <---- Make sure you've declared and initialized the index

for(int j = 0; j <= 2; j++) {
    c.fill = GridBagConstraints.BOTH;
    c.gridy = j;
    for(int i = 0; i < 4; i++) {
        c.gridx = i;
        panel.add(buttons.get(index), c); // <---- This will actually do what you want
        index++; // <---- Don't forget to increment the index to get to all the buttons
    }
}

As for the rest, you haven't specified how you want to alter the size of your buttons, but there are two ways:

Preferred method: experiment with the gridwidth, gridheight and fill fields of GridBagConstraints to change the buttons' sizes.

When you use GridBagLayout, imagine your container is divided into evenly sized boxes. gridwidth and gridheight tell a component how many of those boxes to use to display itself. fill tells a component how to expand to fill any extra space in its box if it's smaller than that box.

GridBagLayout doesn't give you the pixel perfect control that you might be expecting, but what it does give you is a neatly arranged and flexible layout.

Non-preferred method: use the setPreferredSize() method of the individual component to change its size. I mention this technique simply because it's possible, but I have to warn you now that while it's a technique, it's a bad technique.

When you use a layout manager, you want to let that manager control as much as possible given the parameters you've set for it. Users will do things that you might not have considered, like stretching the UI into odd proportions, having it fill their display, smashing it down to tiny sizes or whatever. Layout managers automatically adjust for changes, but when you give it rigid rules like "make this button exactly this many pixels wide," you can encounter undesirable results.

Upvotes: 0

Related Questions