Laying Out Components Within a Container |
Unless you explicitly tell a container not to use a layout manager, the container is associated with its very own instance of a layout manager. This layout manager is automatically consulted each time the container might need to change its appearance. Most layout managers don't require programs to directly call their methods.How to Choose a Layout Manager
The layout managers provided by the Java platform have different strengths and weaknesses. This section discusses some common layout scenarios and which layout managers might work for each scenario. If none of these layout managers is right for your situation, feel free to use other layout managers that you write or find.
- Scenario: You need to display a component in as much space as it can get.
- Consider using
BorderLayout
orGridBagLayout
. If you useBorderLayout
, you'll need to put the space-hungry component in the center. WithGridBagLayout
, you'll need to set the constraints for the component so thatfill=GridBagConstraints.BOTH
. Another possibility is to useBoxLayout
, 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 hold the components and using either theJPanel
's defaultFlowLayout
manager or theBoxLayout
manager.
- 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 have a complex layout with many components.
- Consider either using
GridBagLayout
or grouping the components into one or moreJPanel
s to simplify layout. EachJPanel
might use a different layout manager.How to Create a Layout Manager and Associate It with a Container
As we mentioned in Layout Management, by convention each container has a layout manager. AllJPanel
objects are initialized to use aFlowLayout
. The content pane for allJApplet
,JDialog
, andJFrame
objects is initialized to use aBorderLayout
. Other Swing containers tend to have very specialized layout managers or, as in the case ofJLayeredPane
, no layout manager at all. [PENDING: reword other layout stuff to reflect this.]If you want to use a container's default layout manager, you don't have to do a thing. The constructor for the container creates a layout manager instance and initializes the container to use it.
To use a layout manager other than the default layout manager, you must create an instance of the desired layout manager class and tell the container to use it. Normally, you would do this only for
JPanel
s and content panes. The following statement creates aBorderLayout
manager and sets it up as the layout manager for a panel.Here is an example of making aaJPanel.setLayout(new BorderLayout());FlowLayout
object the layout manager for a applet's content pane:For examples of creating each layout manager, see the how-to section for the particular layout manager.//In a JApplet subclass: Container contentPane = getContentPane(); contentPane.setLayout(new FlowLayout());Rules of Thumb for Using Layout Managers
TheContainer
methods that result in calls to the container's layout manager areadd
,remove
,removeAll
,doLayout
,invalidate
,getAlignmentX
,getAlignmentY
,getPreferredSize
,getMinimumSize
, andgetMaximumSize
. Theadd
,remove
, andremoveAll
methods add and remove components from a container; you can call them at any time. ThedoLayout
method, which is called as the result of any paint request to a container or of avalidate
call on the container, requests that the container place and size itself and the components it contains; you don't call thedoLayout
method directly. [PENDING: check with aim]If you change the size of a component, even by indirect means such as changing its font, the component should automatically resize and repaint itself. If that doesn't happen for some reason, then you should invoke the
revalidate
method on the component. This request is passed up the containment hierarchy until it encounters a container, such as a scroll pane or top-level container, that shouldn't be affected by the component's resizing. (This is determined by calling the container'sisValidateRoot
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. After callingrevalidate
on a component, you should then invokerepaint
on it. [PENDING: check]The
getAlignmentX
andgetAlignmentY
methods are called by layout managers that try to align groups of components.BoxLayout
is the only layout manager we discuss that calls these methods. [PENDING: OverlayLayout also calls these methods and implements LayoutManager2; be careful about promises about "Java platform"; "layout managers discussed in this trail/book" is more accurate.]The
getPreferredSize
,getMinimumSize
, andgetMaximumSize
methods return the container's ideal, minimum, and maximum sizes, respectively. The values returned are just hints; a layout manager can ignore them.
Laying Out Components Within a Container |