1.6 Laying Out Components Within a Container

This lesson tells you how to use the layout managers provided by the Java platform. It also tells you how to use absolute positioning (no layout manager) and gives an example of writing a custom layout manager. For each layout manager (or lack thereof), this lesson points to an example that you can run using Java™ Web Start. By resizing an example's window, you can see how size changes affect the layout.

◉ A Visual Guide to Layout Managers


Several AWT and Swing classes provide layout managers for general use:

BorderLayout

Oracle Java Tutorials and Materials, Oracle Java Certifications

Every content pane is initialized to use a BorderLayout. (As Using Top-Level Containers explains, the content pane is the main container in all frames, applets, and dialogs.) A BorderLayout places components in up to five areas: top, bottom, left, right, and center. All extra space is placed in the center area. Tool bars that are created using JToolBar must be created within a BorderLayout container, if you want to be able to drag and drop the bars away from their starting positions.

BoxLayout


Oracle Java Tutorials and Materials, Oracle Java Certifications

The BoxLayout class puts components in a single row or column. It respects the components' requested maximum sizes and also lets you align components.

CardLayout

Oracle Java Tutorials and Materials, Oracle Java Certifications

The CardLayout class lets you implement an area that contains different components at different times. A CardLayout is often controlled by a combo box, with the state of the combo box determining which panel (group of components) the CardLayout displays. An alternative to using CardLayout is using a tabbed pane, which provides similar functionality but with a pre-defined GUI.

FlowLayout

Oracle Java Tutorials and Materials, Oracle Java Certifications

FlowLayout is the default layout manager for every JPanel. It simply lays out components in a single row, starting a new row if its container is not sufficiently wide.

GridBagLayout

Oracle Java Tutorials and Materials, Oracle Java Certifications

GridBagLayout is a sophisticated, flexible layout manager. It aligns components by placing them within a grid of cells, allowing components to span more than one cell. The rows in the grid can have different heights, and grid columns can have different widths.

GridLayout

Oracle Java Tutorials and Materials, Oracle Java Certifications

GridLayout simply makes a bunch of components equal in size and displays them in the requested number of rows and columns.

GroupLayout

Oracle Java Tutorials and Materials, Oracle Java Certifications

GroupLayout is a layout manager that was developed for use by GUI builder tools, but it can also be used manually. GroupLayout works with the horizontal and vertical layouts separately. The layout is defined for each dimension independently. Consequently, however, each component needs to be defined twice in the layout. The Find window shown above is an example of a GroupLayout.

SpringLayout

Oracle Java Tutorials and Materials, Oracle Java Certifications

Oracle Java Tutorials and Materials, Oracle Java Certifications

SpringLayout is a flexible layout manager designed for use by GUI builders. It lets you specify precise relationships between the edges of components under its control. For example, you might define that the left edge of one component is a certain distance (which can be dynamically calculated) from the right edge of a second component. SpringLayout lays out the children of its associated container according to a set of constraints, as shall be seen in How to Use SpringLayout.

This section shows example GUIs that use these layout managers, and tells you where to find the how-to page for each layout manager.

◉ Using Layout Managers

A layout manager is an object that implements the LayoutManager interface* and determines the size and position of the components within a container. Although components can provide size and alignment hints, a container's layout manager has the final say on the size and position of the components within the container.

Note: This lesson covers writing layout code by hand, which can be challenging. If you are not interested in learning all the details of layout management, you might prefer to use the GroupLayout layout manager combined with a builder tool to lay out your GUI. One such builder tool is the NetBeans IDE. Otherwise, if you want to code by hand and do not want to use GroupLayout, then GridBagLayout is recommended as the next most flexible and powerful layout manager.
If you are interested in using JavaFX to create your GUI

This section discusses some of the common tasks related to using layout managers:

Setting the Layout Manager

As a rule, the only containers whose layout managers you need to worry about are JPanels and content panes. Each JPanel object is initialized to use a FlowLayout, unless you specify differently when creating the JPanel. Content panes use BorderLayout by default. If you do not like the default layout manager that a panel or content pane uses, you are free to change it to a different one. However, unless you are using JToolBar, the FlowLayout and BorderLayout managers are only useful for prototyping. Any real application will need to reset the layout manager. Again, you should use an appropriate tool to do this, rather than coding the manager by hand.

You can set a panel's layout manager using the JPanel constructor. For example:

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

After a container has been created, you can set its layout manager using the setLayout method. For example:

Container contentPane = frame.getContentPane();
contentPane.setLayout(new FlowLayout());

Although we strongly recommend that you use layout managers, you can perform layout without them. By setting a container's layout property to null, you make the container use no layout manager. With this strategy, called absolute positioning, you must specify the size and position of every component within that container. One drawback of absolute positioning is that it does not adjust well when the top-level container is resized. It also does not adjust well to differences between users and systems, such as different font sizes and locales.

Adding Components to a Container

When you add components to a panel or content pane, the arguments you specify to the add method depend on the layout manager that the panel or content pane is using. In fact, some layout managers do not even require you to add the component explicitly; for example, GroupLayout. For example, BorderLayout requires that you specify the area to which the component should be added (using one of the constants defined in BorderLayout) using code like this:

pane.add(aComponent, BorderLayout.PAGE_START);

The how-to section for each layout manager has details on what, if any, arguments you need to specify to the add method. Some layout managers, such as GridBagLayout and SpringLayout, require elaborate setup procedures. Many layout managers, however, simply place components based on the order they were added to their container.

Swing containers other than JPanel and content panes generally provide API that you should use instead of the add method. For example, instead of adding a component directly to a scroll pane (or, actually, to its viewport), you either specify the component in the JScrollPane constructor or use setViewportView. Because of specialized API like this, you do not need to know which layout manager (if any) many Swing containers use. (For the curious: scroll panes happen to use a layout manager named ScrollPaneLayout.)

Providing Size and Alignment Hints

Sometimes you need to customize the size hints that a component provides to its container's layout manager, so that the component will be laid out well. You can do this by specifying one or more of the minimum, preferred, and maximum sizes of the component. You can invoke the component's methods for setting size hints — setMinimumSize, setPreferredSize, and setMaximumSize. Or you can create a subclass of the component that overrides the appropriate getter methods — getMinimumSize, getPreferredSize, and getMaximumSize. Here is an example of making a component's maximum size unlimited:

component.setMaximumSize(new Dimension(Integer.MAX_VALUE,
                                       Integer.MAX_VALUE));

Many layout managers do not pay attention to a component's requested maximum size. However, BoxLayout and SpringLayout do. Furthermore, GroupLayout provides the ability to set the minimum, preferred or maximum size explicitly, without touching the component.

Besides providing size hints, you can also provide alignment hints. For example, you can specify that the top edges of two components should be aligned. You set alignment hints either by invoking the component's setAlignmentX and setAlignmentY methods, or by overriding the component's getAlignmentX and getAlignmentY methods. Although most layout managers ignore alignment hints, BoxLayout honors them. You can find examples of setting the alignment in How to Use BoxLayout.

Putting Space Between Components

Three factors influence the amount of space between visible components in a container:

The layout manager
Some layout managers automatically put space between components; others do not. Some let you specify the amount of space between components. See the how-to page for each layout manager for information about spacing support.

Invisible components
You can create lightweight components that perform no painting, but that can take up space in the GUI. Often, you use invisible components in containers controlled by BoxLayout. See How to Use BoxLayout for examples of using invisible components.

Empty borders
No matter what the layout manager, you can affect the apparent amount of space between components by adding empty borders to components. The best candidates for empty borders are components that typically have no default border, such as panels and labels. Some other components might not work well with borders in some look-and-feel implementations, because of the way their painting code is implemented.

Setting the Container's Orientation

This website is written in English, with text that runs from left to right, and then top to bottom. However, many other languages have different orientations. The componentOrientation property provides a way of indicating that a particular component should use something different from the default left-to-right, top-to-bottom orientation. In a component such as a radio button, the orientation might be used as a hint that the look and feel should switch the locations of the icon and text in the button. In a container, the orientation is used as a hint to the layout manager.

To set a container's orientation, you can use either the Component-defined method setComponentOrientation or, to set the orientation on the container's children as well, applyComponentOrientation. The argument to either method can be a constant such as ComponentOrientation.RIGHT_TO_LEFT, or it can be a call to the ComponentOrientation method getOrientation(Locale). For example, the following code causes all JComponents to be initialized with an Arabic-language locale, and then sets the orientation of the content pane and all components inside it accordingly:

JComponent.setDefaultLocale(new Locale("ar"));
JFrame frame = new JFrame();
...
Container contentPane = frame.getContentPane();
contentPane.applyComponentOrientation(
    ComponentOrientation.getOrientation(
        contentPane.getLocale()));

Here are two pictures showing how FlowLayout lays out components in containers that are exactly the same, except for their orientation.

Oracle Java Tutorials and Materials, Oracle Java Certifications
Default orientation (left-to-right)

Oracle Java Tutorials and Materials, Oracle Java Certifications
Right-to-left orientation

he standard layout managers that support component orientation are FlowLayout, BorderLayout, BoxLayout, GridBagLayout, and GridLayout.

Note: Care must be taken that the component orientation is applied to renderers, editors and any other components unreachable through normal traversal of the containment hierarchy.

Tips on Choosing a Layout Manager

Layout managers have different strengths and weaknesses. This section discusses some common layout scenarios and which layout managers might work for each scenario. However, once again, it is strongly recommended that you use a builder tool to create your layout managers, such as the NetBeans IDE Matisse GUI builder, rather than coding managers by hand. The scenarios listed below are given for information purposes, in case you are curious about which type of manager is used in different situations, or in case you absolutely must code your manager manually.

If none of the layout managers we discuss is right for your situation and you cannot use a builder tool, feel free to use other layout managers that you may write or find. Also keep in mind that flexible layout managers such as GridBagLayout and SpringLayout can fulfill many layout needs.

Scenario: You need to display a component in as much space as it can get.
If it is the only component in its container, use GridLayout or BorderLayout. Otherwise, BorderLayout or GridBagLayout might be a good match.

If you use BorderLayout, you will need to put the space-hungry component in the center. With GridBagLayout, you will need to set the constraints for the component so that fill=GridBagConstraints.BOTH. Another possibility is to use BoxLayout, making the space-hungry component specify very large preferred and maximum sizes.

Scenario: You need to display a few components in a compact row at their natural size.
Consider using a JPanel to group the components and using either the JPanel's default FlowLayout manager or the BoxLayout manager. SpringLayout is also good for this.

Scenario: You need to display a few components of the same size in rows and columns.
GridLayout is perfect for this.

Scenario: You need to display a few components in a row or column, possibly with varying amounts of space between them, custom alignment, or custom component sizes.
BoxLayout is perfect for this.

Scenario: You need to display aligned columns, as in a form-like interface where a column of labels is used to describe text fields in an adjacent column.
SpringLayout is a natural choice for this. The SpringUtilities class used by several Tutorial examples defines a makeCompactGrid method that lets you easily align multiple rows and columns of components.

Scenario: You have a complex layout with many components.
Consider either using a very flexible layout manager such as GridBagLayout or SpringLayout, or grouping the components into one or more JPanels to simplify layout. If you take the latter approach, each JPanel might use a different layout manager.

Third-Party Layout Managers

Other third party layout managers have been created by the Swing community, to complement those provided by the Java platform. The following list is by no means definitive, but the layout managers listed below are the most popular:

1. MiGLayout
2. Karsten Lentzsch's FormLayout

◉ How Layout Management Works

If you are interested in using JavaFX to create your GUI.

Here is an example of a layout management sequence for a container using LayoutManager2.

1. Layout managers basically do two things:
  • Calculate the minimum/preferred/maximum sizes for a container.
  • Lay out the container's children.
Layout managers do this based on the provided constraints, the container's properties (such as insets) and on the children's minimum/preferred/maximum sizes. If a child is itself a container then its own layout manger is used to get its minimum/preferred/maximum sizes and to lay it out.

2. A container can be valid (namely, isValid() returns true) or invalid. For a container to be valid, all the container's children must be laid out already and must all be valid also. The Container.validate method can be used to validate an invalid container. This method triggers the layout for the container and all the child containers down the component hierarchy and marks this container as valid.

3. After a component is created it is in the invalid state by default. The Window.pack method validates the window and lays out the window's component hierarchy for the first time.

The end result is that to determine the best size for the container, the system determines the sizes of the containers at the bottom of the containment hierarchy. These sizes then percolate up the containment hierarchy, eventually determining the container's total size.

If the size of a component changes, for example following a change of font, the component must be resized and repainted by calling the revalidate and repaint methods on that component. Both revalidate and repaint are thread-safe — you need not invoke them from the event-dispatching thread.

When you invoke revalidate on a component, a request is passed up the containment hierarchy until it encounters a container, such as a scroll pane or top-level container, that should not be affected by the component's resizing. (This is determined by calling the container's isValidateRoot method.) The container is then laid out, which has the effect of adjusting the revalidated component's size and the size of all affected components.

◉ How to Use Various Layout Managers

Each of the following pages describes how to use a particular kind of layout manager. Another way to get to these pages is through A Visual Guide to Layout Managers.

Note: This lesson covers writing layout code by hand, which can be challenging. If you are not interested in learning all the details of layout management, you might prefer to use the GroupLayout layout manager combined with a builder tool to lay out your GUI. One such builder tool is the NetBeans IDE. Otherwise, if you want to code by hand and do not want to use GroupLayout, then GridBagLayout is recommended as the next most flexible and powerful layout manager.
If you are interested in using JavaFX to create your GUI, see Working With Layouts in JavaFX.

➥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
➥How to Use SpringLayout

◉ How to Use BorderLayout

Note: This lesson covers writing layout code by hand, which can be challenging. If you are not interested in learning all the details of layout management, you might prefer to use the GroupLayout layout manager combined with a builder tool to lay out your GUI. One such builder tool is the NetBeans IDE. Otherwise, if you want to code by hand and do not want to use GroupLayout, then GridBagLayout is recommended as the next most flexible and powerful layout manager.

If you are interested in using JavaFX to create your GUI.

The following figure represents a snapshot of an application that uses the BorderLayout class.

Oracle Java Tutorials and Materials, Oracle Java Certifications

Click the Launch button to run BorderLayoutDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.

The complete code of this demo is in the BorderLayoutDemo.java file.

As the preceding picture shows, a BorderLayout object has five areas. These areas are specified by the BorderLayout constants:
  • PAGE_START
  • PAGE_END
  • LINE_START
  • LINE_END
  • CENTER
Version note: 

Before JDK release 1.4, the preferred names for the various areas were different, ranging from points of the compass (for example, BorderLayout.NORTH for the top area) to wordier versions of the constants we use in our examples. The constants our examples use are preferred because they are standard and enable programs to adjust to languages that have different orientations.

If the window is enlarged, the center area gets as much of the available space as possible. The other areas expand only as much as necessary to fill all available space. Often a container uses only one or two of the areas of the BorderLayout object — just the center, or the center and the bottom.

The following code adds components to a frame's content pane. Because content panes use the BorderLayout class by default, the code does not need to set the layout manager. The complete program is in the BorderLayoutDemo.java file.

...//Container pane = aFrame.getContentPane()...
JButton button = new JButton("Button 1 (PAGE_START)");
pane.add(button, BorderLayout.PAGE_START);

//Make the center component big, since that's the
//typical usage of BorderLayout.
button = new JButton("Button 2 (CENTER)");
button.setPreferredSize(new Dimension(200, 100));
pane.add(button, BorderLayout.CENTER);

button = new JButton("Button 3 (LINE_START)");
pane.add(button, BorderLayout.LINE_START);

button = new JButton("Long-Named Button 4 (PAGE_END)");
pane.add(button, BorderLayout.PAGE_END);

button = new JButton("5 (LINE_END)");
pane.add(button, BorderLayout.LINE_END);

Specify the component's location (for example, BorderLayout.LINE_END) as one of the arguments to the add method. If this component is missing from a container controlled by a BorderLayout object, make sure that the component's location was specified and no another component was placed in the same location.

All tutorial examples that use the BorderLayout class specify the component as the first argument to the add method. For example:

add(component, BorderLayout.CENTER)  //preferred

However, the code in other programs specifies the component as the second argument. For example, here are alternate ways of writing the preceding code:

add(BorderLayout.CENTER, component)  //valid but old fashioned
    or
add("Center", component)             //valid but error prone

The BorderLayout API


The following table lists constructors and methods to specify gaps (in pixels).

Specifying gaps

Constructor or Method Purpose
BorderLayout(int horizontalGap, int verticalGap) Defines a border layout with specified gaps between components
setHgap(int) Sets the horizontal gap between components.
setVgap(int) Sets the vertical gap between components.

Examples that Use BorderLayout


The following table lists code examples that use the BorderLayout class and provides links to related sections.

Where Described Where Described Notes
BorderLayoutDemo This page Puts a component in each of the five possible locations.
TabbedPaneDemo How to Use Tabbed Panes One of many examples that puts a single component in the center of a content pane, so that the component is as large as possible.
CheckBoxDemo How to Use Check Boxes Creates a JPanel object that uses the BorderLayout class. Puts components into the left (actually, LINE_START) and center locations.


◉ How to Use BoxLayout

Note: This lesson covers writing layout code by hand, which can be challenging. If you are not interested in learning all the details of layout management, you might prefer to use the GroupLayout layout manager combined with a builder tool to lay out your GUI. One such builder tool is the NetBeans IDE. Otherwise, if you want to code by hand and do not want to use GroupLayout, then GridBagLayout is recommended as the next most flexible and powerful layout manager.
If you are interested in using JavaFX to create your GUI.

The Swing packages include a general purpose layout manager named BoxLayout. BoxLayout either stacks its components on top of each other or places them in a row — your choice. You might think of it as a version of FlowLayout, but with greater functionality. Here is a picture of an application that demonstrates using BoxLayout to display a centered column of components:

Oracle Java Tutorials and Materials, Oracle Java Certifications

Click the Launch button to run BoxLayoutDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.

Launches the BoxLayoutDemo example
You can see the code in BoxLayoutDemo.java.

The following figure shows a GUI that uses two instances of BoxLayout. In the top part of the GUI, a top-to-bottom box layout places a label above a scroll pane. In the bottom part of the GUI, a left-to-right box layout places two buttons next to each other. A BorderLayout combines the two parts of the GUI and ensures that any excess space is given to the scroll pane.

Oracle Java Tutorials and Materials, Oracle Java Certifications

The following code, taken from ListDialog.java, lays out the GUI. This code is in the constructor for the dialog, which is implemented as a JDialog subclass. The bold lines of code set up the box layouts and add components to them.

JScrollPane listScroller = new JScrollPane(list);
listScroller.setPreferredSize(new Dimension(250, 80));
listScroller.setAlignmentX(LEFT_ALIGNMENT);
...
//Lay out the label and scroll pane from top to bottom.
JPanel listPane = new JPanel();
listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS));
JLabel label = new JLabel(labelText);
...
listPane.add(label);
listPane.add(Box.createRigidArea(new Dimension(0,5)));
listPane.add(listScroller);
listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));

//Lay out the buttons from left to right.
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
buttonPane.add(Box.createHorizontalGlue());
buttonPane.add(cancelButton);
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPane.add(setButton);

//Put everything together, using the content pane's BorderLayout.
Container contentPane = getContentPane();
contentPane.add(listPane, BorderLayout.CENTER);
contentPane.add(buttonPane, BorderLayout.PAGE_END);

The first bold line creates a top-to-bottom box layout and sets it up as the layout manager for listPane. The two arguments to the BoxLayout constructor are the container that it manages and the axis along which the components will be laid out. The PAGE_AXIS constant specifies that components should be laid out in the direction that lines flow across a page as determined by the target container's ComponentOrientation property. The LINE_AXIS constant specifies that components should be laid out in the direction of a line of text as determined by the target container's ComponentOrientation property. These constants allow for internationalization, by laying out components in their container with the correct left-to-right, right-to-left or top-to-bottom orientation for the language being used.

The next three bold lines add the label and scroll pane to the container, separating them with a rigid area — an invisible component used to add space between components. In this case, the rigid area has no width and puts exactly 5 pixels between the label and scroll pane. Rigid areas are discussed later, in Using Invisible Components as Filler.

The next chunk of bold code creates a left-to-right box layout and sets it up for the buttonPane container. Then the code adds two buttons to the container, using a rigid area to put 10 pixels between the buttons. To place the buttons at the right side of their container, the first component added to the container is glue. This glue is an invisible component that grows as necessary to absorb any extra space in its container.

As an alternative to using invisible components, you can sometimes use empty borders to create space around components, most particularly panels. For example, the preceding code snippet uses empty borders to put 10 pixels between all sides of the dialog and its contents, and between the two parts of the contents. Borders are completely independent of layout managers. They are simply how Swing components draw their edges and provide padding between the content of the component and the edge.

The following sections discuss BoxLayout in more detail:
  • Box layout features
  • Using invisible components as filler
  • Fixing alignment problems
  • Specifying component sizes
  • The box layout API
  • Examples that use box layouts
Do not let the length of the BoxLayout discussion scare you! You can probably use BoxLayout with the information you already have. If you run into trouble or you want to take advantage of BoxLayout's power, read on.

Box Layout Features

As said before, BoxLayout arranges components either on top of each other or in a row. As the box layout arranges components, it takes the components' alignments and minimum, preferred, and maximum sizes into account. In this section, we will talk about top-to-bottom layout. The same concepts apply to left-to-right or right-to-left layout. You simply substitute X for Y, height for width, and so on.

Version note: Before JDK version 1.4, no constants existed for specifying the box layout's axis in a localizable way. Instead, you specified X_AXIS (left to right) or Y_AXIS (top to bottom) when creating the BoxLayout. Our examples now use the constants LINE_AXIS and PAGE_AXIS, which are preferred because they enable programs to adjust to languages that have different orientations. In the default, left-to-right orientation, LINE_AXIS specifies left-to-right layout and PAGE_AXIS specifies top-to-bottom layout.

When a BoxLayout lays out components from top to bottom, it tries to size each component at the component's preferred height. If the vertical space of the layout does not match the sum of the preferred heights, then BoxLayout tries to resize the components to fill the space. The components either grow or shrink to fill the space, with BoxLayout honoring the minimum and maximum sizes of each of the components. Any extra space appears at the bottom of the container.

For a top-to-bottom box layout, the preferred width of the container is that of the maximum preferred width of the children. If the container is forced to be wider than that, BoxLayout attempts to size the width of each component to that of the container's width (minus insets). If the maximum size of a component is smaller than the width of the container, then X alignment comes into play.

The X alignments affect not only the components' positions relative to each other, but also the location of the components (as a group) within their container. The following figures illustrate alignment of components that have restricted maximum widths.

Oracle Java Tutorials and Materials, Oracle Java CertificationsOracle Java Tutorials and Materials, Oracle Java CertificationsOracle Java Tutorials and Materials, Oracle Java Certifications

In the first figure, all three components have an X alignment of 0.0 (Component.LEFT_ALIGNMENT). This means that the components' left sides should be aligned. Furthermore, it means that all three components are positioned as far left in their container as possible.

In the second figure, all three components have an X alignment of 0.5 (Component.CENTER_ALIGNMENT). This means that the components' centers should be aligned, and that the components should be positioned in the horizontal center of their container.

In the third figure, the components have an X alignment of 1.0 (Component.RIGHT_ALIGNMENT). You can guess what that means for the components' alignment and position relative to their container.

You might be wondering what happens when the components have both restricted maximum sizes and different X alignments. The next figure shows an example of this:

Oracle Java Tutorials and Materials, Oracle Java Certifications

As you can see, the left side of the component with an X alignment of 0.0 (Component.LEFT_ALIGNMENT) is aligned with the center of the component that has the 0.5 X alignment (Component.CENTER_ALIGNMENT), which is aligned with the right side of the component that has an X alignment of 1.0 (Component.RIGHT_ALIGNMENT). Mixed alignments like this are further discussed in Fixing Alignment Problems.

What if none of the components has a maximum width? In this case, if all the components have identical X alignment, then all components are made as wide as their container. If the X alignments are different, then any component with an X alignment of 0.0 (left) or 1.0 (right) will be smaller. All components with an intermediate X alignment (such as center) will be as wide as their container. Here are two examples:

Oracle Java Tutorials and Materials, Oracle Java CertificationsOracle Java Tutorials and Materials, Oracle Java Certifications

To get to know BoxLayout better, you can run your own experiments with BoxLayoutDemo2.

Try this: 

1. Click the Launch button to run BoxLayoutDemo2 using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.Launches the BoxLayoutDemo2 example

You can see the code in BoxLayoutDemo2.java.
You will see a window like the one above that contains three rectangles. Each rectangle is an instance of BLDComponent, which is a JComponent subclass.

2. Click inside one of the rectangles.
This is how you change the rectangle's X alignment.

3. Click the check box at the bottom of the window.
This turns off restricted sizing for all the rectangles.

4. Make the window taller.
This makes the rectangles' container larger than the sum of the rectangles' preferred sizes. The container is a JPanel that has a red outline, so that you can tell where the container's edges are.

Using Invisible Components as Filler

Each component controlled by a box layout butts up against its neighboring components. If you want to have space between components, you can either add an empty border to one or both components, or insert invisible components to provide the space. You can create invisible components with the help of the Box class.

The Box class defines a nested class, Box.Filler, that is a transparent component that paints nothing, and is used to provide space between other components. However, Filler is not actually invisible, because setVisible(false) is not invoked. The Box class provides convenience methods to help you create common kinds of filler. The following table gives details about creating invisible components with Box and Box.Filler.

Type Size Constraints How to Create
rigid area
Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java

Box.createRigidArea(size)
glue, horizontal
Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java
Box.createHorizontalGlue()
glue, vertical
Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java
Box.createVerticalGlue()
custom Box.Filler (as specified) new Box.Filler(minSize, prefSize, maxSize)

Here is how you generally use each type of filler:

Rigid area

Use this when you want a fixed-size space between two components. For example, to put 5 pixels between two components in a left-to-right box, you can use this code:
container.add(firstComponent);
container.add(Box.createRigidArea(new Dimension(5,0)));
container.add(secondComponent);

Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle JavaOracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java

Note: The Box class provides another kind of filler for putting fixed space between components: a vertical or horizontal strut. Unfortunately, struts have unlimited maximum heights or widths (for horizontal and vertical struts, respectively). This means that if you use a horizontal box within a vertical box, for example, the horizontal box can sometimes become too tall. For this reason, we recommend that you use rigid areas instead of struts.

Glue

Use this to specify where excess space in a layout should go. Think of it as a kind of elastic glue — stretchy and expandable, yet taking up no space unless you pull apart the components that it is sticking to. For example, by putting horizontal glue between two components in a left-to-right box, you make any extra space go between those components, instead of to the right of all the components. Here is an example of making the space in a left-to-right box go between two components, instead of to the right of the components:
container.add(firstComponent);
container.add(Box.createHorizontalGlue());
container.add(secondComponent);

Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle JavaOracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java

Custom Box.Filler

Use this to specify a component with whatever minimum, preferred, and maximum sizes you want. For example, to create some filler in a left-to-right layout that puts at least 5 pixels between two components and ensures that the container has a minimum height of 100 pixels, you could use this code:
container.add(firstComponent);
Dimension minSize = new Dimension(5, 100);
Dimension prefSize = new Dimension(5, 100);
Dimension maxSize = new Dimension(Short.MAX_VALUE, 100);
container.add(new Box.Filler(minSize, prefSize, maxSize));
container.add(secondComponent);

Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle JavaOracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java

Fixing Alignment Problems

Two types of alignment problems sometimes occur with BoxLayout:
  • A group of components all have the same alignment, but you want to change their alignment to make them look better. For example, instead of having the centers of a group of left-to-right buttons all in a line, you might want the bottoms of the buttons to be aligned. Here is an example:
Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java
  • Two or more components controlled by a BoxLayout have different default alignments, which causes them to be mis-aligned. For example, as the following shows, if a label and a panel are in a top-to-bottom box layout, the label's left edge is, by default, aligned with the center of the panel.
Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java

In general, all the components controlled by a top-to-bottom BoxLayout object should have the same X alignment. Similarly, all the components controlled by a left-to-right Boxlayout should generally have the same Y alignment. You can set a JComponent's X alignment by invoking its setAlignmentX method. An alternative available to all components is to override the getAlignmentX method in a custom subclass of the component class. Similarly, you set the Y alignment of a component by invoking the setAlignmentY method or by overriding getAlignmentY.

Here is an example, taken from an application called BoxAlignmentDemo, of changing the Y alignments of two buttons so that the bottoms of the buttons are aligned:

button1.setAlignmentY(Component.BOTTOM_ALIGNMENT);
button2.setAlignmentY(Component.BOTTOM_ALIGNMENT);

Click the Launch button to run BoxAlignmentDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.

By default, most components have center X and Y alignment. However, buttons, combo boxes, labels, and menu items have a different default X alignment value: LEFT_ALIGNMENT. The previous picture shows what happens if you put a left-aligned component such as a label together with a center-aligned component in a container controlled by a top-to-bottom BoxLayout.

The BoxAlignmentDemo program gives examples of fixing mismatched alignment problems. Usually, it is as simple as making an offending button or label be center aligned. For example:

label.setAlignmentX(Component.CENTER_ALIGNMENT);

Specifying Component Sizes

As mentioned before, BoxLayout pays attention to a component's requested minimum, preferred, and maximum sizes. While you are fine-tuning the layout, you might need to adjust these sizes.

Sometimes the need to adjust the size is obvious. For example, a button's maximum size is generally the same as its preferred size. If you want the button to be drawn wider when additional space is available, then you need to change its maximum size.

Sometimes, however, the need to adjust size is not so obvious. You might be getting unexpected results with a box layout, and you might not know why. In this case, it is usually best to treat the problem as an alignment problem first. If adjusting the alignments does not help, then you might have a size problem. We'll discuss this further a bit later.

Note: Although BoxLayout pays attention to a component's maximum size, many layout managers do not. For example, if you put a button in the bottom part of a BorderLayout, the button will probably be wider than its preferred width, no matter what the button's maximum size is. BoxLayout, on the other hand, never makes a button wider than its maximum size.
You can change the minimum, preferred, and maximum sizes in two ways:
  • By invoking the appropriate setXxxSize method (which is defined by the JComponent class). For example:
comp.setMinimumSize(new Dimension(50, 25));
comp.setPreferredSize(new Dimension(50, 25));
comp.setMaximumSize(new Dimension(Short.MAX_VALUE,
                                  Short.MAX_VALUE));
  • By overriding the appropriate getXxxSize method. For example:
...//in a subclass of a component class:
public Dimension getMaximumSize() {
    size = getPreferredSize();
    size.width = Short.MAX_VALUE;
    return size;
}

If you are running into trouble with a box layout and you have ruled out alignment problems, then the trouble might well be size-related. For example, if the container controlled by the box layout is taking up too much space, then one or more of the components in the container probably needs to have its maximum size restricted.

You can use two techniques to track down size trouble in a box layout:
  • Add a garish line border to the outside of the Swing components in question. This lets you see what size they really are. For example:
comp.setBorder(BorderFactory.createCompoundBorder(
                   BorderFactory.createLineBorder(Color.red),
                   comp.getBorder()));
  • Use System.out.println to print the components' minimum, preferred, and maximum sizes, and perhaps their bounds.
The Box Layout API

The following tables list the commonly used BoxLayout and Box constructors and methods. The API for using box layouts falls into these categories:

Creating BoxLayout objects
Constructor or Method Purpose
BoxLayout(Container, int) Creates a BoxLayout instance that controls the specified Container. The integer argument specifies the axis along which the container's components should be laid out. When the container has the default component orientation, BoxLayout.LINE_AXIS specifies that the components be laid out from left to right, and BoxLayout.PAGE_AXIS specifies that the components be laid out from top to bottom.
Box(int) Creates a Box — a container that uses a BoxLayout with the specified axis.
static Box createHorizontalBox()
(in Box)
Creates a Box that lays out its components from left to right.
static Box createVerticalBox()
(in Box)
Creates a Box that lays out its components from top to bottom.

Creating Space Fillers
These methods are defined in the Box class.
Constructor or Method Purpose
Component createRigidArea(Dimension) Create a rigid component.
Component createHorizontalGlue()
Component createVerticalGlue()
Component createGlue()
Create a glue component. Horizontal glue and vertical glue can be very useful.
Component createHorizontalStrut()
Component createVerticalStrut()
Create a "strut" component. We recommend using rigid areas instead of struts.
Box.Filler(Dimension, Dimension, Dimension) Creates a component with the specified minimum, preferred, and maximum sizes (with the arguments specified in that order). See the custom Box.Filler discussion, earlier in this section, for details.

Other useful methods
MethodPurpose
void changeShape(Dimension, Dimension, Dimension) (in Box.Filler)Change the minimum, preferred, and maximum sizes of the recipient Box.Filler object. The layout changes accordingly.

Examples that Use Box Layouts

The following table lists some of the many examples that use box layouts.

Example Where Described- Notes
BoxLayoutDemo2 This page-Uses a box layout to create a centered column of components.
BoxAlignmentDemo This page-Demonstrates how to fix common alignment problems.
BoxLayoutDemo This page-Lets you play with alignments and maximum sizes.
ListDialog This page- A simple yet realistic example of using both a top-to-bottom box layout and a left-to-right one. Uses horizontal glue, rigid areas, and empty borders. Also sets the X alignment of a component.
InternalFrameEventDemo How to Write an Internal Frame Listener-Uses a top-to-bottom layout to center buttons and a scroll pane in an internal frame.
MenuGlueDemo Customizing Menu Layout-Shows how to right-align a menu in the menu bar, using a glue component.
MenuLayoutDemo Customizing Menu Layout-Shows how to customize menu layout by changing the menu bar to use a top-to-bottom box layout, and the popup menu to use a left-to-right box layout.
ConversionPanel.java in the Converter demo How to Use Panels-Aligns two components in different box-layout-controlled containers by setting the components' widths to be the same, and their containers' widths to be the same.

◉ How to Use CardLayout


Note: This lesson covers writing layout code by hand, which can be challenging. If you are not interested in learning all the details of layout management, you might prefer to use the GroupLayout layout manager combined with a builder tool to lay out your GUI. One such builder tool is the NetBeans IDE. Otherwise, if you want to code by hand and do not want to use GroupLayout, then GridBagLayout is recommended as the next most flexible and powerful layout manager.

If you are interested in using JavaFX to create your GUI.

The following figure represents a snapshot of an application that uses the CardLayout class to switch between two panels.

Java Tutorials and Materials, Java Certifications, Java Guides

Java Tutorials and Materials, Java Certifications, Java Guides

Click the Launch button to run CardLayoutDemo using Java™ Web Start (download Java SE). Alternatively, to compile and run the example yourself, consult the example index.

The complete code of this demo is in the CardLayoutDemo.java file.

The CardLayout class manages two or more components (usually JPanel instances) that share the same display space. When using the CardLayout class, let the user choose between the components by using a combo box. The CardLayoutDemo application is an example to illustrate this feature.

Another way to accomplish the same task is to use a tabbed pane. The following picture shows a tabbed pane version of the preceding example:

Java Tutorials and Materials, Java Certifications, Java Guides

Because a tabbed pane provides its own GUI, using a tabbed pane is simpler than using the CardLayout class. For example, implementing the preceding example using a tabbed pane results in a program with fewer lines of code.

Click the Launch button to run TabDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.

The complete code of this demo is in the TabDemo.java file.

Conceptually, each component that a CardLayout manages is like a playing card or trading card in a stack, where only the top card is visible at any time. You can choose the card that is showing in any of the following ways:
  • By asking for either the first or last card, in the order it was added to the container
  • By flipping through the deck backwards or forwards
  • By specifying a card with a specific name
The CardLayoutDemo class uses the last scheme.

The following code snippet from the CardLayoutDemo.java application creates the CardLayout object and the components it manages.

//Where instance variables are declared:
JPanel cards;
final static String BUTTONPANEL = "Card with JButtons";
final static String TEXTPANEL = "Card with JTextField";

//Where the components controlled by the CardLayout are initialized:
//Create the "cards".
JPanel card1 = new JPanel();
...
JPanel card2 = new JPanel();
...

//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, BUTTONPANEL);
cards.add(card2, TEXTPANEL);

To add a component to a container that a CardLayout object manages, specify a string that identifies the component being added. For example, in this demo, the first panel has the string "Card with JButtons", and the second panel has the string "Card with JTextField". In this demo those strings are also used in the combo box.

To choose which component a CardLayout object shows, put additional code in your code example:

//Where the GUI is assembled:
//Put the JComboBox in a JPanel to get a nicer look.
JPanel comboBoxPane = new JPanel(); //use FlowLayout
String comboBoxItems[] = { BUTTONPANEL, TEXTPANEL };
JComboBox cb = new JComboBox(comboBoxItems);
cb.setEditable(false);
cb.addItemListener(this);
comboBoxPane.add(cb);
...
pane.add(comboBoxPane, BorderLayout.PAGE_START);
pane.add(cards, BorderLayout.CENTER);
...

//Method came from the ItemListener class implementation,
//contains functionality to process the combo box item selecting
public void itemStateChanged(ItemEvent evt) {
    CardLayout cl = (CardLayout)(cards.getLayout());
    cl.show(cards, (String)evt.getItem());
}

This example shows that to use the show method of the CardLayout class, you must set the currently visible component. The first argument in the show method is the container the CardLayout controls — that is, the container of the components the CardLayout manages. The second argument is the string that identifies the component to show. This string is the same string that was used when adding the component to the container.

The CardLayout API


The following table lists the CardLayout class methods that are used to choose a component. For each method, the first argument is the container for which the CardLayout is the layout manager (the container of the cards the CardLayout controls).

Method Purpose
first (Container parent) Flips to the first card of the container.
next (Container parent) Flips to the next card of the container. If the currently visible card is the last one, this method flips to the first card in the layout.
previous (Container parent) Flips to the previous card of the container. If the currently visible card is the first one, this method flips to the last card in the layout.
last (Container parent) Flips to the last card of the container.
show (Container parent, String name) Flips to the component that was added to this layout with the specified name, using the addLayoutComponent method.

Examples that Use CardLayout


Only one example in this trail uses CardLayout, and this is the CardLayoutDemo. Generally, our examples use tabbed panes instead of CardLayout, since a tabbed pane provides its own GUI.

◉ How to Use FlowLayout

Note: This lesson covers writing layout code by hand, which can be challenging. If you are not interested in learning all the details of layout management, you might prefer to use the GroupLayout layout manager combined with a builder tool to lay out your GUI. One such builder tool is the NetBeans IDE. Otherwise, if you want to code by hand and do not want to use GroupLayout, then GridBagLayout is recommended as the next most flexible and powerful layout manager.
If you are interested in using JavaFX to create your GUI.

The FlowLayout class provides a very simple layout manager that is used, by default, by the JPanel objects. The following figure represents a snapshot of an application that uses the flow layout:

Oracle Java Tutorials, SAP Certifications

Click the Launch button to run FlowLayoutDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.

The complete code of this demo is in the FlowLayoutDemo.java file.

The FlowLayout class puts components in a row, sized at their preferred size. If the horizontal space in the container is too small to put all the components in one row, the FlowLayout class uses multiple rows. If the container is wider than necessary for a row of components, the row is, by default, centered horizontally within the container. To specify that the row is to aligned either to the left or right, use a FlowLayout constructor that takes an alignment argument. Another constructor of the FlowLayout class specifies how much vertical or horizontal padding is put around the components.

The code snippet below creates a FlowLayout object and the components it manages.

FlowLayout experimentLayout = new FlowLayout();

...

    compsToExperiment.setLayout(experimentLayout);

    compsToExperiment.add(new JButton("Button 1"));
    compsToExperiment.add(new JButton("Button 2"));
    compsToExperiment.add(new JButton("Button 3"));
    compsToExperiment.add(new JButton("Long-Named Button 4"));
    compsToExperiment.add(new JButton("5"));

Select either the Left to Right or Right to Left option and click the Apply orientation button to set up the component's orientation. The following code snippet applies the Left to Right components orientation to the experimentLayout.

        compsToExperiment.setComponentOrientation(
                ComponentOrientation.LEFT_TO_RIGHT);

The FlowLayout API

The following table lists constructors of the FlowLayout class.

Constructor Purpose
FlowLayout() Constructs a new FlowLayout object with a centered alignment and horizontal and vertical gaps with the default size of 5 pixels.
FlowLayout(int align) Creates a new flow layout manager with the indicated alignment and horizontal and vertical gaps with the default size of 5 pixels. The alignment argument can be FlowLayout.LEADING, FlowLayout.CENTER, or FlowLayout.TRAILING. When the FlowLayout object controls a container with a left-to right component orientation (the default), the LEADING value specifies the components to be left-aligned and the TRAILING value specifies the components to be right-aligned.
FlowLayout (int align, int hgap, int vgap) Creates a new flow layout manager with the indicated alignment and the indicated horizontal and vertical gaps. The hgap and vgap arguments specify the number of pixels to put between components.

Examples that Use FlowLayout

The following table lists code examples that use the FlowLayout class and provides links to related sections.

Example Where Described Notes
FlowLayoutDemo This page Sets up a content pane to use FlowLayout. If you set the RIGHT_TO_LEFT constant to true and recompile, you can see how FlowLayout handles a container that has a right-to-left component orientation.
CardLayoutDemo How to Use CardLayout Centers a component nicely in the top part of a BorderLayout, and puts the component in a JPanel that uses a FlowLayout.
ButtonDemo How to Use Buttons, Check Boxes, and Radio Buttons Uses the default FlowLayout of a JPanel.
TextInputDemo How to Use Formatted Text Fields Uses a panel with a right-aligned FlowLayout presenting two buttons.

◉ How to Use GridBagLayout

Note: This lesson covers writing layout code by hand, which can be challenging. If you are not interested in learning all the details of layout management, you might prefer to use the GroupLayout layout manager combined with a builder tool to lay out your GUI. One such builder tool is the NetBeans IDE. Otherwise, if you want to code by hand and do not want to use GroupLayout, then GridBagLayout is recommended as the next most flexible and powerful layout manager.


If you are interested in using JavaFX to create your GUI.

Here is a picture of an example that uses GridBagLayout.

Oracle Java Tutorials and Materials, Oracle Certifications, Java Guides

Click the Launch button to run GridBagLayoutDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.

The code for GridBagDemo is in GridBagLayoutDemo.java.

package layout;

/*
 * GridBagLayoutDemo.java requires no other files.
 */

import java.awt.*;
import javax.swing.JButton;
import javax.swing.JFrame;

public class GridBagLayoutDemo {
    final static boolean shouldFill = true;
    final static boolean shouldWeightX = true;
    final static boolean RIGHT_TO_LEFT = false;

    public static void addComponentsToPane(Container pane) {
        if (RIGHT_TO_LEFT) {
            pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        }

        JButton button;
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
//natural height, maximum width
c.fill = GridBagConstraints.HORIZONTAL;
}

button = new JButton("Button 1");
if (shouldWeightX) {
c.weightx = 0.5;
}
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
pane.add(button, c);

button = new JButton("Button 2");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 1;
c.gridy = 0;
pane.add(button, c);

button = new JButton("Button 3");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 2;
c.gridy = 0;
pane.add(button, c);

button = new JButton("Long-Named Button 4");
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 40;      //make this component tall
c.weightx = 0.0;
c.gridwidth = 3;
c.gridx = 0;
c.gridy = 1;
pane.add(button, c);

button = new JButton("5");
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 0;       //reset to default
c.weighty = 1.0;   //request any extra vertical space
c.anchor = GridBagConstraints.PAGE_END; //bottom of space
c.insets = new Insets(10,0,0,0);  //top padding
c.gridx = 1;       //aligned with button 2
c.gridwidth = 2;   //2 columns wide
c.gridy = 2;       //third row
pane.add(button, c);
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("GridBagLayoutDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Set up the content pane.
        addComponentsToPane(frame.getContentPane());

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

GridBagLayout is one of the most flexible — and complex — layout managers the Java platform provides. A GridBagLayout places components in a grid of rows and columns, allowing specified components to span multiple rows or columns. Not all rows necessarily have the same height. Similarly, not all columns necessarily have the same width. Essentially, GridBagLayout places components in rectangles (cells) in a grid, and then uses the components' preferred sizes to determine how big the cells should be.

The following figure shows the grid for the preceding applet. As you can see, the grid has three rows and three columns. The button in the second row spans all the columns; the button in the third row spans the two right columns.

Oracle Java Tutorials and Materials, Oracle Certifications, Java Guides

If you enlarge the window as shown in the following figure, you will notice that the bottom row, which contains Button 5, gets all the new vertical space. The new horizontal space is split evenly among all the columns. This resizing behavior is based on weights the program assigns to individual components in the GridBagLayout. You will also notice that each component takes up all the available horizontal space — but not (as you can see with button 5) all the available vertical space. This behavior is also specified by the program.

Oracle Java Tutorials and Materials, Oracle Certifications, Java Guides

The way the program specifies the size and position characteristics of its components is by specifying constraints for each component. The preferred approach to set constraints on a component is to use the Container.add variant, passing it a GridBagConstraints object, as demonstrated in the next sections.

The following sections explain the constraints you can set and provide examples.

Specifying Constraints

The following code is typical of what goes in a container that uses a GridBagLayout. You will see a more detailed example in the next section.

JPanel pane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

//For each component to be added to this container:
//...Create the component...
//...Set instance variables in the GridBagConstraints instance...
pane.add(theComponent, c);

As you might have guessed from the above example, it is possible to reuse the same GridBagConstraints instance for multiple components, even if the components have different constraints. However, it is recommended that you do not reuse GridBagConstraints, as this can very easily lead to you introducing subtle bugs if you forget to reset the fields for each new instance.

Note: The following discussion assumes that the GridBagLayout controls a container that has a left-to-right component orientation.

You can set the following GridBagConstraints instance variables:

gridx, gridy

Specify the row and column at the upper left of the component. The leftmost column has address gridx=0 and the top row has address gridy=0. Use GridBagConstraints.RELATIVE (the default value) to specify that the component be placed just to the right of (for gridx) or just below (for gridy) the component that was added to the container just before this component was added. We recommend specifying the gridx and gridy values for each component rather than just using GridBagConstraints.RELATIVE; this tends to result in more predictable layouts.

gridwidth, gridheight

Specify the number of columns (for gridwidth) or rows (for gridheight) in the component's display area. These constraints specify the number of cells the component uses, not the number of pixels it uses. The default value is 1. Use GridBagConstraints.REMAINDER to specify that the component be the last one in its row (for gridwidth) or column (for gridheight). Use GridBagConstraints.RELATIVE to specify that the component be the next to last one in its row (for gridwidth) or column (for gridheight). We recommend specifying the gridwidth and gridheight values for each component rather than just using GridBagConstraints.RELATIVE and GridBagConstraints.REMAINDER; this tends to result in more predictable layouts.

Note: GridBagLayout does not allow components to span multiple rows unless the component is in the leftmost column or you have specified positive gridx and gridy values for the component.

fill

Used when the component's display area is larger than the component's requested size to determine whether and how to resize the component. Valid values (defined as GridBagConstraints constants) include NONE (the default), HORIZONTAL (make the component wide enough to fill its display area horizontally, but do not change its height), VERTICAL (make the component tall enough to fill its display area vertically, but do not change its width), and BOTH (make the component fill its display area entirely).

ipadx, ipady

Specifies the internal padding: how much to add to the size of the component. The default value is zero. The width of the component will be at least its minimum width plus ipadx*2 pixels, since the padding applies to both sides of the component. Similarly, the height of the component will be at least its minimum height plus ipady*2 pixels.

insets

Specifies the external padding of the component -- the minimum amount of space between the component and the edges of its display area. The value is specified as an Insets object. By default, each component has no external padding.

anchor

Used when the component is smaller than its display area to determine where (within the area) to place the component. Valid values (defined as GridBagConstraints constants) are CENTER (the default), PAGE_START, PAGE_END, LINE_START, LINE_END, FIRST_LINE_START, FIRST_LINE_END, LAST_LINE_END, and LAST_LINE_START.

Here is a picture of how these values are interpreted in a container that has the default, left-to-right component orientation.

FIRST_LINE_START PAGE_START FIRST_LINE_END
LINE_START CENTER LINE_END
LAST_LINE_START PAGE_END LAST_LINE_END

Version note: The PAGE_* and *LINE_* constants were introduced in 1.4. Previous releases require values named after points of the compass. For example, NORTHEAST indicates the top-right part of the display area. We recommend that you use the new constants, instead, since they enable easier localization.

weightx, weighty

Specifying weights is an art that can have a significant impact on the appearance of the components a GridBagLayout controls. Weights are used to determine how to distribute space among columns (weightx) and among rows (weighty); this is important for specifying resizing behavior.
Unless you specify at least one non-zero value for weightx or weighty, all the components clump together in the center of their container. This is because when the weight is 0.0 (the default), the GridBagLayout puts any extra space between its grid of cells and the edges of the container.

Generally weights are specified with 0.0 and 1.0 as the extremes: the numbers in between are used as necessary. Larger numbers indicate that the component's row or column should get more space. For each column, the weight is related to the highest weightx specified for a component within that column, with each multicolumn component's weight being split somehow between the columns the component is in. Similarly, each row's weight is related to the highest weighty specified for a component within that row. Extra space tends to go toward the rightmost column and bottom row.

The next section discusses constraints in depth, in the context of explaining how the example program works.

The Example Explained

Here, again, is a picture of the GridBagLayoutDemo application.

Oracle Java Tutorials and Materials, Oracle Certifications, Java Guides

Click the Launch button to run GridBagLayoutDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.

The following code creates the GridBagLayout and the components it manages. You can find the entire source file in GridBagLayoutDemo.java.

JButton button;
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
                //natural height, maximum width
                c.fill = GridBagConstraints.HORIZONTAL;
}

button = new JButton("Button 1");
if (shouldWeightX) {
                   c.weightx = 0.5;
}
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
pane.add(button, c);

button = new JButton("Button 2");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 1;
c.gridy = 0;
pane.add(button, c);

button = new JButton("Button 3");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 2;
c.gridy = 0;
pane.add(button, c);

button = new JButton("Long-Named Button 4");
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 40;      //make this component tall
c.weightx = 0.0;
c.gridwidth = 3;
c.gridx = 0;
c.gridy = 1;
pane.add(button, c);

button = new JButton("5");
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 0;       //reset to default
c.weighty = 1.0;   //request any extra vertical space
c.anchor = GridBagConstraints.PAGE_END; //bottom of space
c.insets = new Insets(10,0,0,0);  //top padding
c.gridx = 1;       //aligned with button 2
c.gridwidth = 2;   //2 columns wide
c.gridy = 2;       //third row
pane.add(button, c);

This example uses one GridBagConstraints instance for all the components the GridBagLayout manages, however in real-life situations it is recommended that you do not reuse GridBagConstraints, as this can very easily lead to you introducing subtle bugs if you forget to reset the fields for each new instance. Just before each component is added to the container, the code sets (or resets to default values) the appropriate instance variables in the GridBagConstraints object. It then adds the component to its container, specifying the GridBagConstraints object as the second argument to the add method.

For example, to make button 4 be extra tall, the example has this code:

c.ipady = 40;

And before setting the constraints of the next component, the code resets the value of ipady to the default:

c.ipady = 0;

If a component's display area is larger than the component itself, then you can specify whereabouts in the display area the component will be displayed by using the GridBagConstraints.anchor constraint. The anchor constraint's values can be absolute (north, south, east, west, and so on), or orientation-relative (at start of page, at end of line, at the start of the first line, and so on), or relative to the component's baseline. For a full list of the possible values of the anchor constraint, including baseline-relative values,see the API documentation for GridBagConstraints.anchor. You can see in the code extract above that Button 5 specifies that it should be displayed at the end of the display area by setting an anchor at GridBagConstraints.PAGE_END.

Note: The Tutorial's examples used to specify the constraints object a different way, which you might see in other programs as well. Rather than specifying the constraints with the add method, our examples used to invoke the setConstraints method on the GridBagLayout object. For example:

GridBagLayout gridbag = new GridBagLayout();
pane.setLayout(gridbag);
...
gridbag.setConstraints(button, c);
pane.add(button);

However, we recommend you use the Container.add method since it makes for cleaner code than if you were to use setConstraints.

Here is a table that shows all the constraints for each component in GridBagLayoutDemo's content pane. Values that are not the default are marked in boldface. Values that are different from those in the previous table entry are marked in italics.

◉ 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