The Java TM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

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, `GridBagLayout` 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.

> To create a custom layout manager, you must create a class that implements the `LayoutManager` interface. You can either implement it directly, or implement its subinterface, `LayoutManager2`.

> 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` `getComponents` method.

> `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` 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 `resize`, `move`, and `reshape` 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. 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`:

> - `addLayoutComponent(Component, Object)`
> - `getLayoutAlignmentX(Container)`
> - `getLayoutAlignmentY(Container)`
> - `invalidateLayout(Container)`
> - `maximumLayoutSize(Container)`
> For more information about these methods, see the `LayoutManager2` API documentation. Also see the source code for `BoxLayout`, to see how it implements the `LayoutManager2` interface.

> When implementing a layout manager, you might want to use `SizeRequirements` objects to help you determine the size and position of components. See the source code for `BoxLayout` for an example of using `SizeRequirements`.

> In `DiagonalLayout.java`, you can find the source code for a custom layout manager. `DialogLayout` lays out components diagonally, from left to right, with one component per row. Here's an example of `DiagonalLayout` in action:

> This is a picture of the applet's GUI. To run the applet, click the picture. The applet will appear in a new browser window.

> You can find another example of a custom layout manager in `GraphPaperLayout.java`. `GraphPaperLayout`, written by Michael Martak, lays out components in a grid. Each component's size and location are specified, using grid units rather than absolute locations, when the component is added to its 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. For an example of using `GraphPaperLayout`, see `GraphPaperTest.java`. Here's a snapshot of `GraphPaperTest` that shows `GraphPaperLayout` in action:

| Start of Tutorial > Start of Trail > Start of Lesson | Search