Posted by Rob Camick on November 6, 2008
A layout manager has two main functions:
- determine the preferred size of the container
- layout the components in the container based on the layout rules
The FlowLayout is a strange animal. It does both of these functions. The preferred size of the container assumes all components will be laid out in a single row. The layout code will wrap components to the next row when the maximum width of the container is encountered. However, the problem is that the functions don’t talk to one another. When the components are wrapped to a new row, the preferred size doesn’t change so you never see the components on the extra row.
What we want is the preferred size to be dynamically calculated as the size of the container is changed. In other words, as the width of the container changes the height will need to be recalculated as well. The WrapLayout extends the FlowLayout to implement this functionality. This will result in synchronizing the preferred size of the container with the layout of the container.
In the following example, the button panel was added to the north of a BorderLayout and the blue panel added to the center. You use the WrapLayout the same as you would use the FlowLayout:
As the frame is resized smaller, the button panel will increase in height and the blue panel will decrease:
When the panel is added to a scroll pane, the size of the scroll pane won’t change, but horizontal and vertical scrollbars will appear as required.
The initial preferred size calculation of the layout manager still assumes all components will be displayed on a single row. So if you pack() a frame the preferred width may be excessive. You can limit the width of the container by using:
buttons.setSize(new Dimension(300, 1));
Note, you must use the setSize() method, this will still allow the preferred size to be dynamically changed.