Download the JDK
Search the Tutorials
Hide the TOC
Trail: Creating a GUI with JFC/Swing
Lesson: Laying Out Components Within a Container
Laying Out Components Within a Container
A Visual Guide to Layout Managers
Using Layout Managers
How Layout Management Works
How to Use Various Layout Managers
How to Use BorderLayout
How to Use BoxLayout
How to Use CardLayout
How to Use FlowLayout
How to Use GridBagLayout
How to Use GridLayout
How to Use GroupLayout
A GroupLayout Example
How to Use SpringLayout
Creating a Custom Layout Manager
Doing Without a Layout Manager (Absolute Positioning)
Solving Common Layout Problems
Home Page > Creating a GUI with JFC/Swing > Laying Out Components Within a Container
« Previous • Trail • Next »
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.

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

> `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 `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` 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`:

> - `addLayoutComponent(Component, Object)`
> - `getLayoutAlignmentX(Container)`
> - `getLayoutAlignmentY(Container)`
> - `invalidateLayout(Container)`
> - `maximumLayoutSize(Container)`
> For more information about these methods, see the `LayoutManager2` API documentation.

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

> The example CustomLayoutDemo uses a custom layout manager called `DiagonalLayout`. You can find the layout manager's source code in `DiagonalLayout.java`. `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.

> You can run CustomLayoutDemo using JavaTM Web Start. 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`. Here is a picture of a rough demo called GraphPaperTest that uses `GraphPaperLayout`:

> 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. You can find its complete source code in the example index.

« Previous • Trail • Next »
Previous page: How to Use SpringLayout
Next page: Doing Without a Layout Manager (Absolute Positioning)