Building Swing Components
A layout manager is a java.awt class passed to setLayout() to decide how a container arranges its components.
A Window Someone Has to Arrange
Suppose you build a window with several buttons and labels. Somebody has to decide where each piece sits, how far apart they are, and what happens when the window is stretched or shrunk. In Java, that decision is not hard-coded into each component. Instead, a container hands the job to a separate object that knows how to arrange whatever it is given. Understanding that handoff is the first step toward building graphical interfaces that look deliberate rather than accidental.
This article follows one question from start to finish: when you place several components into a container, what actually determines where each one ends up? You will meet the object responsible for that answer, watch it work through a concrete case, and then test your own reasoning on a small example.
Who Decides Where Each Component Goes
The important idea is that the arrangement rule is an object you choose, separate from the components themselves. A button does not know whether it belongs in a row or a grid; the container's layout manager makes that call. Java provides a variety of standard layout managers for this purpose. This article looks at three of them: FlowLayout, BorderLayout, and GridLayout. Only FlowLayout is explained in detail here, and BorderLayout and GridLayout are named so you can recognize them when you meet them later.
Read the diagram as a relationship, not a sequence. The container owns the components and also points to one layout manager. Changing the layout manager changes the arrangement rule without touching the components it arranges. The components are the things being placed; the layout manager is the object that decides the placement.
What a Layout Manager Is
A layout manager is a java.awt class passed to setLayout() to decide how a container arranges its components.
The word to notice is passed. You do not write a layout manager into the component, and you do not ask the button where it should go. You create a layout manager object and hand it to the container through setLayout(). From then on, the container consults that object whenever it needs to position the components it holds. Layout managers are classes in the java.awt package, so the names you will meet are the standard ones that Java supplies.
How FlowLayout Fills a Row
FlowLayout is the simplest of the three layout managers covered here. Its rule can be stated in a few words: it lines components up in a row across the container. Each component is drawn at its preferred size, which is the size that component itself reports as ideal. The layout manager does not stretch components to fill space, and it does not decide sizes on its own.
- 1Start at the left edge of the container and place the first component at its preferred size.
- 2Place the next component in the same row, immediately after the previous one.
- 3Before placing each component, check whether it still fits in the remaining width of the current row.
- 4If the next component does not fit, start a new row and place that component at the left edge of the new row.
- 5Repeat until there are no components left to place.
The row break is decided by available width, not by a fixed count of components. Two identical sets of components can produce one row in a wide container and two rows in a narrow one.
Tracing a Narrowed Window
What do you think happens?
If the container is narrowed so that the row cannot hold every component, what happens to the components at the end of the sequence?
Reveal answer
They move down to a new row.
FlowLayout does not shrink components below their preferred size. When the next component does not fit in the current row, it starts a new row, so the components at the end of the sequence move down.
The before and after views show the effect of narrowing the container. In the wide container, all five buttons fit on one row. In the narrow container, A, B, and C still fit on the first row, but D does not, so D starts a second row and E follows it there. Only the placement of D and E changed. Their size did not, and neither did the order of the buttons. The narrower width simply forced a row break earlier in the sequence.
Predicting Where a Row Breaks
A JPanel uses FlowLayout. It holds five buttons A, B, C, D, and E, each at its preferred width. The panel is narrowed so that A, B, and C fit in the first row but D does not fit after C. Where does each button land?
- 1Place the first row
A is placed at the left edge, then B, then C, each at its preferred size, because each still fits in the remaining width.
- 2Test D
Before placing D,
FlowLayoutchecks whether D fits in the remaining width of the current row. It does not, so a row break occurs. - 3Start the second row
D is placed at the left edge of a new row, and E is placed after it because E fits in that row.
Row 1 holds A, B, and C. Row 2 holds D and E. No component was resized or reordered.
The Default Layout of a JPanel
You do not always have to choose a layout manager. A JPanel uses a FlowLayout by default. Unless you specify something else by calling the panel's setLayout() method, the panel will arrange its components in rows using the FlowLayout rule described above.
Mistakes Beginners Make with Layout Managers
Common mistake Expecting FlowLayout to stretch components to fill the container
What it looks likeA button appears the same width after the window is enlarged.
Why it failsFlowLayoutdraws each component at its preferred size and does not stretch it.Do this insteadExpect components to keep their preferred size and to change only their position.
Common mistake Assuming the number of rows is fixed
Why it failsRow breaks depend on available width, so the same components can produce different numbers of rows at different container sizes.
Do this insteadTest the layout at several window widths to see how the rows change.
Common mistake Thinking each button decides its own position
Why it failsThe container hands placement to its layout manager object, so the button does not know whether it belongs in a row or a grid.
Do this insteadLook at the layout manager set on the container when you want to understand or change placement.
Common mistake Forgetting that a JPanel already has a layout manager
Why it failsA
JPanelusesFlowLayoutby default, so placement follows theFlowLayoutrule even when you never callsetLayout().Do this insteadCall setLayout() only when you want a rule other than the default FlowLayout.
Practice: Predicting the Row Breaks
A JPanel uses the default FlowLayout and holds six buttons labeled 1 through 6. The panel is wide enough for buttons 1, 2, and 3 on the first row, and button 4 does not fit after button 3. Predict which buttons are on the first row and which are on the second row. Then explain what would change, and what would stay the same, if the panel were made wider.
Hints
- Ask whether each button fits in the remaining width of the current row before placing it.
- Remember that components keep their preferred size and their order.
- A wider container may fit more buttons on the first row, but it does not reorder or resize them.
Key Takeaways
- A layout manager is a
java.awtclass passed tosetLayout()to decide how a container arranges its components. FlowLayoutlines components up in a row at their preferred size and starts a new row when the next component does not fit.- Row breaks depend on available width, so the same components can form different numbers of rows at different container sizes.
- A
JPanelusesFlowLayoutby default, andsetLayout()replaces that default with a different layout manager.