GridBagLayout simplified ?

The java.awt.GridBagLayout has a (dis)reputation of being a complex layout manager. This funny flash animation is a testament to that.

IMHO this is partly due to the following factors:

All of this makes the code complex and long. I have written a simple class GridBagHelper to manage the complexity of the layout code and make it compact.
/\*\*
 \*
 \* Author: Sandip Chitale (Sandip.Chitale@Sun.Com)
 \*/
import java.awt.\*;
import java.awt.event.\*;

/\*\*
 \*
 \* This helps manage and organize the <code>GridBagLayout</code> code.
 \*
 \* For example:
 \* 
 \* The following table is based on the Scott Stanchfield's (Swing course instructor)
 \* tip for taming the GridBagLayout. The only difference is that the row
 \* and column from his tip are transposed. i.e. the constraints are in a row
 \* and components go downwards.
 \*
 \* <code>
 \* <pre>
JLabel     entryLabel  = new JLabel("Entry");
JButton    browse      = new JButton("Browse...");
JTextField entry       = new JTextField();
JButton    add         = new JButton("Add");
JLabel     entriesLabel= new JLabel("Entries");
JButton    delete      = new JButton("Delete");
JList      entries     = new JList();
JButton    modify      = new JButton("Modify");
JButton    moveUp      = new JButton("Move Up");
JButton    moveDown    = new JButton("Move Down");

// Non last rows insets
Insets    i  = new Insets(5,5,0,0);
// last row insets
Insets    ir = new Insets(5,5,5,0);
// last col insets
Insets    ic = new Insets(5,5,0,5);
// last row,col insets
Insets    irc= new Insets(5,5,5,5);

GridBagHelper gbh[] = {
//____________________________________________________________________________________________________________________________________
//                            |    |    |     |      |   |   |                            |                             |     |   |
//                  Component | col| row|     |      |wt |wt |        anchor              |            fill             |insts|pad|pad 
//                            |  x |  y |width|height| x | y |                            |                             |     | x | y
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(entryLabel  , 0  , 0  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.NONE      , i   , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(browse      , 1  , 0  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, ic  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(entry       , 0  , 1  , 1   , 1    , 1 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, i   , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(add         , 1  , 1  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, ic  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(entriesLabel, 0  , 2  , 1   , 1    , 1 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.NONE      , i   , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(delete      , 1  , 2  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, ic  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(entries     , 0  , 3  , 1   , 3    , 0 , 1 ,GridBagConstraints.NORTHWEST,GridBagConstraints.BOTH      , ir  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(modify      , 1  , 3  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, ic  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(moveUp      , 1  , 4  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, ic  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(moveDown    , 1  , 5  , 1   , 1    , 0 , 1 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, irc , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
};

Panel mainPanel = new Panel();

GridBagHelper.createGUI(mainPanel, gbh); 
 \* </pre>
 \* </code>
 \* <p>
 \* @author Sandip Chitale (Sandip.Chitale@Sun.Com)
 \* @see GridBagLayout
 \* @see GridBagConstraints
 \*
 \*/
public class GridBagHelper
{
    private Component         component;
    private GridBagConstraints gbc;

    /\*\*
     \* Create an instance for a component and its constraints
     \*
     \* @param component  the component for which the following constraints apply
     \* @param gridx      the cell column
     \* @param gridy      the cell row
     \* @param gridwidth  the number of columns spanned  
     \* @param gridheight the number of rows spanned
     \* @param weightx    the ratio of horzontal expansion
     \* @param weighty    the ratio of vertical expansion 
     \* @param anchor     the point in the cell where the component gravitates N, NE, E, SE, S, SW, W, NW, C
     \* @param fill       the direction in which the component fills the cell NONE, HORIZONTAL, VERTICAL, BOTH
     \* @param insets     the margins around the component
     \* @param ipadx      the horizontal padding between cells
     \* @param ipady      the vertical padding between cells
     \*/
    public GridBagHelper(Component component
                         ,int gridx
                         ,int gridy
                         ,int gridwidth
                         ,int gridheight
                         ,double weightx
                         ,double weighty
                         ,int anchor
                         ,int fill
                         ,Insets insets
                         ,int ipadx
                         ,int ipady
                         )
    {
        this.component = component;
        gbc = new GridBagConstraints();
        gbc.gridx = gridx;
        gbc.gridy = gridy;
        gbc.gridwidth = gridwidth;
        gbc.gridheight = gridheight;
        gbc.weightx = weightx;
        gbc.weighty = weighty;
        gbc.anchor = anchor;
        gbc.fill = fill;
        gbc.insets = insets;
        gbc.ipadx = ipadx;
        gbc.ipady = ipady;    
    }

    /\*\*
     \* createGUI - adds the components with suitable constraints.
     \*
     \* @param c a value of type 'Container'
     \* @param gbh[] a value of type 'GridBagHelper'
     \*/
    public static void createGUI(Container c, GridBagHelper gbh[])
    {
        c.setLayout(new GridBagLayout());
        for (int i = 0; i < gbh.length;i++){
            c.add(gbh[i].component, gbh[i].gbc);
        }
    }
}
I use a simple algorithm to deal with the layout using GridBagHelper class above.
  • Create the containing panel p.
  • Sketch out a grid in which components will be added.
  • Create all the required components.
  • Create insets. I use a value of 5 pixels. However this should be controlled by the look and feel guidelines you follow.
    • Insets i = new Insets(5,5,0,0); - for cells that do not touch the right or bottom edge of the grid
    • Insets ir = new Insets(5,5,5,0); - for cells that the bottom edge of the grid (i.e. last row cells).
    • Insets ic = new Insets(5,5,0,5); - for cells that touch the right edge of the grid (i.e. last column cells).
    • Insets irc= new Insets(5,5,5,5); - for cells that touch the right and bottom edge of the grid (i.e. last row and column cell).
  • Start with empty table:
GridBagHelper gbh[] = {
//____________________________________________________________________________________________________________________________________
//                            |    |    |     |      |   |   |                            |                             |     |   |
//                  Component | col| row|     |      |wt |wt |        anchor              |            fill             |insts|pad|pad 
//                            |  x |  y |width|height| x | y |                            |                             |     | x | y
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
};
  • For each component c:
    • Create a row:
new GridBagHelper(            ,    ,    ,     ,      ,   ,   ,                            ,                             ,     ,   , ),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
    • Add component reference c under Component column.
    • Enter the cell column number in the col x column
    • Enter the cell row number in the row y column.
    • How many columns cells does the component span. Enter that value in width column. This may affect the col x number of the components to the right.
    • How many row cells does the component span. Enter that value in height column. This may affect the row y number of the components to the below.
    • When the containing panel is resized should the changes in width affect this component's width and to what proportion. Enter that value in wt x column.
    • When the containing panel is resized should the changes in height affect this components height and to what proportion. Enter that value in wt x column. Note: This is affected by how the fill contraint.
    • How will the component be aligned vertically and horizontally in the cell. I mostly use GridBagConstraints.NORTHWEST.
    • Should the component be stretched to fill the cell
      • if the answer is no  enter the value GridBagConstraints.NONE in fill column.
      • if the answer is horizontally enter the value GridBagConstraints.HORIZONTAL in fill column.
      • if the answer is vertically enter the value GridBagConstraints.VERTICAL in fill column.
      • if the answer is horizontally  and vertically enter the value GridBagConstraints.BOTH in fill column.
    • Enter the inset reference in the insts column based on the position of the cell in the grid. See the insets creation step above.
    • Enter any padding in pad x and pad y columns
  • Some times it is necessary to add two panel - one in the last column and one in the last row with the following constraints to force the layout to move to north west.
    • wt x = 1.0
    • wt y = 1.0
    • anchor = GridBagConstraints.NORTHWEST
    • fill = GridBagConstraints.BOTH
  • Now do the layout by calling
GridBagHelper.createGUI(p, gbh);

Thats all. I hope this will you make use of the powerful GridBagLayout to layout your GUI panels. Enoy!

Comments:

certainly makes it a bit shorter, thanks!

Posted by codecraig on May 18, 2006 at 12:54 AM PDT #

Great post and draw. Thank you for sharing.!!@!

Posted by links of london on November 25, 2009 at 10:40 AM PST #

Post a Comment:
Comments are closed for this entry.
About

sandipchitale

Search

Archives
« May 2015
SunMonTueWedThuFriSat
     
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
      
Today