Click here to Skip to main content
13,150,344 members (28,569 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


12 bookmarked
Posted 18 Dec 2013

FreeLayout: A New Java Layout

, 18 Dec 2013
Rate this:
Please Sign up or sign in to vote.
This article presents a new flexible Java layout.


When it is necessary to create a GUI, one of the big headaches is to arrange the several components (buttons, text fields, lists, ...) into the window. The problem turns bigger if the window must be resized and all the components must be repositioned. And more complicated if in the middle of the process you must create another component and place it in the middle of your window. It is not a complicated task but gives a lot of work.

Java has a list of some layouts that help to create your GUIs but this task can be tricky if you are not familiar with them or the layout that you pretend to use is too complex. You can use a simple GUI tool where you drag and drop the components into the window and design the layout that you wish. But I do not like to use those tools (I feel more comfortable writing each line of code).

So, in this article, I propose a class that deals with this problem without the programmer doing anything (almost nothing). I have called it FreeLayout.

Using the code

FreeLayout is composed of only two methods and a constructor.

There are three constructors available and all of them must receive the dimension of the container (or the container itself) to be able to position the components into the container.

public FreeLayout(Dimension size)
public FreeLayout(int width, int height)
public FreeLayout(Container container)

Next, let's look at the method that is responsible for positioning the components into the container:

public void relativeTo(Component component,
		Anchor leftAnchor,
		Anchor topAnchor,
		Anchor rightAnchor,
		Anchor bottomAnchor)


FreeLayout assumes that the component position to be added is defined by four Anchors and each Anchor is defined by a component and a gap.

The component can take two possible values: a valid component object (by valid, I mean that the component has already been added using the relativeTo method and in this case, the Anchor refers to a component, like a button, text editor, ...), or a null object (in this case, the Anchor refers to the border of the container).

The gap is an integer number that can be a positive value or negative one, and the fact being a positive or negative influences the position of the component to be added into the container. Let's assume that the component of the Anchor is non null. In this case, whatever the value of gap is, positive or not, will always correspond to the space that separates the component of the Anchor and the component to be added. On the other hand, if the component of the Anchor is null and the gap is a positive value, then this value refers to the space that separates the border and the component to be added. If the gap is a negative value (and the component remains null), this value refers to a dimension of the component to be added (for the top and bottom anchors, this gap refers to the height of the component, for the left and right anchors, the gap refers to the width of the component).

The following table summarizes what has been explained:

non nullnull
Gappositivegap between
gap between component
and container border
negativegap between
component width/height

So, let's see an example:

		new Anchor(null, 5),
		new Anchor(btn1, 5),
		new Anchor(null, 5),
		new Anchor(null, -20));

In this example, I am adding a component, btn3, to the container, in the following disposition:

  • new Anchor(null, 5): the left side of the btn3 component will be referenced to the left border of the container and the gap between them will be of 5
  • new Anchor(btn1, 5): the top side of the btn3 component will be referenced to the bottom side of btn1 and the gap between them will be of 5
  • new Anchor(null, 5): the right side of the btn3 component will be referenced to the right side of the container and the gap between them will be of 5. This makes the button width go from one end to the other of the container
  • new Anchor(null, -20): the bottom side of the btn3 component is not referenced to any surrounding component because the component is a null object and the gap is a negative value. In this case, I am define that my btn3 component will have a height of 20

In the next table, we can see all possible combinations that a component can receive:

Left Component/
Top Component
Left Gap/
Top Gap
Right Component/
Bottom Component
Right Gap/
Bottom Gap
nullnegativenullpositiveWidth/Height - Container border
nullnegativenon nullnegativeWidth/Height - Component
nullnegativenon nullpositiveWidth/Height - Component
nullpositivenullnegativeContainer border - Width/Height
nullpositivenullpositiveContainer border - Container border
nullpositivenon nullnegativeContainer border - Component
nullpositivenon nullpositiveContainer border - Component
non nullnegativenullnegativeComponent - Width/Height
non nullnegativenullpositiveComponent - Container border
non nullnegativenon nullnegativeComponent - Component
non nullnegativenon nullpositiveComponent - Component
non nullpositivenullnegativeComponent - Width/Height
non nullpositivenullpositiveComponent - Container border
non nullpositivenon nullnegativeComponent - Component
non nullpositivenon nullpositiveComponent - Component

So far the components are in the right position that we desire but if the window is resizable, the components must be adapted to the new size of the container. This is done by simply calling the invalidate method in the callback method that is called when the container is resized (this method only updates the components that were added using the relativeTo method):

public void invalidate(int width, int height)
public void invalidate(Dimension size)
public void invalidate(Container container)

This method just accepts the new size of the container (or the container itself, as in the constructor) and FreeLayout will position all components keeping the same parameterization defined previously.


Using this layout is very simple as you will see. I will create a simple window to exemplify how to use the FreeLayout class.

There are two things that are essential to making this layout work: set the frame layout to null and give a size to the pane container. I will also implement a component listener to grab the resize event.

Here is the sample code:

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.*;
import freelayout.*;

public class Main extends JFrame implements ComponentListener {

    // Initialize the FreeLayout
    FreeLayout freeLayout = new FreeLayout(300, 300);
    public Main() {
        super("FreeLayout Demo");
        // Set the frame layoutof to null and set the container size
        getContentPane().setPreferredSize(new Dimension(300, 300));
        JButton open = new JButton("open");
                new Anchor(null, -80),
                new Anchor(null, 5),
                new Anchor(null, 5),
                new Anchor(null, -20));
        JTextField textField1 = new JTextField("Text field 1");
                new Anchor(null, 5),
                new Anchor(null, 5),
                new Anchor(open, 5),
                new Anchor(null, -20));
        JLabel label = new JLabel("Label: ");
                new Anchor(null, 5),
                new Anchor(textField1, 5),
                new Anchor(null, -40),
                new Anchor(null, -20));
        JButton cancel = new JButton("cancel");
                new Anchor(null, -80),
                new Anchor(null, -20),
                new Anchor(null, 5),
                new Anchor(null, 5));
        JButton ok = new JButton("ok");
                new Anchor(null, -80),
                new Anchor(null, -20),
                new Anchor(cancel, 5),
                new Anchor(null, 5));
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(3,3));
        panel.add(new JButton("1"));
        panel.add(new JButton("2"));
        panel.add(new JButton("3"));
        panel.add(new JButton("4"));
        panel.add(new JButton("5"));
        panel.add(new JButton("6"));
        panel.add(new JButton("7"));
        panel.add(new JButton("8"));
        panel.add(new JButton("9"));
                new Anchor(null, 5),
                new Anchor(null, -150),
                new Anchor(null, 5),
                new Anchor(cancel, 5));
        JTextArea textArea = new JTextArea("Texta area: ");
                new Anchor(label, 5),
                new Anchor(textField1, 5),
                new Anchor(null, 5),
                new Anchor(panel, 5));
        // To resize the window
    public static void main(String[] args) {
        new Main().setVisible(true);
    public void componentHidden(ComponentEvent e) {

    public void componentMoved(ComponentEvent e) {

    public void componentResized(ComponentEvent e) {
        freeLayout.invalidate(((JFrame) (e.getComponent())).getContentPane().getSize());

    public void componentShown(ComponentEvent e) {

The result of the code is shown in the next figure:



As you can see, to create a window using FreeLayout is very simple, and repositioning all components when the window is resized is not a problem. FreeLayout handles everything for you.

Any comments will be welcome!


  • 17/12/2013 - Original article.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Filipe Marques
Software Developer (Junior)
Portugal Portugal
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralWell anchored. Pin
Osmund Francis2-Aug-14 9:15
memberOsmund Francis2-Aug-14 9:15 
GeneralRe: Well anchored. Pin
Filipe Marques11-Aug-14 3:32
memberFilipe Marques11-Aug-14 3:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170924.2 | Last Updated 18 Dec 2013
Article Copyright 2013 by Filipe Marques
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid