The Swing layout management

The Java Swing toolkit has two kind of components: containers and children. The containers group children into suitable layouts. To create layouts, we use layout managers.

ZetCode offers a dedicated 196 pages e-book for the Swing layout management process: Java Swing layout management tutorial

Swing has plenty of layout managers available — both built-in and third-party. However, most of the managers are not suitable in modern UI creation.

There are three layout managers that can do the job properly:

MigLayout, GroupLayout, and FormLayout are powerful, flexible layout managers that can cope with most layout requirements.

The following layout managers are obsolete:

These layout managers are simplistic and they cannot fulfill requirements for a modern UI.

Obsolete managers

In this section, we are going to cover obsolete layout managers. These managers are not recommended to use. Only put some time to study them if we need to maintain some legacy code. Otherwise, their usage should be rejected.

FlowLayout manager

This is the simplest layout manager in the Java Swing toolkit. It is the default layout manager for the JPanel component.

It is so simple that it cannot be used for any real layout. This manager is covered in many Java Swing tutorials and therefore, beginners try to use it in their projects not realizing that it cannot be used for anything serious.

When calculating its children size, a flow layout lets each component assume its natural (preferred) size. The manager puts components into a row. In the order, they were added. If they do not fit into one row, they go into the next one. The components can be added from the right to the left or vice versa. The manager allows to align the components. Implicitly, the components are centered and there is 5px space among components and components and the edges of the container.

FlowLayout()
FlowLayout(int align)
FlowLayout(int align, int hgap, int vgap) 

There are three constructors available for the FlowLayout manager. The first one creates a manager with implicit values. Centered with 5px horizontal and vertical spaces. The others allow to specify those parameters.

FlowLayoutEx.java
package com.zetcode;

import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.SwingUtilities;

public class FlowLayoutEx extends JFrame {

    public FlowLayoutEx() {

        initUI();
    }

    private void initUI() {

        JPanel panel = new JPanel();

        JButton button = new JButton("button");
        panel.add(button);

        JTree tree = new JTree();
        panel.add(tree);

        JTextArea area = new JTextArea("text area");
        area.setPreferredSize(new Dimension(100, 100));

        panel.add(area);

        add(panel);

        pack();

        setTitle("FlowLayout Example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            FlowLayoutEx ex = new FlowLayoutEx();
            ex.setVisible(true);
        });
    }
}

The example shows a button, a tree component, and a text area component in the window. If we create an empty tree component, there are some default values inside the component.

JPanel panel = new JPanel();

The implicit layout manager of the JPanel component is a flow layout manager. We do not have to set it manually.

JTextArea area = new JTextArea("text area");
area.setPreferredSize(new Dimension(100, 100));

The flow layout manager sets a preferred size for its components. This means, that in our case, the area component will have 100x100px. If we didn't set the preferred size, the component would have a size of its text. No more, no less. Without the text, the component would not be visible at all. Try to write or delete some text in the area component. The component will grow and shrink accordingly.

panel.add(area);

To put a component inside a container, we simply call the add() method.

FlowLayout
Figure: FlowLayout

GridLayout

The GridLayout layout manager lays out components in a rectangular grid. The container is divided into equally sized rectangles. One component is placed in each rectangle.

GridLayout is very simple and cannot be used for any real layout.

GridLayoutEx.java
package com.zetcode;

import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GridLayoutEx extends JFrame {

    public GridLayoutEx() {

        initUI();
    }

    private void initUI() {

        JPanel panel = new JPanel();

        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        panel.setLayout(new GridLayout(5, 4, 5, 5));

        String[] buttons = {
            "Cls", "Bck", "", "Close", "7", "8", "9", "/", "4",
            "5", "6", "*", "1", "2", "3", "-", "0", ".", "=", "+"
        };

        for (int i = 0; i < buttons.length; i++) {

            if (i == 2) {
                panel.add(new JLabel(buttons[i]));
            } else {
                panel.add(new JButton(buttons[i]));
            }
        }

        add(panel);

        setTitle("GridLayout");
        setSize(350, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            GridLayoutEx ex = new GridLayoutEx();
            ex.setVisible(true);
        });
    }
}

The example shows a skeleton of a simple calculator tool. We put nineteen buttons and one label into the manager. Notice that each button is of the same size.

panel.setLayout(new GridLayout(5, 4, 5, 5));

Here we set the grid layout manager for the panel component. The layout manager takes four parameters. The number of rows, the number of columns and the horizontal and vertical gaps between components.

GridLayout
Figure: GridLayout

BorderLayout

BorderLayout is a simple layout manager that can be handy in certain layouts. It is a default layout manager for JFrame, JWindow, JDialog, JInternalFrame, and JApplet. It has a serious limitiation — it sets the gaps between its children in pixels, thus creating rigid layouts. This leads to non-portable UI, and therefore, its usage is not recommended.

BorderLayout divides the space into five regions: north, west, south, east, and centre. Each region can have only one component. If we need to put more components into a region, we have to put a panel there with a manager of our choice. The components in N, W, S, E regions get their preferred size. The component in the centre takes up the whole space left.

It does not look good if child components are too close to each other. We must put some space among them. Each component in Swing toolkit can have borders around its edges. To create a border, we either create a new instance of an EmptyBorder class or we use a BorderFactory.

BorderEx.java
package com.zetcode;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

public class BorderEx extends JFrame {

    public BorderEx() {

        initUI();
    }

    private void initUI() {

        JPanel bottomPanel = new JPanel(new BorderLayout());
        JPanel topPanel = new JPanel();

        topPanel.setBackground(Color.gray);
        topPanel.setPreferredSize(new Dimension(250, 150));
        bottomPanel.add(topPanel);

        bottomPanel.setBorder(new EmptyBorder(new Insets(20, 20, 20, 20)));

        add(bottomPanel);

        pack();

        setTitle("Border Example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            BorderEx ex = new BorderEx();
            ex.setVisible(true);
        });
    }
}

The example will display a gray panel and border around it.

JPanel bottomPanel = new JPanel(new BorderLayout());
JPanel topPanel = new JPanel();

We place a panel into a panel. The bottom panel has a BorderLayout manager.

bottomPanel.add(topPanel);

Here we placed the top panel into the bottom panel component. More precisely, we placed it into the center area of its BorderLayout manager.

bottomPanel.setBorder(new EmptyBorder(new Insets(20, 20, 20, 20)));

Here we created a 20px border around the bottom panel. The border values are as follows: top, left, bottom and right. Note that creating fixed insets (spaces) is not portable.

Border example
Figure: Border example

The next example will show a typical usage of a border layout manager.

BorderLayoutEx.java
package com.zetcode;

import java.awt.BorderLayout;
import java.awt.Insets;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

public class BorderLayoutEx extends JFrame {

    public BorderLayoutEx() {

        initUI();
    }

    private void initUI() {

        JMenuBar menubar = new JMenuBar();
        JMenu file = new JMenu("File");

        menubar.add(file);
        setJMenuBar(menubar);

        JToolBar toolbar = new JToolBar();
        toolbar.setFloatable(false);

        ImageIcon exit = new ImageIcon("exit.png");
        JButton bexit = new JButton(exit);
        bexit.setBorder(new EmptyBorder(0, 0, 0, 0));
        toolbar.add(bexit);

        add(toolbar, BorderLayout.NORTH);

        JToolBar vertical = new JToolBar(JToolBar.VERTICAL);
        vertical.setFloatable(false);
        vertical.setMargin(new Insets(10, 5, 5, 5));

        ImageIcon driveIcon = new ImageIcon("drive.png");
        ImageIcon compIcon = new ImageIcon("computer.png");
        ImageIcon printIcon = new ImageIcon("printer.png");

        JButton driveBtn = new JButton(driveIcon);
        driveBtn.setBorder(new EmptyBorder(3, 0, 3, 0));

        JButton compBtn = new JButton(compIcon);
        compBtn.setBorder(new EmptyBorder(3, 0, 3, 0));
        JButton printBtn = new JButton(printIcon);
        printBtn.setBorder(new EmptyBorder(3, 0, 3, 0));

        vertical.add(driveBtn);
        vertical.add(compBtn);
        vertical.add(printBtn);

        add(vertical, BorderLayout.WEST);

        add(new JTextArea(), BorderLayout.CENTER);

        JLabel statusbar = new JLabel(" Statusbar");
        add(statusbar, BorderLayout.SOUTH);

        setSize(400, 350);
        setTitle("BorderLayout");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            BorderLayoutEx ex = new BorderLayoutEx();
            ex.setVisible(true);
        });
    }
}

The example shows a typical application skeleton. We show a vertical and horizontal toolbars, a statusbar, and a central component (a text area).

BorderLayout is the default layout manager for the JFrame container. So we do not have to set it explicitly.

add(toolbar, BorderLayout.NORTH);

We place the toolbar to the north of the layout.

JButton driveBtn = new JButton(driveIcon);
driveBtn.setBorder(new EmptyBorder(3, 0, 3, 0));

In order to put some empty space around the button, we have to use EmptyBorder. This adds some fixed space to the top and bottom of the button. When we add fixed spaces, the UI is not portable. A 3px space may look OK on a 1280x720 screen but it is inappropriate on a 1920x1200px screen.

add(vertical, BorderLayout.WEST); 

We place the vertical toobar to the west.

add(new JTextArea(), BorderLayout.CENTER);

We place the text area into the center.

add(statusbar, BorderLayout.SOUTH);

The statusbar goes to the south area.

BorderLayout
Figure: BorderLayout

CardLayout

CardLayout is a simple layout manager that treats each component as a card. The container is a stack of these cards. Only one component is visible at a time; the rest is hidden. The first component added to the container is visible by default when the container is initially displayed. This manager has a limited practical use. It can be used to create a wizard or a tabbed pane.

The following example uses a CardLayout manager to create a gallery of images. We use four images of the Krasna Horka castle (before the fire in 2012).

CardLayoutEx.java
package com.zetcode;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class CardLayoutEx extends JFrame {

    private ImageIcon horka1;
    private ImageIcon horka2;
    private ImageIcon horka3;
    private ImageIcon horka4;
    private ImageIcon previ;
    private ImageIcon nexti;

    private JPanel mainPanel;
    private CardLayout layout;

    public CardLayoutEx() {

        initUI();
    }

    private void initUI() {

        mainPanel = new JPanel();
        mainPanel.setBackground(new Color(50, 50, 50));

        mainPanel.setBorder(
                BorderFactory.createEmptyBorder(5, 5, 5, 5)
        );

        layout = new CardLayout();
        mainPanel.setLayout(layout);

        horka1 = new ImageIcon("horka1.jpg");
        horka2 = new ImageIcon("horka2.jpg");
        horka3 = new ImageIcon("horka3.jpg");
        horka4 = new ImageIcon("horka4.jpg");

        previ = new ImageIcon("previous.png");
        nexti = new ImageIcon("next.png");

        JLabel label1 = new JLabel(horka1);
        JLabel label2 = new JLabel(horka2);
        JLabel label3 = new JLabel(horka3);
        JLabel label4 = new JLabel(horka4);

        mainPanel.add(label1);
        mainPanel.add(label2);
        mainPanel.add(label3);
        mainPanel.add(label4);

        add(mainPanel);

        JButton prevButton = new JButton(previ);
        prevButton.addActionListener((ActionEvent e) -> {
            layout.previous(mainPanel);
        });

        JButton nextButton = new JButton(nexti);
        nextButton.addActionListener((ActionEvent e) -> {
            layout.next(mainPanel);
        });

        JPanel btnPanel = new JPanel();
        btnPanel.setBackground(new Color(50, 50, 50));
        btnPanel.add(prevButton);
        btnPanel.add(nextButton);

        add(btnPanel, BorderLayout.SOUTH);

        pack();

        setTitle("Gallery");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(() -> {
            CardLayoutEx ex = new CardLayoutEx();
            ex.setVisible(true);
        });
    }
}

We create two buttons to navigate through the images.

mainPanel = new JPanel();
mainPanel.setBackground(new Color(50, 50, 50));

mainPanel.setBorder(
        BorderFactory.createEmptyBorder(5, 5, 5, 5)
);

We create the main panel component. We set its colour to dark gray. We put 5px around the panel so that its children are not too close to the border of the window.

layout = new CardLayout();
mainPanel.setLayout(layout);

The CardLayout manager is created and set to the main panel.

mainPanel.add(label1);
mainPanel.add(label2);
mainPanel.add(label3);
mainPanel.add(label4);

The label components displaying the images are added to the panel.

JButton prevButton = new JButton(previ);
prevButton.addActionListener((ActionEvent e) -> {
    layout.previous(mainPanel);
});

Clicking on the Previous button the previous() method of the manager is called. It flips to the previous card of the specified container.

add(mainPanel);

We add the main panel to the center area of the border layout of the frame component. If we do not specify explicitly where we place the component, it is added to the center area.

JPanel btnPanel = new JPanel();
btnPanel.setBackground(new Color(50, 50, 50));
btnPanel.add(prevButton);
btnPanel.add(nextButton);

The buttons are added to the button panel.

add(btnPanel, BorderLayout.SOUTH);

Finally, the panel with the buttons is placed into the south area of the BorderLayout manager.

CardLayout
Figure: CardLayout

BoxLayout

BoxLayout manager is a simple layout manager that organizes components in a column or a row. It can create quite sophisticated layouts with nesting. However, this raises the complexity of the layout creation and uses additional resources, notably many other JPanel components. BoxLayout is only able to create fixed spaces; therefore, its layouts are not portable.

BoxLayout has the following constructor:

BoxLayout(Container target, int axis)

The constructor creates a layout manager that will lay out components along the given axis. Unlike other layout managers, BoxLayout takes a container instance as the first parameter in the constructor. The second parameter determines the orientation of the manager. To create a horizontal box, we can use the LINE_AXIS constant. To create a vertical box, we can use the PAGE_AXIS constant.

The box layout manager is often used with the Box class. This class creates several invisible components, which affect the final layout.

Let's say we want to put two buttons into the right bottom corner of the window.

BoxLayoutButtonsEx.java
package com.zetcode;

import java.awt.Dimension;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class BoxLayoutButtonsEx extends JFrame {

    public BoxLayoutButtonsEx() {

        initUI();
    }

    private void initUI() {

        JPanel basic = new JPanel();
        basic.setLayout(new BoxLayout(basic, BoxLayout.Y_AXIS));
        add(basic);

        basic.add(Box.createVerticalGlue());

        JPanel bottom = new JPanel();
        bottom.setAlignmentX(1f);
        bottom.setLayout(new BoxLayout(bottom, BoxLayout.X_AXIS));

        JButton ok = new JButton("OK");
        JButton close = new JButton("Close");

        bottom.add(ok);
        bottom.add(Box.createRigidArea(new Dimension(5, 0)));
        bottom.add(close);
        bottom.add(Box.createRigidArea(new Dimension(15, 0)));

        basic.add(bottom);
        basic.add(Box.createRigidArea(new Dimension(0, 15)));

        setTitle("Two Buttons");
        setSize(300, 150);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            BoxLayoutButtonsEx ex = new BoxLayoutButtonsEx();
            ex.setVisible(true);
        });
    }
}

The following drawing illustrates the example.

Two buttons
Figure: Two buttons

We create two panels. The basic panel has a vertical box layout. The bottom panel has a horizontal one. We will put a bottom panel into the basic panel. We right align the bottom panel. The space between the top of the window and the bottom panel is expandable. It is done by the vertical glue.

basic.setLayout(new BoxLayout(basic, BoxLayout.Y_AXIS));

Here we create a basic panel with the vertical BoxLayout.

JPanel bottom = new JPanel();
bottom.setAlignmentX(1f);
bottom.setLayout(new BoxLayout(bottom, BoxLayout.X_AXIS));

The bottom panel is right aligned. This is done by the setAlignmentX() method. The panel has a horizontal layout.

bottom.add(Box.createRigidArea(new Dimension(5, 0)));

We put some rigid space between the buttons.

basic.add(bottom);

Here we put the bottom panel with a horizontal box layout to the vertical basic panel.

basic.add(Box.createRigidArea(new Dimension(0, 15)));

We also put some space between the bottom panel and the border of the window.

BoxLayout buttons example
Figure: BoxLayout buttons example

When we use a BoxLayout manager, we can set a rigid area between our components.

BoxLayoutRigidAreaEx.java
package com.zetcode;

import java.awt.Dimension;
import java.awt.Insets;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

public class BoxLayoutRigidAreaEx extends JFrame {

    public BoxLayoutRigidAreaEx() {

        initUI();
    }

    private void initUI() {

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

        panel.setBorder(new EmptyBorder(new Insets(40, 60, 40, 60)));

        panel.add(new JButton("Button"));
        panel.add(Box.createRigidArea(new Dimension(0, 5)));
        panel.add(new JButton("Button"));
        panel.add(Box.createRigidArea(new Dimension(0, 5)));
        panel.add(new JButton("Button"));
        panel.add(Box.createRigidArea(new Dimension(0, 5)));
        panel.add(new JButton("Button"));

        add(panel);

        pack();

        setTitle("RigidArea");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            BoxLayoutRigidAreaEx ex = new BoxLayoutRigidAreaEx();
            ex.setVisible(true);
        });
    }
}

In this example, we display four buttons. By default, there is no space between the buttons. To put some space among them, we add some rigid area.

panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

We use a vertical BoxLayout manager for our panel.

panel.add(new JButton("Button"));
panel.add(Box.createRigidArea(new Dimension(0, 5)));
panel.add(new JButton("Button"));

We add buttons and create a rigid area in between them.

Rigid area
Figure: Rigid area

Tip of the Day

JDeveloper has a dialog window called Tip of the Day.

Tip of the Day
Figure: Tip of the Day

We will create a similar dialog. We will use a combination of various layout managers, namely, a border layout, flow layout, and box layout manager.

package zetcode;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.KeyEvent;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;


public class TipOfDayExample extends JDialog {


    public TipOfDayExample() {

        initUI();
    }

    public final void initUI() {

        JPanel basic = new JPanel();
        basic.setLayout(new BoxLayout(basic, BoxLayout.Y_AXIS));
        add(basic);

        JPanel topPanel = new JPanel(new BorderLayout(0, 0));
        topPanel.setMaximumSize(new Dimension(450, 0));
        JLabel hint = new JLabel("JDeveloper Productivity Hints");
        hint.setBorder(BorderFactory.createEmptyBorder(0, 25, 0, 0));
        topPanel.add(hint);

        ImageIcon icon = new ImageIcon("jdev.png");
        JLabel label = new JLabel(icon);
        label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        topPanel.add(label, BorderLayout.EAST);

        JSeparator separator = new JSeparator();
        separator.setForeground(Color.gray);

        topPanel.add(separator, BorderLayout.SOUTH);

        basic.add(topPanel);

        JPanel textPanel = new JPanel(new BorderLayout());
        textPanel.setBorder(BorderFactory.createEmptyBorder(15, 25, 15, 25));
        JTextPane pane = new JTextPane();

        pane.setContentType("text/html");
        String text = "<p><b>Closing windows using the mouse wheel</b></p>" +
            "<p>Clicking with the mouse wheel on an editor tab closes the window. " +
            "This method works also with dockable windows or Log window tabs.</p>";
        pane.setText(text);
        pane.setEditable(false);
        textPanel.add(pane);

        basic.add(textPanel);

        JPanel boxPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 0));

        JCheckBox box = new JCheckBox("Show Tips at startup");
        box.setMnemonic(KeyEvent.VK_S);

        boxPanel.add(box);
        basic.add(boxPanel);

        JPanel bottom = new JPanel(new FlowLayout(FlowLayout.RIGHT));

        JButton ntip = new JButton("Next Tip");
        ntip.setMnemonic(KeyEvent.VK_N);
        JButton close = new JButton("Close");
        close.setMnemonic(KeyEvent.VK_C);

        bottom.add(ntip);
        bottom.add(close);
        basic.add(bottom);

        bottom.setMaximumSize(new Dimension(450, 0));

        setTitle("Tip of the Day");
        setSize(new Dimension(450, 350));
        setResizable(false);
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        setLocationRelativeTo(null);
    }


    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                TipOfDayExample ex = new TipOfDayExample();
                ex.setVisible(true);
            }
        });
    }
}

The example uses a mix of layout managers. Simply we put four panels into the vertically organized basic panel.

JPanel basic = new JPanel();
basic.setLayout(new BoxLayout(basic, BoxLayout.Y_AXIS));
add(basic);

This is the very bottom panel. It has a vertical box layout manager. The basic panel is added to the default JDialog component. This component has a border layout manager by default.

JPanel topPanel = new JPanel(new BorderLayout(0, 0));

The topPanel panel has a border layout manager. We will put three components into it. Two labels and a separator.

topPanel.setMaximumSize(new Dimension(450, 0));

If we want to have a panel that is not greater than its components, we must set its maximum size. The zero value is ignored. The manager calculates the necessary heights.

JPanel textPanel = new JPanel(new BorderLayout());
...
textPanel.add(pane);

The text pane component is added to the center area of the border layout manager. It takes all space left. Exactly, as we wanted.

JPanel boxPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 0));

The check box is shown in the boxPanel panel. It is left aligned. The flow layout manager has a 20px horizontal gap. Other components have 25px. Why is that? It is because the flow layout manager puts some space to between the component and the edge as well.

JPanel bottom = new JPanel(new FlowLayout(FlowLayout.RIGHT));
...
bottom.setMaximumSize(new Dimension(450, 0));

The bottom panel displays two buttons. It has a right aligned flow layout manager. In order to show the buttons on the right edge of the dialog, the panel must stretch horizontally from the beginning to the end.

Tip of the Day
Figure: Tip of the Day

No manager

It is possible to go without a layout manager. There might be few situations where we might not need a layout manager. (Maybe positioning a few images at some irregular locations.) But in most cases to create truly portable, complex applications, we need layout managers.

Without layout manager, we position components using absolute values.

AbsoluteLayoutEx.java
package com.zetcode;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class AbsoluteLayoutEx extends JFrame {

    public AbsoluteLayoutEx() {

        initUI();
    }

    private void initUI() {

        setLayout(null);

        JButton okBtn = new JButton("OK");
        okBtn.setBounds(50, 50, 80, 25);

        JButton clsBtn = new JButton("Close");
        clsBtn.setBounds(150, 50, 80, 25);

        add(okBtn);
        add(clsBtn);

        setTitle("Absolute positioning");
        setSize(300, 250);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            AbsoluteLayoutEx ex = new AbsoluteLayoutEx();
            ex.setVisible(true);
        });
    }
}

This simple example shows two buttons.

setLayout(null);

We use absolute positioning by providing null to the setLayout() method. (The JFrame component has a default layout manager, the BorderLayout.)

okBtn.setBounds(50, 50, 80, 25);

The setBounds() method positions the Ok button. The parameters are the x and y coordinates and the width and height of the component.

Absolute layout
Figure: Absolute layout

In this chapter, we have mentioned layout management in Swing.