Hi! I'm having some problems with gridbaglayout trying to get functionality that maybe isn't even there.

The problem is the following

I have 3 Jpanels with differend contents. I want panel 1 to be displayed to the left of the screen filling the y-axis, panel 2 in the middle filling y and panel 3 to the right.

I Want panel 1 to take 1/10 of space in x-direction, panel 2 8/10 and panel 3 1/10 to. So i made these three constraints.

GridBagConstraints c1 = new GridBagConstraints();
        c1.fill = c1.BOTH;
        c1.gridx = 0;
        c1.gridy = 0;
        c1.weightx = 1;
        c1.weighty = 1;
        c1.gridwidth = 1;
        this.add( panel1, c1 );

        GridBagConstraints c2 = new GridBagConstraints();
        c2.fill = c2.BOTH;
        c2.gridx = 1;
        c2.gridy = 0;
        c2.weightx = 1;
        c2.weighty = 1;
        c2.gridwidth = 8;
        this.add( panel2, c2 );

        GridBagConstraints c3 = new GridBagConstraints();
        c3.fill = c3.BOTH;
        c3.gridx = 10;
        c3.gridy = 0;
        c3.weightx = 1;
        c3.weighty = 1;
        c3.gridwidth = 1;
        this.add(panel3, c3 );

Now the problem is that the panels doesn't take up the space i want. Panel1 gets way to big, and then shrink when panel2 is filled with content.

So the question is if there is a way to make gridbaglayout force all grids to be of equal size like gridlayout or should I use another layoutManager. In that case, Which one?

Recommended Answers

All 10 Replies

The weightx and weighty values are doubles, because they are percentages. A weight of 1 means 100%. If you want 10% it should be 0.1

Edit: Remember, though, that if the component needs more space than that in order to be completely displayed it will take that space, so don't, necessarily, expect that those percentages are "set in stone".

yes I know that the weight are percentages. But as you can see panel 2 has a gridwidthx of 8, and I guess i thought that panel2 would take up 8 grids and the rest would take up 1 grid each. But that didnt work.

For now I just set weightx for panel 1 and 3 to zero and then I set the minimum and preffered sizes of those panels to something that works, so panels 1 and 3 will always take up a certain amount of pixels while panel 2 will resize.

What I would like thought is a gridbaglayout that forces the gridsizes on its content just like gridlayout. The question is why it isn't there, GridBagLayout.forceGridSize(boolean b)?

And you have given three columns (0, 1, and 10, and where has column 9 gone, as that is your 10th column since the first column is 0, 10 is the eleventh column) a percentage of 100%, and the remaining became 0% (since you didn't assign one to them), so, obviously, all of the space will be (at best) evenly split between those three columns. So, even that you "know" that the weights are percentages, you seemingly don't know what that means (so I doubt that assertion to begin with). It has nothing to do with the gridwidth. If you want 10 columns all with a width of 0.1 and use gridwidth to "control" component size, then use the columnwieghts property of the layout itself.

gbl.columnWeights = new double[] { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 };

(gbl is the GridBagLayout variable, I don't know what you used as you didn't show it.)

And set c1.wieghtx to 0.0. Also, you can reuse the same GridBagConstraints object. A copy of that object will be made when you use add (at least when using gbl.setConstraints(comp, const) and then add(comp), I'm not sure about add(comp, const) as I don't use that one). There is no reason to create a new GridBagConstraints object every time.

If a component "needs" more space than the "columnWeight" would normally provide, it will still take it, though.

There is no "forceGridSize" as that would make it GridLayout, so use that.

Oh i see that i forgot column 8, not in my code thought. But having gridbaglayout with forced gridsizes wouldn't be the same things as a gridlayout. In a gridlayout you can only place a component in one grid. I was thinking a gridlayout where you can choose to make a component span several grids, but still forcing the grids to be of equal size no matter what the component thinks of it's size, that would be some kind of a combination of gridlayout and gridbaglayout.

I set panel 1s weight to 1 because i thought that all the grids would then have to share an equal amount of space in x-direction. Panel 2 takes up 8 grids in x-direction and the weight is also 1 so i assumed that all those grids would have to be as big as the first grid, but it apparently doesn't work that way.

Well, have you tried the columnWeights suggestion? Does that "fit the bill" for you?

hehe "fit the bill", you make me sound jerky. Well yes I did and the problem is the same, the panels will still take up the minimum amount of space that they need, maybe I could at initialization of all components set their minimum sizes to 0 or something small, but thats a pain in the ass. The layout will only try to divide space even amongst grids. I guess it's a limitation of gridbaglayout.

Yes, I have stated multiple times, that the components will take the minimum (or preferredSize amount of space) space needed to display itself. It might help if you actually showed some more of your code as this works just fine

import java.awt.Color;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class GridBagTest extends JFrame {

	public static final long serialVersionUID = 0L;

	JPanel redPanel, bluePanel, greenPanel;

	GridBagConstraints gbc;
	Container container;

	public static void main (String args[]) {
		GridBagTest gbe = new GridBagTest();
		try { Thread.sleep(2000); } catch (InterruptedException ie) {}
		gbe.setVisible(false);
		gbe.dispose();
	}

	public GridBagTest() {
		setSize (400, 400);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		container = getContentPane();

		redPanel = new JPanel ();
		greenPanel = new JPanel ();
		bluePanel = new JPanel ();
		redPanel.setBackground(Color.RED);
		greenPanel.setBackground(Color.GREEN);
		bluePanel.setBackground(Color.BLUE);

		GridBagLayout gbl = new GridBagLayout();
		container.setLayout(gbl);
		gbc = new GridBagConstraints ();

		AddPanel (redPanel, 0, 1);
		AddPanel (greenPanel, 1, 8);
		AddPanel (bluePanel, 9, 1);

		gbl.columnWeights = new double[] { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 };
		setVisible (true);
	}

	public void AddPanel (JPanel panel, int gridx, int gridwidth) {
		gbc.gridx = gridx;
		gbc.gridy = 0;
		gbc.gridwidth = gridwidth;
		gbc.gridheight = 1;
		gbc.weightx = 0.0;
		gbc.weighty = 1.0;
		gbc.fill = GridBagConstraints.BOTH;
		add(panel, gbc);
	}
}

And seems to do exactly what you're asking.

Yes of course your totally right. But try placing a giant jlabel in redpanel and it will take up more space, just as you said. I think the problem is solved, Thanks you for your help, hope to meet again!

cheers!

Yes, it will, and I don't, myself, consider that a limitation (after all, you do want to see the entire content, don't you?). If you don't want them to take up more space, then place your JPanels into JScrollPanes and place the JScrollPanes into the GBL and let the "additional" content be "scrollable", although you wouls probably not like that either. ;-)

the program I'm writing is for embedded systems with touchscreens so you really want as little scrolling as possible, there are some scrollpanels but with a custom implementation where you have big scrollbuttons and no scrollbar, and you want the content to be really predictable, thats the history of my problem really. It is more important for the middle panel to have a large size rather then the panel to the left of it showing for example the entire labels that are in it, and most important you don't want the panels sizes to change while they get filled with content. So my solution was to set minimum and preferred sizes for the two panels that do not have to be large or even show its entire contents and then set their weights to 0, but you still want everything to take up as much space as possible at the same time so things are easy to click on with you finger etc.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.