Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 

Swing Chapter 4. (The basics) Layout Managers. Easy for reading, Click here!

Custom Search
Swing Chapter 4. (The basics) Layout Managers. Easy for reading, Click here!

[ Return to Swing (Book) ]

Page: 3/7 



Previous Page Previous Page (2/7) - Next Page (4/7) Next Page
Subpages: 1. Layouts overview 
2. Comparing common layout managers
3.
Using GridBagLayout
4. Choosing the right layout
5. Custom layout manager: part I -Label/field pairs
6. Custom layout manager: part II - Common interfaces
7. Dynamic layout in a JavaBeans container

4.3    Using GridBagLayout

...by James Tan, Systems Analyst, United Overseas Bank Singapore, jamestan@earthling.net

Of all the layouts included with Swing and AWT, GridBagLayout is by far the most complex. In this section, we will walk through the various constraints attributes it relies on, along with several short examples showing how to use them. We follow up this discussion with a comprehensive input dialog example putting together all these attributes. We then conclude this section with the construction and demonstration of a helper class designed to make using GridBagLayout more convenient.

4.3.1    Default behavior of GridBagLayout

By simply setting a container's layout to a GridBagLayout and adding Components to it, the result will be a row of components, each set to their preferred size, tightly packed and placed in the center of the container. Unlike FlowLayout, GridBagLayout will allow components to be clipped by the edge of the managing container, and it will not move child components down into a new row. The following code demonstrates, and figure 4.4 shows the result:

  JInternalFrame fr1 = new JInternalFrame(

    "Example 1", true, true );

  fr1.setBounds( 5, 5, 270, 100 );

  cn = fr1.getContentPane();

  cn.setLayout( new GridBagLayout() );

  cn.add( new JButton( "Wonderful" ) );

  cn.add( new JButton( "World" ) );

  cn.add( new JButton( "Of" ) );

  cn.add( new JButton( "Swing !!!" ) );

  desktop.add( fr1, 0 );

Figure 4.4 Default GridBagLayout behaviour

<<figure4-4.gif>>

4.3.2    Introducing GridBagConstraint

When a component is added to a container which has been assigned a GridBagLayout, a default GridBagConstraints object is used by the layout manager to place the component accordingly, as in the above example. By creating and setting a GridBagConstraints' attributes and passing it in as an additional parameter in the add() method, we can flexibly manage the placement of our components.

Below are the various attributes we can set in a GridBagConstraints object along with their default values. The behaviour of these attributes will be explained in the examples that follow.

  public int gridx = GridBagConstraints.RELATIVE;

  public int gridy = GridBagConstraints.RELATIVE;

  public int gridwidth = 1;

  public int gridheight = 1;

  public double weightx = 0.0;

  public double weighty = 0.0;

  public int anchor = GridBagConstraints.CENTER;

  public int fill = GridBagConstraints.NONE;

  public Insets insets = new Insets( 0, 0, 0, 0 );

  public int ipadx = 0;

  public int ipady = 0;

4.3.3    Using the gridx, gridy, insets, ipadx and ipady constraints

The gridx and gridy constraints (or column and row constraints) are used to specify the exact grid cell location where we want our component to be placed. Components placement starts from the upper left corner of the container, and gridx and gridy begin with values of 0. Specifying negative values for either of these attributes is equivalent to setting them to GridBagConstraints.RELATIVE, which means that the next component added will be placed directly after the previous gridx or gridy location.

The insets constraint adds an invisible exterior padding around the associated component. Negative values can be used which will force the component to be sized larger than the cell it is contained in.

The ipadx and ipady constraints add an interior padding which increases the preferred size of the associated component. Specifically,it adds ipadx * 2 pixels to the preferred width and ipady * 2 pixels to the preferred height (* 2 because this padding applies to both sides of the component).

In this example we place the "Wonderful" and "World" buttons in the first row and the other two buttons in the second row. We also associate insets with each button so they don't look too cluttered, and they vary in both height and width.

  JInternalFrame fr2 = new JInternalFrame("Example 2", true, true );

  fr2.setBounds( 5, 110, 270, 140 );

  cn = fr2.getContentPane();

  cn.setLayout( new GridBagLayout() );

  c = new GridBagConstraints();

  c.insets = new Insets( 2, 2, 2, 2 );

  c.gridx = 0;   // column 0

  c.gridy = 0;   // row 0

  c.ipadx = 5;   // increases component width by 10 pixels

  c.ipady = 5;   // increases component height by 10 pixels

  cn.add( new JButton( "Wonderful" ), c );

  c.gridx = 1;   // column 1

  c.ipadx = 0;   // reset the padding to 0

  c.ipady = 0;

  cn.add( new JButton( "World" ), c );                               

  c.gridx = 0;   // column 0

  c.gridy = 1;   // row 1

  cn.add( new JButton( "Of" ), c );                                  

  c.gridx = 1;   // column 1

  cn.add( new JButton( "Swing !!!" ), c );                            

  desktop.add( fr2, 0 );

We begin by creating a GridBagConstraints object to set the constraints for the first button component. We pass it in together with the button in the add() method. We reuse this same constraints object by changing the relevant attributes and passing in again for each remaining component. This conserves memory and also relieves us of having to reassign a whole new group of attributes. Figure 4.5 shows the result.

Figure 4.5 Using the gridx, gridy, insets, ipadx and ipady constraints.

<<figure4-5.gif>>

4.3.4    Using weightx and weighty constraints

When the container in the above example is resized, the components respect the constraints we have assigned, but the whole group remains in the center of the container. Why don't the buttons grow to occupy a proportional amount of the increased space surrounding them? The answer lies in the use of the weightx and weighty constraints, which both default to zero when GridBagConstraints is instantiated.

These two constraints specify how any extra space in a container should be distributed among each component's cell. The weightx attribute is used to specify the fraction of extra horizontal space to occupy. Similarly, weighty is used to specify the fraction of extra vertical space to occupy.  Both constraints can be assigned values ranging from 0.0 to 1.0.

For example, lets say we have two buttons, A and B, placed in columns 0 and 1 of row 0 respectively. If we specify weightx = 1.0 for the first button and weightx = 0 for the second button, when we resize the container, all extra space will be distributed to the first button's cell -- 50% on the left of the button and 50% on the right. The other button will be pushed to the right of the container as far as possible. Figure 4.6 illustrates.

Figure 4.6 weightx and weighty constraints.

<<figure4-6.gif>>

Getting back to our "Wonderful" "World" "Of" "Swing !!!" example, we now modify all button cells to share any extra container space equally as the container is resized. Specifying weightx = 1.0 and weighty = 1.0, and keeping these attributes constant as each component is added, will tell GridBagLayout to use all available space for each cell.

  JInternalFrame fr3 = new JInternalFrame("Example 3", true, true );

  fr3.setBounds( 5, 255, 270, 140 );                                 

  cn = fr3.getContentPane();                                         

  cn.setLayout( new GridBagLayout() );                               

  c = new GridBagConstraints();                                      

  c.insets = new Insets( 2, 2, 2, 2 );                               

  c.weighty = 1.0;

  c.weightx = 1.0;                                                   

  c.gridx = 0;                                                       

  c.gridy = 0;                                                       

  cn.add( new JButton( "Wonderful" ), c );                           

  c.gridx = 1;                                                       

  cn.add( new JButton( "World" ), c );                               

  c.gridx = 0;                                                       

  c.gridy = 1;                                                       

  cn.add( new JButton( "Of" ), c );                                  

  c.gridx = 1;                                                       

  cn.add( new JButton( "Swing !!!" ), c );                           

  desktop.add( fr3, 0 );

Figure 4.7 Using weightx and weighty constraints.

<<figure4-7.gif>>

4.3.5    Using gridwidth and gridheight constraints

GridBagLayout also allows us to span components across multiple cell using the gridwidth and gridheight constraints. To demonstrate we modify our example to force the "Wonderful" button to occupy 2 rows and the "World" button to occupy 2 columns. Figure 4.8 illustrates. Note that occupying more cells forces more rows and/or columns to be created based on current container size.

  JInternalFrame fr4 = new JInternalFrame("Example 4", true, true );

  fr4.setBounds( 280, 5, 270, 140 );                                 

  cn = fr4.getContentPane();                                         

  cn.setLayout( new GridBagLayout() );                               

  c = new GridBagConstraints();                                      

  c.insets = new Insets( 2, 2, 2, 2 );                               

  c.weighty = 1.0;                                                   

  c.weightx = 1.0;                                                   

  c.gridx = 0;                                                       

  c.gridy = 0;                                                       

  c.gridheight = 2; // span across 2 rows

  cn.add( new JButton( "Wonderful" ), c );  

  c.gridx = 1;                                                       

  c.gridheight = 1; // remember to set back to 1 row

  c.gridwidth = 2; // span across 2 columns

  cn.add( new JButton( "World" ), c );                               

  c.gridy = 1;                                                       

  c.gridwidth = 1; // remember to set back to 1 column

  cn.add( new JButton( "Of" ), c );                                  

  c.gridx = 2;                                                       

  cn.add( new JButton( "Swing !!!" ), c );                           

  desktop.add( fr4, 0 );

Figures 4.8 Using gridwidth and gridheight constraints.

<<figure4-8.gif>>

4.3.6    Using anchor constraints

We can control how a component is aligned within its cell(s) by setting the anchor constraint. By default this is set to GridBagConstraints.CENTER, which forces the component to be centered within its occupied cell(s). We can choose from the following anchor settings:

  GridBagConstraints.NORTH

  GridBagConstraints.SOUTH

  GridBagConstraints.EAST

  GridBagConstraints.WEST

  GridBagConstraints.NORTHEAST

  GridBagConstraints.NORTHWEST

  GridBagConstraints.SOUTHEAST

  GridBagConstraints.SOUTHWEST

  GridBagConstraints.CENTER

Below we've modified our example to anchor the "Wonderful" button NORTH and the "World" button SOUTHWEST. The "Of" and "Swing !!!" buttons are achored in the CENTER of their cells. Figure 4.9 illustrates.

  JInternalFrame fr5 = new JInternalFrame("Example 5", true, true );

  fr5.setBounds( 280, 150, 270, 140 );                               

  cn = fr5.getContentPane();                                         

  cn.setLayout( new GridBagLayout() );                               

  c = new GridBagConstraints();                                      

  c.insets = new Insets( 2, 2, 2, 2 );                               

  c.weighty = 1.0;                                                   

  c.weightx = 1.0;                                                   

  c.gridx = 0;                                                       

  c.gridy = 0;                                                        

  c.gridheight = 2;                                                  

  c.anchor = GridBagConstraints.NORTH;

  cn.add( new JButton( "Wonderful" ), c );                           

  c.gridx = 1;                                                       

  c.gridheight = 1;                                                  

  c.gridwidth = 2;                                                   

  c.anchor = GridBagConstraints.SOUTHWEST;

  cn.add( new JButton( "World" ), c );                               

  c.gridy = 1;                                                       

  c.gridwidth = 1;                                                   

  c.anchor = GridBagConstraints.CENTER;

  cn.add( new JButton( "Of" ), c );                                  

  c.gridx = 2;                                                       

  cn.add( new JButton( "Swing !!!" ), c );                           

  desktop.add( fr5, 0 );

Figure 4.9 Using gridwidth and gridheight constraints.

<<figure4-9.gif>>

4.3.7    Using fill constraints

The most common reason for spanning multiple cells is because we want the component contained in that cell to occupy this enlarged space. To do this we use the gridheight/gridwidth constraints as described above, as well as the fill constraint. The fill constraint can be assigned any of the following values:

  GridBagConstraints.NONE

  GridBagConstraints.HORIZONTAL

  GridBagConstraints.VERTICAL

  GridBagConstraints.BOTH

Below we modify our example to force the "Wonderful" button to occupy all available cell space, both vertically and horizontally. The "World" button now occupies all available horizontal cell space, but continues to use its preferred vertical size. The "Of" button does not make use of the fill constraint and simply uses its preferred size. The "Swing !!!" button occupies all available vertical cell space, but uses its preferred horizontal size. Figure 4.10 illustrates.

  JInternalFrame fr6 = new JInternalFrame("Example 6", true, true );

  fr6.setBounds( 280, 295, 270, 140 );                               

  cn = fr6.getContentPane();                                         

  cn.setLayout( new GridBagLayout() );                               

  c = new GridBagConstraints();                                      

  c.insets = new Insets( 2, 2, 2, 2 );                               

  c.weighty = 1.0;                                                   

  c.weightx = 1.0;                                                   

  c.gridx = 0;                                                       

  c.gridy = 0;                                                       

  c.gridheight = 2;                                                  

  c.fill = GridBagConstraints.BOTH;

  cn.add( new JButton( "Wonderful" ), c );                           

  c.gridx = 1;                                                       

  c.gridheight = 1;                                                  

  c.gridwidth = 2;                                                   

  c.fill = GridBagConstraints.HORIZONTAL;

  cn.add( new JButton( "World" ), c );  

  c.gridy = 1;                                                       

  c.gridwidth = 1;                                                   

  c.fill = GridBagConstraints.NONE;

  cn.add( new JButton( "Of" ), c );

  c.gridx = 2;                                                       

  c.fill = GridBagConstraints.VERTICAL;

  cn.add( new JButton( "Swing !!!" ), c );                           

  desktop.add( fr6, 0 );

Figure 4.10 Using fill constraints.

4.3.8 Putting it all together: Constructing a complaints dialog

Figure 4.11 shows a sketch of a generic complaints dialog that can be used for various forms of user feedback. This sketch shows clearly how we plan to lay out the various components, and the columns and rows in which they will be placed. In order to set the constraints correctly so that the components will be laid out as shown, we must do the following:

For the "Short Description" text field, we set the gridwidth constraint to 3 and the fill constraint to GridBagConstraints.HORIZONTAL. In order to make this field occupy all the horizontal space available, we also need to set the weightx constraints to 1.0.

For the "Description" text area, we set the gridwidth constraint to 3, gridheight to 2, and the fill constraint to GridBagConstraint.BOTH. In order to make this field occupy all available horizontal and vertical space, we set the weightx and weighty constraints to 1.0.

For the "Name," "Telephone," "Sex" and "ID Number" input fields, we want each to use their preferred width. Since widths each exceed the width of one cell, we set gridwidth to 3, and set weightx to 0.0 so that they have enough space to fit but they will not use any additional available horizontal space.

For the "Help" button, we set the anchor constraint to GridBagConstraint.NORTH so that it will stick together with the upper two buttons, "Submit" and "Cancel." The fill constraint is set to HORIZONTAL to force each of these buttons to occupy all available horizontal cell space.

All labels use their preferred sizes, and each component in this dialog is anchored WEST.

Figure 4.11 Sketch of a generic complaints dialog.

<<figure4-11.gif>>

Our implementation follows, and figure 4.12 shows the resulting dialog.

import javax.swing.*;

import javax.swing.border.*;

import java.awt.*;

import java.awt.event.*;

public class ComplaintsDialog extends JDialog

{

  public ComplaintsDialog( JFrame frame ) {

    super( frame, true );

    setTitle( "Simple Complaints Dialog" );

    setSize( 500, 300 );

    // Creates a panel to hold all components

    JPanel panel = new JPanel( new BorderLayout() );

    panel.setLayout( new GridBagLayout() );

    // give the panel a border gap of 5 pixels

    panel.setBorder( new EmptyBorder( new Insets( 5, 5, 5, 5 ) ) );

    getContentPane().add( BorderLayout.CENTER, panel );

    GridBagConstraints c = new GridBagConstraints();

    // Define preferred sizes for input fields

    Dimension shortField = new Dimension( 40, 20 );

    Dimension mediumField = new Dimension( 120, 20 );

    Dimension longField = new Dimension( 240, 20 );

    Dimension hugeField = new Dimension( 240, 80 );

    // Spacing between label and field

    EmptyBorder border = new EmptyBorder( new Insets( 0, 0, 0, 10 ) );

    EmptyBorder border1 = new EmptyBorder( new Insets( 0, 20, 0, 10 ) );

    // add space around all components to avoid clutter

    c.insets = new Insets( 2, 2, 2, 2 );

    // anchor all components WEST

    c.anchor = GridBagConstraints.WEST;

    JLabel lbl1 = new JLabel( "Short Description" );

    lbl1.setBorder( border ); // add some space to the right

    panel.add( lbl1, c );

    JTextField txt1 = new JTextField();

    txt1.setPreferredSize( longField );

    c.gridx = 1;

    c.weightx = 1.0; // use all available horizontal space

    c.gridwidth = 3; // spans across 3 columns

    c.fill = GridBagConstraints.HORIZONTAL; // fills the 3 columns

    panel.add( txt1, c );

    JLabel lbl2 = new JLabel( "Description" );

    lbl2.setBorder( border );

    c.gridwidth = 1;

    c.gridx = 0;

    c.gridy = 1;;

    c.weightx = 0.0; // do not use any extra horizontal space

    panel.add( lbl2, c );

    JTextArea area1 = new JTextArea();

    JScrollPane scroll = new JScrollPane( area1 );

    scroll.setPreferredSize( hugeField );

    c.gridx = 1;

    c.weightx = 1.0; // use all available horizontal space

    c.weighty = 1.0; // use all available vertical space

    c.gridwidth = 3; // span across 3 columns

    c.gridheight = 2; // span across 2 rows

    c.fill = GridBagConstraints.BOTH; // fills the cols & rows

    panel.add( scroll, c );

    JLabel lbl3 = new JLabel( "Severity" );

    lbl3.setBorder( border );

    c.gridx = 0;

    c.gridy = 3;

    c.gridwidth = 1;

    c.gridheight = 1;

    c.weightx = 0.0;

    c.weighty = 0.0;

    c.fill = GridBagConstraints.NONE;

    panel.add( lbl3, c );

    JComboBox combo3 = new JComboBox();

    combo3.addItem( "A" );

    combo3.addItem( "B" );

    combo3.addItem( "C" );

    combo3.addItem( "D" );

    combo3.addItem( "E" );

    combo3.setPreferredSize( shortField );

    c.gridx = 1;

    panel.add( combo3, c );

    JLabel lbl4 = new JLabel( "Priority" );

    lbl4.setBorder( border1 );

    c.gridx = 2;

    panel.add( lbl4, c );

    JComboBox combo4 = new JComboBox();

    combo4.addItem( "1" );

    combo4.addItem( "2" );

    combo4.addItem( "3" );

    combo4.addItem( "4" );

    combo4.addItem( "5" );

    combo4.setPreferredSize( shortField );

    c.gridx = 3;

    panel.add( combo4, c );

    JLabel lbl5 = new JLabel( "Name" );

    lbl5.setBorder( border );

    c.gridx = 0;

    c.gridy = 4;

    panel.add( lbl5, c );

    JTextField txt5 = new JTextField();

    txt5.setPreferredSize( longField );

    c.gridx = 1;

    c.gridwidth = 3;

    panel.add( txt5, c );

    JLabel lbl6 = new JLabel( "Telephone" );

    lbl6.setBorder( border );

    c.gridx = 0;

    c.gridy = 5;

    panel.add( lbl6, c );

    JTextField txt6 = new JTextField();

    txt6.setPreferredSize( mediumField );

    c.gridx = 1;

    c.gridwidth = 3;

    panel.add( txt6, c );

    JLabel lbl7 = new JLabel( "Sex" );

    lbl7.setBorder( border );

    c.gridx = 0;

    c.gridy = 6;

    panel.add( lbl7, c );

    JPanel radioPanel = new JPanel();

    // Create a FlowLayout JPanel with 5 pixel horizontal gaps

    // and no vertical gaps

    radioPanel.setLayout( new FlowLayout( FlowLayout.LEFT, 5, 0 ) );

    ButtonGroup group = new ButtonGroup();

    JRadioButton radio1 = new JRadioButton( "Male" );

    radio1.setSelected( true );

    group.add( radio1 );

    JRadioButton radio2 = new JRadioButton( "Female" );

    group.add( radio2 );

    radioPanel.add( radio1 );

    radioPanel.add( radio2 );

    c.gridx = 1;

    c.gridwidth = 3;

    panel.add( radioPanel, c);

    JLabel lbl8 = new JLabel( "ID Number" );

    lbl8.setBorder( border );

    c.gridx = 0;

    c.gridy = 7;

    c.gridwidth = 1;

    panel.add( lbl8, c );

    JTextField txt8 = new JTextField();

    txt8.setPreferredSize( mediumField );

    c.gridx = 1;

    c.gridwidth = 3;

    panel.add( txt8, c );

    JButton submitBtn = new JButton( "Submit" );

    c.gridx = 4;

    c.gridy = 0;

    c.gridwidth = 1;

    c.fill = GridBagConstraints.HORIZONTAL;

    panel.add( submitBtn, c );

    JButton cancelBtn = new JButton( "Cancel" );

    c.gridy = 1;

    panel.add( cancelBtn, c );

    JButton helpBtn = new JButton( "Help" );

    c.gridy = 2;

    c.anchor = GridBagConstraints.NORTH; // anchor north

    panel.add( helpBtn, c );

    WindowListener wndCloser = new WindowAdapter() {

      public void windowClosing(WindowEvent e) {

        System.exit(0);

      }

    };

    addWindowListener( wndCloser );

    setVisible( true );

  }

  public static void main( String[] args ) {

    new ComplaintsDialog( new JFrame() );

  }

}

Figure 4.12 The Complaints Dialog.

<<figure4-12.gif>>

4.3.9    Simple Helper class example

As we can see from the code above, constructing dialogs with more than a few components easily becomes a very tedious task and reduces source code legibility as well as organization. One way to make the use of GridBagLayout cleaner and easier is to create a helper class that manages all constraints for us, and provides self-explanitory method names and predefined parameters.

Below is the source code of a simple helper class we have constructed for this purpose. The method names used are easier to understand and laying out our components using row and column parameters is more intuitive than gridx and gridy. Methods implemented in this class are each a variation of one of the following:

addComponent: used to add a component that needs to adhere to its preferred size.

addAnchoredComponent: used to add a component that needs to be anchored.

addFilledComponent: used to add a component that will fill the entire cell space allocated to it.

import javax.swing.*;

import java.awt.*;

public class GriddedPanel extends JPanel

{

  private GridBagConstraints constraints;

  // default constraints value definitions

  private static final int C_HORZ = GridBagConstraints.HORIZONTAL;

  private static final int C_NONE = GridBagConstraints.NONE;

  private static final int C_WEST = GridBagConstraints.WEST;

  private static final int C_WIDTH = 1;

  private static final int C_HEIGHT = 1;

  // Create a GridBagLayout panel using a default insets constraint.

  public GriddedPanel() {

    this(new Insets(2, 2, 2, 2));

  }

  // Create a GridBagLayout panel using the specified insets

  // constraint.

  public GriddedPanel(Insets insets) {

    super(new GridBagLayout());

    constraints = new GridBagConstraints();

    constraints.anchor = GridBagConstraints.WEST;

    constraints.insets = insets;

  }

  // Add a component to specified row and col.

  public void addComponent(JComponent component, int row, int col) {

    addComponent(component, row, col, C_WIDTH,

      C_HEIGHT, C_WEST, C_NONE);

  }

  // Add component to specified row and col, spanning across

  // a specified number of columns and rows.

  public void addComponent(JComponent component, int row, int col,

   int width, int height ) {

    addComponent(component, row, col, width,

      height, C_WEST, C_NONE);

  }

  // Add component to specified row and col, using a specified

  // anchor constraint

  public void addAnchoredComponent(JComponent component, int row,

   int col, int anchor ) {

    addComponent(component, row, col, C_WIDTH,

     C_HEIGHT, anchor, C_NONE);

  }

  // Add component to specified row and col, spanning across

  // a specified number of columns and rows, using a specified

  // anchor constraint

  public void addAnchoredComponent(JComponent component,

   int row, int col, int width, int height, int anchor) {

     addComponent(component, row, col, width,

       height, anchor, C_NONE);

  }

  // Add component to specified row and col

  // filling the column horizontally.

  public void addFilledComponent(JComponent component,

   int row, int col) {

    addComponent(component, row, col, C_WIDTH,

     C_HEIGHT, C_WEST, C_HORZ);

  }

  // Add component to the specified row and col

  // with the specified fill constraint.

  public void addFilledComponent(JComponent component,

   int row, int col, int fill) {

    addComponent(component, row, col, C_WIDTH,

     C_HEIGHT, C_WEST, fill);

  }

  // Add component to the specified row and col,

  // spanning a specified number of columns and rows,

  // with specified fill constraint

  public void addFilledComponent(JComponent component,

   int row, int col, int width, int height, int fill) {

    addComponent(component, row, col, width, height, C_WEST, fill);

  }

  // Add component to the specified row and col,

  // spanning specified number of columns and rows, with

  // specified fill and anchor constraints

  public void addComponent(JComponent component,

   int row, int col, int width, int height, int anchor, int fill) {

    constraints.gridx = col;

    constraints.gridy = row;

    constraints.gridwidth = width;

    constraints.gridheight = height;

    constraints.anchor = anchor;

    double weightx = 0.0;

    double weighty = 0.0;

    // only use extra horizontal or vertical space if component

    // spans more than one column and/or row.

    if(width > 1)

      weightx = 1.0;

    if(height > 1)

      weighty = 1.0;

    switch(fill)

    {

      case GridBagConstraints.HORIZONTAL:

        constraints.weightx = weightx;

        constraints.weighty = 0.0;

        break;

      case GridBagConstraints.VERTICAL:

        constraints.weighty = weighty;

        constraints.weightx = 0.0;

        break;

      case GridBagConstraints.BOTH:

        constraints.weightx = weightx;

        constraints.weighty = weighty;

        break;

      case GridBagConstraints.NONE:

        constraints.weightx = 0.0;

        constraints.weighty = 0.0;

        break;

        default:

        break;

    }

    constraints.fill = fill;

    add(component, constraints);

  }

}

Below is the source code used to construct the same complaints dialog as above, using our helper class methods instead of manipulating the constraints directly. Note that the size of the code has been reduced and the readability improved. Also note that we add components starting at row 1 and column 1, rather than row 0 and column 0, as this is the most common numbering scheme for rows and columns (see figure 4.11).

import javax.swing.*;

import javax.swing.border.*;

import java.awt.*;

import java.awt.event.*;

public class ComplaintsDialog2 extends JDialog

{

  public ComplaintsDialog2( JFrame frame ) {

    super( frame, true );

    setTitle( "Simple Complaints Dialog" );

    setSize( 500, 300 );

    GriddedPanel panel = new GriddedPanel();

    panel.setBorder(new EmptyBorder(new Insets(5, 5, 5, 5)));

    getContentPane().add(BorderLayout.CENTER, panel);

    // Input field dimensions

    Dimension shortField = new Dimension( 40, 20 );

    Dimension mediumField = new Dimension( 120, 20 );

    Dimension longField = new Dimension( 240, 20 );

    Dimension hugeField = new Dimension( 240, 80 );

    // Spacing between labels and fields

    EmptyBorder border = new EmptyBorder(

      new Insets( 0, 0, 0, 10 ));

    EmptyBorder border1 = new EmptyBorder(

      new Insets( 0, 20, 0, 10 ));

    JLabel lbl1 = new JLabel( "Short Description" );

    lbl1.setBorder( border );

    panel.addComponent( lbl1, 1, 1 );

    JTextField txt1 = new JTextField();

    txt1.setPreferredSize( longField );

    panel.addFilledComponent( txt1, 1, 2, 3, 1,

      GridBagConstraints.HORIZONTAL );

    JLabel lbl2 = new JLabel( "Description" );

    lbl2.setBorder( border );

    panel.addComponent( lbl2, 2, 1 );

    JTextArea area1 = new JTextArea();

    JScrollPane scroll = new JScrollPane( area1 );

    scroll.setPreferredSize( hugeField );

    panel.addFilledComponent( scroll, 2, 2, 3, 2,

      GridBagConstraints.BOTH );

    JLabel lbl3 = new JLabel( "Severity" );

    lbl3.setBorder( border );

    panel.addComponent( lbl3, 4, 1 );

    JComboBox combo3 = new JComboBox();

    combo3.addItem( "A" );

    combo3.addItem( "B" );

    combo3.addItem( "C" );

    combo3.addItem( "D" );

    combo3.addItem( "E" );

    combo3.setPreferredSize( shortField );

    panel.addComponent( combo3, 4, 2 );

    JLabel lbl4 = new JLabel( "Priority" );

    lbl4.setBorder( border1 );

    panel.addComponent( lbl4, 4, 3 );

    JComboBox combo4 = new JComboBox();

    combo4.addItem( "1" );

    combo4.addItem( "2" );

    combo4.addItem( "3" );

    combo4.addItem( "4" );

    combo4.addItem( "5" );

    combo4.setPreferredSize( shortField );

    panel.addComponent( combo4, 4, 4 );

    JLabel lbl5 = new JLabel( "Name" );

    lbl5.setBorder( border );

    panel.addComponent( lbl5, 5, 1 );

    JTextField txt5 = new JTextField();

    txt5.setPreferredSize( longField );

    panel.addComponent( txt5, 5, 2, 3, 1 );

    JLabel lbl6 = new JLabel( "Telephone" );

    lbl6.setBorder( border );

    panel.addComponent( lbl6, 6, 1 );

    JTextField txt6 = new JTextField();

    txt6.setPreferredSize( mediumField );

    panel.addComponent( txt6, 6, 2, 3, 1 );

    JLabel lbl7 = new JLabel( "Sex" );

    lbl7.setBorder( border );

    panel.addComponent( lbl7, 7, 1 );

    JPanel radioPanel = new JPanel();

    radioPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));

    ButtonGroup group = new ButtonGroup();

    JRadioButton radio1 = new JRadioButton( "Male" );

    radio1.setSelected( true );

    group.add( radio1 );

    JRadioButton radio2 = new JRadioButton( "Female" );

    group.add( radio2 );

    radioPanel.add( radio1 );

    radioPanel.add( radio2 );

    panel.addComponent( radioPanel, 7, 2, 3, 1 );

    JLabel lbl8 = new JLabel( "ID Number" );

    lbl8.setBorder( border );

    panel.addComponent( lbl8, 8, 1 );

    JTextField txt8 = new JTextField();

    txt8.setPreferredSize( mediumField );

    panel.addComponent( txt8, 8, 2, 3, 1 );

    JButton submitBtn = new JButton( "Submit" );

    panel.addFilledComponent( submitBtn, 1, 5 );

    JButton cancelBtn = new JButton( "Cancel" );

    panel.addFilledComponent( cancelBtn, 2, 5 );

    JButton helpBtn = new JButton( "Help" );

    panel.addComponent(helpBtn, 3, 5, 1, 1,

      GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL);

    WindowListener wndCloser = new WindowAdapter() {

      public void windowClosing(WindowEvent e) {

        System.exit(0);

      }

    };

    addWindowListener( wndCloser );

    setVisible( true );

  }

  public static void main( String[] args ) {

    new ComplaintsDialog2( new JFrame() );

  }

}



[ Return to Swing (Book) ]


Top 10 read Java Articles
 Get free "1000 Java Tips eBook"

 Java Calendar and Date: good to know facts and code examples

 Array vs ArrayList vs LinkedList vs Vector: an excellent overview and examples

 How can I convert any Java Object into byte array? And byte array to file object

 The Java Lesson 1: What is Java?

 How do I compare two dates and times, date between dates, time between times and

 Maven vs Ant or Ant vs Maven?

 How to open, read, write, close file(s) in Java? Examples on move, rename and de

 Java Array

 Java: JLabel font and color


[ More in News Section ]
Java Lessons

The Java Lesson 1:
What is Java?
The Java Lesson 2:
Anatomy of a simple Java program
The Java Lesson 3:
Identifiers and primitive data types
The Java Lesson 4:
Variables, constants, and literals
The Java Lesson 5:
Arithmetic operations, conversions, and casts
The Java Lesson 6:
Boolean expressions and operations
The Java Lesson 7:
Bitwise operations
The Java Lesson 8:
Flow control with if and else
The Java Lesson 9:
switch statements
The Java Lesson 10:
for, while, and do-while statements
The Java Lesson 11:
Using break and continue
The Java Lesson 12:
Class methods and how they are called
The Java Lesson 13:
Using the Math class
The Java Lesson 14:
Creating and calling custom class methods
The Java Lesson 15:
Overloading class methods
The Java Lesson 16:
An introduction to objects and object references
The Java Lesson 17:
The String class
The Java Lesson 18:
The StringBuffer class
The Java Lesson 19:
Initializing and processing arrays of primitives
The Java Lesson 20:
Initializing and processing arrays of objects
The Java Lesson 23:
Inheritance and overriding inherited methods
The Java Lesson 24:
abstract classes and polymorphism
The Java Lesson 25:
Interfaces, instanceof, and object conversion and casting
The Java Lesson 26:
Introduction to graphical programming and the java.awt packa
The Java Lesson 27:
The Component class
The Java Lesson 28:
Containers and simple layout managers
The Java Lesson 29:
The Color and Font classes
The Java Lesson 30:
Drawing geometric shapes
The Java Lesson 31:
Choice, List, and Checkbox controls
The Java Lesson 32:
Using the Scrollbar graphical control
The Java Lesson 33:
Menus and submenus
The Java Lesson 34:
An introduction to applets and the Applet class
The Java Lesson 35:
Essential HTML to launch an applet and pass it parameters
The Java Lesson 36:
Mouse event processing
Java Lesson 37:
Menus and submenus
Java Lesson 38:
The WindowListener interface and the WindowAdapter class
Java Lesson 39:
An introduction to GridBagLayout
Java Lesson 40:
An introduction to the Java Collections API
Java Lesson 41:
Exception handling with try, catch, and finally blocks
Java Lesson 42:
Claiming and throwing exceptions
Java Lesson 43:
Multithreading, the Thread class, and the Runnable interface
Java Lesson 44:
An introduction to I/O and the File and FileDialog classes
Java Lesson 45:
Low-level and high-level stream classes
Java Lesson 46:
Using the RandomAccessFile class
Java Lessons by
Joh Huhtala: Update

Latest articles
 Java Profiler JProbe to Resolve Performance Problems Faster

 SSL with GlassFish v2, page 5

 SSL with GlassFish v2, page 4

 SSL with GlassFish v2, page 3

 SSL with GlassFish v2, page 2

 The Java Lesson 2: Anatomy of a simple Java program, page 2

 New site about Java for robots and robotics: both software and hardware.

 Exceptions -III: What's an exception and why do I care?

 Exceptions -II: What's an exception and why do I care?

 Exceptions: What's an exception and why do I care?

 Double your Java code quality in 10 minutes, here is receipt

 Murach's Java Servlets and JSP

 How to get ascii code from a char in Java?

 Can we just try without catch? Yes!

 Make Tomcat page load faster

 Make your Tomcat More secure - limit network address for certain IP addresses

 New Java book online starts now here...

 Implementing RESTful Web Services in Java

 Firefox trimming from 1 GB to 40 Mb with many tabs opened

 SSL with GlassFish v2

 My request to replublish Tech Tips

 Search JavaFAQ.nu site here

 New Advanced Installer for Java 6.0 brings XML updates and imports 3rd party MSI

 EJB programming restrictions

 Maven vs Ant or Ant vs Maven?

 Why Java does not use default value which it should?

 How to unsign signed bytes in Java - your guide is here

 The Java Lesson 3: Identifiers and primitive data types. Page 2

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 4

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 3


[ More in News Section ]


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy