sandip chitale's blog    Sandip Chitale's blog (scblog)
NOTE: I have moved many of my modules to NetBeans Plugin Portal . Please check there for latest versions of modules described on this blog.
20060212 Sunday February 12, 2006

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!


Posted by sandipchitale ( Feb 12 2006, 12:50:53 PM PST ) Permalink Comments [2]










« February 2006 »
SunMonTueWedThuFriSat
   
4
5
6
7
8
10
11
14
15
16
17
18
19
21
24
25
27
28
    
       
Today

Get NetBeans 5.5

Locations of visitors to this page

Today's Page Hits: 225


XML
All
/Creator
/General
/Hobby
/Java
/JavaScript
/Mozilla
/NetBeans
/Ubuntu
/VisualWeb
/VisualWebPack
/Web 2.0

XML
All
/Creator
/General
/Hobby
/Java
/JavaScript
/Mozilla
/NetBeans
/Ubuntu
/VisualWeb
/VisualWebPack
/Web 2.0

scblog
scblog