TableLayout

Java Technology Home Page
Downloads, APIs, Documentation
Java Developer Connection
Docs, Tutorials, Tech Articles, Training
Online Support
Community Discussion
News & Events from Everywhere
Products from Everywhere
How Java Technology is Used Worldwide


TSC Contents
Front Page
Article Index

Related Links
JFC Home
Download J2SE
J2SE 1.4 Release
Notes for Swing
Java Tutorial
Java Web Start
Swing Sightings

Sign up for email
notification

 

 Article Table of Contents 
    
 Introduction 
  What is TableLayout? 
  Creating a TableLayout 
    
 Column and Row Sizes 
  Absolute and Scalable Space 
  Order of Allocation 
  Rounding Considerations 
    
 Cells 
  Adding Components 
  Justification 
  Multiple Cells 
    
 Final Theory 
  Dynamic Rows and Columns 
  Preferred Layout Size 
  Onward 
    
 Examples 
  Simple 
  GridLayout Comparison 
  GridBagLayout Comparison 
  A Typical GUI 
  Preferred Rows and Columns 
  TableLayoutConstraints 
 A RAD Tool 
    
 API Reference 
 Download 
Help pagesA-Z Index

The Source for Java Technology

 

A Rapid Application Development Tool

The following example illustrates how to dynamically create, resize, and remove rows and columns from a TableLayout, and how to dynamically retrieve and change the constraints of a component. This example is a simple Rapid Application Development tool that will generate code using TableLayout. The complete source code available in RadTool.java, but for simplicity, we will look at the pertinent individual parts.

Upon startup, the example looks like this. In the top section of the frame, there is a panel containing several JButtons labeled "0: -2.0", "1:-1.0", and "1:-1.0". These JButtons mark the columns and rows that partition the panel. JButtons were used instead of JLabels so that it would be easy to see where the row and column borders are. The labels of the JButtons refer to the row or column number and the row or column size. For example, "0: -2.0" means that row 0 has a height of TableLayout.PREFERRED (-2.0). "1: -1.0" means row 1 has a height of TableLayout.FILL (-1.0). "2: 50" would mean row 2 has a height of 50 pixels, and "3: 0.25" would mean that row 3 has a height of 25% of the scalable space.

On startup, there are two rows and two columns. The JButtons in row 0 are the column headers and the JButtons in column 0 are the row headers. As we create, resize, and remove rows and columns, these headers will be adjusted. The panel containing these buttons will simply be referred to as 'the panel'.

Below the panel are controls for creating, resizing, and removing rows and columns. The first text field is the row or column number to manipulate. The second text field is a size to use when creating or resizing a row or column. Below those controls is a text area that is used for textual output. Whenever the layout is changed, the current row and column sizes will be shown in this text area. Also, any error messages are also shown in the text area. The "Show Layout" button below the text area is used to show the current layout sizes in the text area. The "Generate Code" button will put fully functional code in the text area for creating a frame that mimics the current state of the panel.

Clicking on a white spot in the panel will create a component (a Smiley face) that occupies the cell clicked. Clicking on the Smiley will pop up a dialog box that can be used to adjust the constraints of the Smiley.

Play with the GUI tool to see how it works. As you add rows and columns, you will also see lines separating the rows and columns.

Constructing a GUI

The picture above shows the RAD tool after a couple of rows and columns are inserted and a couple of Smileys are added. The picture below shows the execution of the code generated by the RAD tool. The Smileys are replaced with java.lang.Button objects. Notice that in this example, there are more than one Smiley in cell (3, 3). They don't overlap because of the container size, their preferred sizes, and their justifications.

The generated code for the above example is given below.

import java.awt.*;
import java.awt.event.*;
import layout.TableLayout;

public class MyClass
{

    public static void main (String args[])
    {
        Frame frame = new Frame("MyTitle");
        frame.setBounds (100, 100, 300, 300);

       double size[][] =
           {{-2.0, 10.0, 50.0, -1.0, 10.0},  // Columns
           {-2.0, 10.0, 0.25, -1.0, 10.0}}; // Rows

        frame.setLayout (new TableLayout(size));

        Button button;
        button = new Button("3, 3, R, C");
        frame.add (button, "3, 3, R, C");
        button = new Button("3, 3, L, T");
        frame.add (button, "3, 3, L, T");
        button = new Button("2, 3, C, T");
        frame.add (button, "2, 3, C, T");
        button = new Button("3, 2, L, C");
        frame.add (button, "3, 2, L, C");
        button = new Button("2, 2, F, F");
        frame.add (button, "2, 2, F, F");
        button = new Button("3, 3, C, C");
        frame.add (button, "3, 3, C, C");

        frame.addWindowListener
            (new WindowAdapter()
                {
                    public void windowClosing (WindowEvent e)
                    {
                        System.exit (0);
                    }
                }
            );

        frame.show();
    }
}
                

Dynamically Manipulating Rows and Columns

The actionPerformed method is called whenever one of the add, resize, remove buttons is pressed. The code in this method (shown below) dynamically changes the layout.

    public void actionPerformed (ActionEvent e)
    {
        // Get row and column information from text fields
        int row = getInt(textfieldRowNumber);
        int col = getInt(textfieldColumnNumber);
        double rowSize = getDouble(textfieldRowSize);
        double colSize = getDouble(textfieldColumnSize);
        
        // Get source of the event
        Object source = e.getSource();
        
        try
        {
            // Update layout
            if (source == buttonAddColumn)
                layout.insertColumn (col, colSize);
            else if (source == buttonRemoveColumn)
                layout.deleteColumn (col);
            else if (source == buttonResizeColumn)
                layout.setColumn (col, colSize);
            else if (source == buttonAddRow)
                layout.insertRow (row, rowSize);
            else if (source == buttonRemoveRow)
                layout.deleteRow (row);
            else if (source == buttonResizeRow)
                layout.setRow (row, rowSize);

            // Update headers, etc. to reflect layout's change
            updateHeader();
            updateBox();

            // Layout and repaint panel since the layout has changed
            panel.doLayout();
            panel.repaint();
            
            // Update layout's description
            textArea.setText(layout.toString());
            
            // Generate code if desired
            if (source == buttonGenerateCode)
                generateCode();
        }
        catch (Throwable error)
        {
            error.printStackTrace();
            textArea.setText (error.toString());
        }
    }
                

The important part of the code is the call to the insertColumn/Row, deleteColumn/Row, setColumn/Row, methods. A single line of code is all that is needed to insert, remove, or resize a row or column. The updateHeader method updates all the row and column headers to reflect the new set of rows and columns. The updateBox method puts empty square buttons in the whitespace of the panel to mark the cells and to insert Smileys. The call to panel.doLayout is necessary to layout the panel since the panel's layout has changed. The call to panel.repaint is necessary because some components will be removed and we don't want their images still being displayed.

Final Word

If you want to get more familiar with the nuts and bolts of dynamic layout manipulation, take a look at RadTool.java. If you just want to know how to use the TableLayout APIs, consult the TableLayout documentation. To get more familar with the runtime behavior of TableLayout, play with the RadTool. Adjust the rows and columns, insert some components, and resize the frame to see TableLayout at work.

The first layout managers that Java programmers learned were easy to use, but could do very little. Eventually, Java programmers tackle GridBagLayout because they need more functionality and flexibility, but most inevitably go back to using either no layout manager or nested simple layout managers because GridBagLayout is to complicated to use. The next series of layout managers introduced layout managers that were simple and could do more advanced tasks, but they were specialized and designed for specific Swing controls. TableLayout is a general-purpose layout manager that is as easy to use as GridLayout and even more powerful than GridBagLayout with the ability to dynamically add, remove, and resize rows and columns. Best of all, TableLayout is simple and easy to understand.

Previous | End