Layouts - Part 7 - GridBag Layout

The GridBagLayout is an extension of the GridLayout in the last tutorial. There are numerous differences however. The size of each cell does not need to be the same size, and widgets can span over more than one cell. The columns and rows in the grid do not need to be the same width or height.

This layout is very useful for sizing things in a GUI, and to let them grow and shrink in a reliable fashion.

Often this LayoutManager is skipped as it can be quite tricky to understand, and with five other LayoutManagers in this section you may be tempted to do this also. Personally I use this Layout as a base in which to place my JPanels full of widgets, rather than a LayoutManager to place widgets themselves. This is suggested by Borland as it is a way of simplifying the design.

The GridBagLayout consists of two things, the actual layout and the constraints.

The Layout is simple, we set the Layout of the JPanel to being a GridBagLayout. No problems there.

The more tricky part is the constraints. Each widget we add to the JPanel must be added with the GridBagConstraints that it uses.
Here is an explanation of the basic ones. There are more complicated constraints but these ones are the most common. To see the constraints I have missed here, have a look at the Swing API

The best way to see how these constraints work is to see an example. This first example takes five coloured boxes and adds them to the GridBag Layout. This will show you how we use the constraints to position the boxes in the cells.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import javax.swing.*;
import java.awt.*;
import java.awt.Color;

public class GridBagLayoutExample{

    public JPanel createContentPane (){

        JPanel totalGUI = new JPanel();

        // We create a JPanel with the GridBagLayout.
        // We also create a GridBagConstraints Object.
        
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        
        // For each item we create to add to the mainPanel...
        
        JPanel red = createSquareJPanel(Color.red, 50);
        
        // We need to define the GridBagConstraints.
        // This defines the widget to go in grid (0,0)
        
        c.gridx = 0;
        c.gridy = 0;
        
        // This tells the widget not to change size
        // to fit the cell. 
        
        c.fill = GridBagConstraints.NONE;
        
        // Once we are happy with the constraints we set.
        // We can add the widget to the JPanel.
        // Remember to add the constraints as the second argument.
        
        mainPanel.add(red, c);
        
        // The constraints we used for the previous one are still in c
        // so we can use them again for the next widget if we wish.
        
        JPanel blue = createSquareJPanel(Color.blue, 60);
        c.gridx = 1;
        // c.gridy = 0 is still set from the previous constraints.
        // c.fill = GridBagConstraints.NONE; is still set too.
        
        mainPanel.add(blue, c);
                
        JPanel green = createSquareJPanel(Color.green, 70);
        c.gridx = 2;
        mainPanel.add(green, c);
        
        JPanel orange = createSquareJPanel(Color.orange, 80);
        c.gridx = 3;
        mainPanel.add(orange, c);
        
        JPanel yellow = createSquareJPanel(Color.yellow, 90);
        c.gridx = 4;
        mainPanel.add(yellow, c);

        // We finish by adding the mainPanel to the totalGUI
        // and returning the JPanel to be set as the content pane.
        
        totalGUI.add(mainPanel);
        totalGUI.setOpaque(true);
        return totalGUI;
    }

    // In this method, we create a square JPanel of a colour and set size
    // specified by the arguments.

    private JPanel createSquareJPanel(Color color, int size)
    {
        JPanel tempPanel = new JPanel();
        tempPanel.setBackground(color);
        tempPanel.setMinimumSize(new Dimension(size, size));
        tempPanel.setMaximumSize(new Dimension(size, size));
        tempPanel.setPreferredSize(new Dimension(size, size));
        return tempPanel;
    }

    private static void createAndShowGUI() {

        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("[=] GridBagLayout [=]");

        GridBagLayoutExample demo = new GridBagLayoutExample();
        frame.setContentPane(demo.createContentPane());
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
GridBagLayout Basic

We instantiate the GridBagLayout in the normal way, and set the layout to GridBagLayout.
After this, we have to create a GridBagConstraints object.
14
15
16
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
We use the GridBagConstraints object c to position the widgets in the grid. Using the attributes we talked about at the start of the section, we set the red panel to be positioned in the first grid, grid 0,0.
25
26
        c.gridx = 0;
        c.gridy = 0;
We also set the constraints of the panel so that the red panel will not resize to fit the entire cell. This is done by setting fill to NONE.
31
        c.fill = GridBagConstraints.NONE;
Once we are happy with the constraints, we add the widget to the JPanel along with the constraints as a second argument.
37
        mainPanel.add(red, c);
When the constraints are used to add a widget to the panel, only a copy is taken. The original constraint object is still available for use and editing without changing the attributes of the previous panel.
So, to put a panel in the second cell, cell (0,1), we can use the same constraints and edit the gridx attribute.
42
43
44
45
46
47
        JPanel blue = createSquareJPanel(Color.blue, 60);
        c.gridx = 1;
        // c.gridy = 0 is still set from the previous constraints.
        // c.fill = GridBagConstraints.NONE; is still set too.
        
        mainPanel.add(blue, c);
We continue this for the other panels. Notice that when the program is run, the boxes are positioned together. This is because the size of each cell can be different. The height of the row is taken from the tallest widget in the row. The width of the column is taken from the widest widget in the column.

Now let's have an example to see the other attributes at work. This example uses all of the other attributes mentioned at the start.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import javax.swing.*;
import java.awt.*;
import java.awt.Color;

public class GridBagLayoutExample_Extended{

    public JPanel createContentPane (){

        JPanel totalGUI = new JPanel();

        // We create a JPanel with the GridBagLayout.
        // We also create a GridBagConstraints Object.
        
        JPanel mainPanel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        
        // For each item we create to add to the mainPanel
        // we set constraints. 
        // This one is cell (0,0) and will not resize.
        
        JPanel red = createSquareJPanel(Color.red, 80);
        c.gridx = 0;
        c.gridy = 0;       
        c.fill = GridBagConstraints.NONE;      
        mainPanel.add(red, c);        
        
        // This one is cell (1,0) and will not resize.
        JPanel blue = createSquareJPanel(Color.blue, 80);
        c.gridx = 1;      
        mainPanel.add(blue, c);
        
        // This one is cell (2,0).
        // This should be a 40x40 square, but we set it to
        // stretch on the vertical.
        JPanel orange = createSquareJPanel(Color.orange, 40);
        c.gridx = 2;
        c.fill = GridBagConstraints.VERTICAL;
        mainPanel.add(orange, c);

        // This starts in cell (3,0)
        // but covers (3, 1) and (3,2) as it's height is 3.
        // This will stretch right down to the bottom because
        // the fill is still set to vertical.
        JPanel pink = createSquareJPanel(Color.pink, 80);
        c.gridx = 3;
        c.gridheight = 3;
        mainPanel.add(pink, c);

        // This one is in cell (0, 1)
        // It is now a simple green square.
        JPanel green = createSquareJPanel(Color.green, 80);
        c.gridx = 0;
        c.gridy = 1;
        c.gridheight = 1;
        c.fill = GridBagConstraints.NONE;
        mainPanel.add(green, c);
               
        // This one is cell (0,2).
        // This should be a 40x40 square, but we set it to
        // stretch on the horizontal.
        JPanel yellow = createSquareJPanel(Color.yellow, 40);
        c.gridy = 2;
        c.fill = GridBagConstraints.HORIZONTAL;
        mainPanel.add(yellow, c);
        
        // This starts in cell (0,3)
        // but covers (1,3) and (2,3) as it's width is 3.
        // This will stretch right along to the side because
        // the fill is still set to horizontal.
        JPanel cyan = createSquareJPanel(Color.cyan, 80);
        c.gridy = 3;
        c.gridwidth = 3;
        mainPanel.add(cyan, c);
        
        // This will place a JPanel at the bottom corner, small and positioned
        // to first_line_start in cell (3,3).  
        JPanel black = createSquareJPanel(Color.black, 40);
        c.gridx = 3;
        c.gridwidth = 1;
        c.anchor = GridBagConstraints.FIRST_LINE_START;
        c.fill = GridBagConstraints.NONE;
        mainPanel.add(black, c);
        
        // This sets a gray JPanel in the middle.
        // it covers (1,1), (1,2), (2,1) and (2,2) because 
        // of it's width and height.
        // We center it using the anchor.
        // Then make it larger by padding it out by 40px on the
        // vertical and horizontal (20px each side).
        JPanel gray = createSquareJPanel(Color.gray, 40);
        c.gridx = 1;
        c.gridy = 1;
        c.gridheight = 2;
        c.gridwidth = 2;
        c.anchor = GridBagConstraints.CENTER;
        c.ipadx = 40;
        c.ipady = 40;
        mainPanel.add(gray, c);
        
        // We finish by adding the mainPanel to the totalGUI
        // and returning the JPanel to be set as the content pane.
        
        totalGUI.add(mainPanel);
        totalGUI.setOpaque(true);
        return totalGUI;
    }

    // In this method, we create a square JPanel of a colour and set size
    // specified by the arguments.

    private JPanel createSquareJPanel(Color color, int size)
    {
        JPanel tempPanel = new JPanel();
        tempPanel.setBackground(color);
        tempPanel.setMinimumSize(new Dimension(size, size));
        tempPanel.setMaximumSize(new Dimension(size, size));
        tempPanel.setPreferredSize(new Dimension(size, size));
        return tempPanel;
    }

    private static void createAndShowGUI() {

        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("[=] GridBagLayout [=]");

        GridBagLayoutExample_Extended demo = new GridBagLayoutExample_Extended();
        frame.setContentPane(demo.createContentPane());
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
GridBagLayout Extended

This uses more of the attributes to create a far more complex design. Instead of picturing these panels as widgets, think of them as panels of widgets. Pink might be all your external links, black might be the corporate logo, red might be the area you login etc.

The comments in the second segment of code are there to help you. Just remember, if you set an attribute in the constraints for one widget, they will all remain as that until you set them to something else. Don't go making all your widgets fill vertically because you forgot to change it back! (Not that it happened to me, obviously.)

Exercises

In this exercise, you have to fix/modify the given code to make buttons look like a calculator.

You can get the code here -> Example Code

When run, all the buttons start in a FlowLayout (the Default) so fill the screen from Left to Right.
Your task is to modify the code with new Layouts, Panels, setPreferredSize() or whatever you wish to make it look like a proper calculator.

For an extra challenge, do not use the same layout manager twice!

There is no need to make Action Listeners, or make the Calculator work, just edit the position of the current widgets.

Here are some examples of what you can attempt to do...

Traffic Lights

Questions

GridBagLayout questions...is it your Bag? (baby! yeah!)

Question 1. Which attributes set the grid location?

  • a) gridx, gridy
  • b) cellx, celly
  • c) posx, posy

Question 2. If you add padding to a widget (using ipadx and ipady), how is the padding placed?

  • a) All at one side.
  • b) Half on one side, half on the other.
  • c) quarter one one side, quarter on the other.

Question 3. How do we add a widget to a JPanel with GridBagLayout?

  • a) add(constraints, widget);
  • b) add(widget, constraints);
  • c) add(widget.(constraints));




Back Top Next
Email Me
Code Style


Required Lessons

External Links

Created and Edited by Stuart Davidson
All Rights Reserved ©

Valid XHTML 1.0 Strict