Hello, since I have realised how little I have understood of the GridBagLayout, I thought I'd open a thread where I could clarify one by one all my doubts.
I have produced a very small and simple GUI which I will use to test the GridBagLayout and ask questions as they arise. The GUI has only a bunch of buttons at the moment but I will update it
as I go along.
So this is the code:

/*TestingGridBag.java*/
import java.awt.GridBagLayout;//chosen JFrame layout
import static java.awt.GridBagConstraints.*;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;//for radio buttons

public class TestingGridBag extends JFrame{
private GridBagLayout layout;
//private JPanel panel;
private JButton okButton;
private JButton cancelButton;
private JButton submitButton;
private JButton test1Button;
private JButton test2Button;

public TestingGridBag(){
super("GridBagLayout test");
layout = new GridBagLayout();
setLayout( layout );//set layout of JFrame

//panel = new JPanel();
okButton = new JButton("OK");
cancelButton = new JButton("Cancel");
submitButton = new JButton("Submit");
test1Button = new JButton("test1");
test2Button = new JButton("test2");

add( okButton, new GridBagConstraints( 0, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );
add( cancelButton, new GridBagConstraints( 1, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );
add( submitButton, new GridBagConstraints( 2, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );
add( test1Button, new GridBagConstraints( 3, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );
add( test2Button, new GridBagConstraints( 4, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );

}//end constructor


}//end of class

and the test class:

/*TestingGridBagTest.java*/
import javax.swing.JFrame;
import java.awt.Dimension;
public class TestingGridBagTest{
public static void main( String[] args ){
TestingGridBag testingGridBag = new TestingGridBag();
testingGridBag.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
testingGridBag.setVisible( true );
Dimension minimumSize = new Dimension( 400, 200 );
testingGridBag.setMinimumSize( minimumSize );
testingGridBag.pack();
}
}

that produces this:
3bdc5dc95d82c6fa5e430679d8119a47

Most of the options are zero, this will hopefully allow me to play with them quite a bit.
Needless to say I had a look on the net before asking and the reason why I post a question is either because I didn't find anything or because what I found makes no sense to me. SO here you are:
1)First some general notions on the GridBagLayout. This layout is supposed to divide the GUI in some sort of grid. In a previous exercise, I was told that the best thing to start with is to actually draw a grid on the GUI I would like to produce.
Now, when I decide how many rows and columns I want, is there a way to specify somewhere that the grid should be, say, 6x6, or 7x10 and so on? If not is it fair to say that a grid is as big as the components I decide to add in? This
altough it might sound silly, I think is very important. And here is the reason. Say that my grid is 5x5 with only 9 components in it so that they are nicely distributed in it in this fashion:
6820bcbc87a6f8b94ddd1f35aabfdfa2
with an empty cell that separate each component. Is this a good way to think of a GridBagLayout grid? From what I understand it might not be because rather than using empty cells to create space we should do it with padding.
2)insets.
The insets are supposed to specify the space that the container must leave. Now, is it supposed to work like padding? I mean from what I understand the values of the insets are: new Insets(int bottom, int left, int right, int top)
So if I do something like new Insets( 10, 0, 0, 0 ) shouldn't that value of 10 added at the bottom of the component or have I got this all thing wrong? The reason why I asked is because in my demo here is the amended code:

add( okButton, new GridBagConstraints( 0, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 10, 0, 0, 0), 0, 0 ) );
add( cancelButton, new GridBagConstraints( 1, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );
...

the first button is shifted downards as if the space was added at the top and I expected it to be added at the bottom instead 60b4e3ca04b7388f5b602dc6541c1442 :

There. I think this is a good start.

Recommended Answers

All 16 Replies

Excellent Questions!

The constructor for Insets is
Insets(int top, int left, int bottom, int right)
(source: API doc)
so you added 10 at the top.

Re your 5x5 grid... yes you can put your components into non-contiguous cells, but if you leave a whole row or column empty its height or width will be zero. In other words the height of a row is the height (plus insets) of the tallest component in that row, similarly for width of columns

The constructor for Insets is

Ah, I see, not sure where I got the wrong order of the parameters from. That explains everything.

Re your 5x5 grid... yes you can put your components into non-contiguous cells

But is there an explicit way to specify that a cell should be empty or do I simply not include its coordinates in the constructor?
Also, has anybody ever come up with some kind of GridBagLayout "box model" - a bit like the CSS box model - to clarify where internal padding and external padding are located? I mean a graphical representation of it, that would be awsome!

is there an explicit way to specify that a cell should be empty

Not that I know of. Just don't put anything in it!
SOmetimes I have had dynamic form contents where I have (eg) added buttons at 1,0 2.0 and 999,0 so I can later add buttons after the first two, but before the last one. The unused columns just get a zero width.

I don't know of such a diagram, but the insets in GBL goes between the grid lines and the component. Any internal padding of the component is part of the component, and GBL doesn't need to know about it.

Cool Ok thanks.

Not that I know of. Just don't put anything in it!

I would have thought that if a cell is empty then its width would be 0 pretty much like an empty column if you like.

Alright, so I am working with GBL's too and I just came across this post which is perfect timing I guess.
Quick question about the insets, can you add a negative value to bring the cell closer to the next or one previous?
Also, is it better to declare the GridBagConstraints as new GridBagConstraints( 1, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) or like

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;
gbc.gridy = 1;

as an example?

  1. I don't believe you can use negative insets... has anyone tried it?
    You can get components to touch by aligning them with the appropriate edge of their grid and having a zero inset.

  2. The two ways of writing the constraints are interchangeable, and a matter of personal preference (unless site standards say otherwise!). Personally I prefer the first version because all the info is there on one line so I don't have to search up through preceeding code to see if any odd constraint values have been set.

Member Avatar for iamthwee

Any particular reason why you're not using a GUI builder?

iamthwee, as far as I am concerned I want to learn how to use the layout managers although I have to say that I am not a programmer so I find extremely hard to grasp concepts that for a programmer are instead obvious. Using a GUI builder will be much easier I am sure, especially for me, but then I will have absolutely no clue as to how things happen. I am not trying to get to a point that I can master all the possible layouts, but I came to realize (ahem!) that the GridBagLayout is extremely useful and powerful (and I'd throw in complicated too) and therefore I think that as a beginner java developer I must learn to use it, at least the basics.

Any particular reason why you're not using a GUI builder?

Personally I find it easier and quicker to make a quick sketch on paper or in my head, then copy/paste add method calls with all the constraints right there in the call. I also end up with code that I understand and can modify for special needs.

Member Avatar for iamthwee

Sure personal preference is personal preference, but when you have the tools at hand why not simply use them. Of course there is no harm in trying to understanding the deeper mechanisms of how things work.

I've been following a few of the OP's threads and I've notice a tendancy to build things from scratch. Like opting to build a responsive layout when there are frameworks at hand that take care of everything. The reason given when asked was - 'I want to learn' well that's fine.

But these tools/frameworks and absolutely necessary when developing fast and robust views. In fact for newbies I'd recommend starting with a gui builder and then later going back to figure out the mechanisms if needed.

My 2p.

I don't disagree with you at all, but I doubt I will ever develop something big. That said, I hope to learn the basics of layout (which will involve doing things from scratch) and then perhaps moving a GUI.

Right, another question.
Just to pick up on something said before about a cell being empty in the layout:

Not that I know of. Just don't put anything in it!
SOmetimes I have had dynamic form contents where I have (eg) added buttons at 1,0 2.0 and 999,0 so I can later add buttons after the first two, but before the last one. The unused columns just get a zero width.

I thought I'd replicate this layout now:
c74171e15b0fbe52c7a8b9d19542064d
So I changed my code accordingly:

 add( okButton, new GridBagConstraints( 0, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );
add( cancelButton, new GridBagConstraints( 2, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );
add( submitButton, new GridBagConstraints( 4, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );
add( test1Button, new GridBagConstraints( 6, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );
add( test2Button, new GridBagConstraints( 8, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );

I have modified the coordinates in an attempt to produce an empty cell between the buttons, but nothing gets displayed. Now, I assume this happens because, as it has been pointed out before, the width of an empty column (and in this case having only one row the empty cell effectively represents a column) is 0. So how do I get around this? SHould I use the inset values perhaps?
thanks

Inset values are one way. You can also add an "invisible" JLabel into one of the empty columns to make it >0 width. eg

        JLabel padding = new JLabel();
        padding.setPreferredSize(new Dimension(40,10));

or you could use a

         Box.createRigidArea(new Dimension(40,10))

I am finally back after quite some time, and unfortunately I have lost quite a bit of what I have learned...
Anyway, I went back through my notes and old posts and messed around with the GridBagConstraints again, and I have a few questions.
This is the latest version of a 5x1 grid of buttons (screenshot attached a13ff6405069e860bd5ae6f43e5798f3 )

/*TestingGridBag.java*/
import java.awt.GridBagLayout;//chosen JFrame layout
import static java.awt.GridBagConstraints.*;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;//for radio buttons

public class TestingGridBag extends JFrame{
    private GridBagLayout layout;
    //private JPanel panel;
    private JButton okButton;
    private JButton cancelButton;
    private JButton submitButton;
    private JButton test1Button;
    private JButton test2Button;

    public TestingGridBag(){
        super("GridBagLayout test");
        layout = new GridBagLayout();
        setLayout( layout );//set layout of JFrame

        //panel = new JPanel();
        okButton = new JButton("OK");
        cancelButton = new JButton("Cancel");
        submitButton = new JButton("Submit");
        test1Button = new JButton("test1");
        test2Button = new JButton("test2");

        add( okButton, new GridBagConstraints( 0, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 20), 0, 0 ) );
        add( cancelButton, new GridBagConstraints( 2, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 20), 0, 0 ) );
        add( submitButton, new GridBagConstraints( 4, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 20), 0, 0 ) );
        add( test1Button, new GridBagConstraints( 6, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 20), 0, 0 ) );
        add( test2Button, new GridBagConstraints( 8, 0, 1, 1, 0, 0, CENTER, NONE, new Insets( 0, 0, 0, 0), 0, 0 ) );

    }//end constructor


}//end of class

I am not entirely sure what it is that allows the buttons to be vertically aligned in the middle. I checked the API and I thought it would be the anchor parameter, but when I changed it from CENTER to any other value (I tried NORTH and SOUTH) I didn't notice any difference, so I was wondering how that is. Also, I would like to make a few changes to the above and have each button on each corner of the window (top right, top left, bottom left, bottom right and one in the middle), so I guess for that to happen each button should be inside its own JPanel?
thanks

Hi, welcome back!
The CENTER spec you are using centers the buttons vertically. NORTH or SOUTH should move them up/down, but note this:
"Unless you specify at least one non-zero value for weightx or weighty, all the components clump together in the center of their container. This is because when the weight is 0.0 (the default), the GridBagLayout puts any extra space between its grid of cells and the edges of the container." http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html

The corners/center layout can be achieved with a 3x3 grid, using cells 0,0 0,2 1,1 2,0 2,2 with appropriate anchoring on each of those cells

OK cool, thanks I will give it a go!

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.