I seem to be missing something pretty basic about the GridBagLayout. I'm trying to specify that a label should be 2 units wide, and that a text field should be 10 units wide.
The following code imitates part of what I'm doing. It shows the text field and label taking up about the same amount of width. What am I missing or doing incorrectly?
package numbers;
import javax.swing.*;
import java.awt.*;
public class FooBar extends JFrame {
public static void main(String[] args) {
new FooBar();
}
FooBar() {
super("Foobar");
setSize(600,100);
JPanel panel = new JPanel();
setLayout(new GridBagLayout());
JLabel nLabel = new JLabel("Foo");
JTextField nTextField = new JTextField("Bar");
GridBagConstraints c = new GridBagConstraints();
add(nLabel, cs(0, 0, 2, 1, c.CENTER, c.NONE));
add(nTextField, cs(2, 0, 10, 1, c.CENTER, c.HORIZONTAL));
add(panel);
setVisible(true);
}
private GridBagConstraints cs(int gridx, int gridy,
int gridwidth, int gridheight,
int anchor, int fill) {
GridBagConstraints c = new GridBagConstraints();
c.gridx = gridx;
c.gridy = gridy;
c.gridwidth = gridwidth;
c.gridheight = gridheight;
c.anchor = anchor;
c.fill = fill;
c.weightx = 1;
c.weighty = 1;
return c;
}
}
I thought I'd specified that nLabel's gridwidth is 2, and that nTextField's gridwidth is 10. I would think the columns would be of about the same width they have the same weightx. Why, then, do the components have the same width? And why are the columns apparently of different sizes?
Update:
adding weightx = 2 and weightx = 10 seems to fix this snippet… but it doesn't work in a larger context. The code I'm using looks something like this:
add(intro1, cs(0, 0, 12, 1, c.WEST, c.NONE));
add(intro2, cs(0, 1, 12, 1, c.WEST, c.NONE));
add(nLabel, cs(0, 3, 2, 1, c.CENTER, c.NONE));
add(nTextField, cs(2, 3, 10, 1, c.CENTER, c.HORIZONTAL));
add(nthFoundLabel, cs(0, 4, 3, 1, c.CENTER, c.NONE));
add(nFoundText, cs(2, 4, 10, 1, c.CENTER, c.HORIZONTAL));
add(blankLine, cs(0, 5, 12, 1, c.CENTER, c.HORIZONTAL));
add(startButton, cs(0, 6, 6, 1, c.CENTER, c.NONE));
add(stopButton, cs(6, 6, 6, 1, c.CENTER, c.NONE));
add(blankLine, cs(0, 7, 12, 1, c.CENTER, c.BOTH));
add(progressLabel, cs(0, 8, 12, 1, c.CENTER, c.NONE));
add(lastFoundLabel, cs(0, 9, 3, 1, c.CENTER, c.NONE));
add(lastFoundText, cs(3, 9, 9, 1, c.CENTER, c.HORIZONTAL));
add(lastNText, cs(3, 10, 9, 1, c.CENTER, c.HORIZONTAL));
add(elapsedLabel, cs(0, 11, 3, 1, c.CENTER, c.HORIZONTAL));
add(remainingLabel, cs(0, 12, 3, 1, c.CENTER, c.HORIZONTAL));
add(progressBar, cs(0, 13, 12, 1, c.CENTER, c.HORIZONTAL));
I thought this might be fixed by changing the helper method cs by adding weightx = gridwidth;
but this still doesn't resolve the problem. What on earth is going on?
The distribution of container width to each child component is determined by weightx. The values you are assigning to gridwidth should be assigned to weightx instead. The gridwidth should be 1 (or REMAINDER) for all of your components.
gridwidth and gridheight do not change the size at which a component is laid out. In particular, a component with gridwidth=2 is not twice as wide as a component with gridwidth=1.
Despite the word "Grid" in the name, a GridBagLayout's cells are not all the same size; they are merely aligned together. If you drew lines to show each cell, a GridBagLayout might look like this:
_________________________________ | | | | (gridy=0) | gridx=1 | gridx=2 |gridx=3| |_________|_______________|_______| | | | | | | | | (gridy=1) | gridx=1 | gridx=2 |gridx=3| | | | | |_________|_______________|_______|
gridwidth/gridheight determine how many of the GridBagLayout's cells are occupied by the component. If you associate gridwidth=2 with a component, but there are no other components in either of the grid columns, the effect will be identical to gridwidth=1, because no other components are driving the widths of the columns. Even though a gridwidth=2 component is two cells wide, those two cells are still only going to be laid out with enough total width to accommodate the component's preferred size.