The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Trail: Creating a GUI with JFC/Swing
Lesson: Laying Out Components Within a Container

Creating a Custom Layout Manager


Note:  Before you start creating a custom layout manager, make sure that no existing layout manager will work. In particular, layout managers such as GridBagLayout, SpringLayout, and BoxLayout are flexible enough to work in many cases. You can also find layout managers from other sources, such as from the Internet. Finally, you can simplify layout by grouping components into containers such as invisible panels (in the Creating a GUI with JFC/Swing trail).

To create a custom layout manager, you must create a class that implements the LayoutManager (in the API reference documentation) interface. You can either implement it directly, or implement its subinterface, LayoutManager2 (in the API reference documentation).

Every layout manager must implement at least the following five methods, which are required by the LayoutManager interface:

void addLayoutComponent(String, Component)
Called by the Container add methods. Layout managers that don't associate strings with their components generally do nothing in this method.

void removeLayoutComponent(Component)
Called by the Container remove and removeAll methods. Many layout managers do nothing in this method, relying instead on querying the container for its components, using the Container method getComponents (in the API reference documentation).

Dimension preferredLayoutSize(Container)
Called by the Container getPreferredSize method, which is itself called under a variety of circumstances. This method should calculate and return the ideal size of the container, assuming that the components it contains will be at or above their preferred sizes. This method must take into account the container's internal borders, which are returned by the getInsets (in the API reference documentation) method.

Dimension minimumLayoutSize(Container)
Called by the Container getMinimumSize method, which is itself called under a variety of circumstances. This method should calculate and return the minimum size of the container, assuming that the components it contains will be at or above their minimum sizes. This method must take into account the container's internal borders, which are returned by the getInsets method.

void layoutContainer(Container)
Called when the container is first displayed, and each time its size changes. A layout manager's layoutContainer method doesn't actually draw components. It simply invokes each component's setSize, setLocation, and setBounds methods to set the component's size and position.

This method must take into account the container's internal borders, which are returned by the getInsets method. If appropriate, it should also take the container's orientation (returned by the getComponentOrientation (in the API reference documentation) method) into account. You can't assume that the preferredLayoutSize or minimumLayoutSize method will be called before layoutContainer is called.

Besides implementing the preceding five methods, layout managers generally implement at least one public constructor and the toString method.

If you wish to support component constraints, maximum sizes, or alignment, then your layout manager should implement the LayoutManager2 interface. That interface adds five methods to those required by LayoutManager:

For more information about these methods, see the LayoutManager2 API documentation (in the API reference documentation).

When implementing a layout manager, you might want to use SizeRequirements (in the API reference documentation) objects to help you determine the size and position of components. See the source code for BoxLayout for an example of using SizeRequirements.

The example CustomLayoutDemo uses a custom layout manager called DiagonalLayout. You can find the layout manager's source code in DiagonalLayout.java (in a .java source file). DialogLayout lays out components diagonally, from left to right, with one component per row. Here's a picture of CustomLayoutDemo using DialogLayout to lay out five buttons.

A snapshot of CustomLayoutDemo

You can run CustomLayoutDemo using JavaTM Web Start (in the Creating a GUI with JFC/Swing trail). Its complete source code is in the example index.

Another example of a custom layout manager is GraphPaperLayout, which implements LayoutManager2 and lays out components in a grid. You can find its source code in GraphPaperLayout.java (in a .java source file). Here is a picture of a rough demo called GraphPaperTest that uses GraphPaperLayout:

A snapshot of GraphPaperTest

When a container uses GraphPaperLayout, the size and location of its child components are specified (using grid units rather than absolute locations) as the components are added to the container. You can set the relative grid size, horizontal space between components, and vertical space between components when initializing the layout manager. You can also change component locations and the grid size dynamically.

You can run GraphPaperTest using JavaTM Web Start (in the Creating a GUI with JFC/Swing trail). You can find its complete source code in the example index.


Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Copyright 1995-2004 Sun Microsystems, Inc. All rights reserved.