epubjs
Version:
Render ePub documents in the browser, across many devices
80 lines (79 loc) • 8.47 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Chapter 19. Layout Managers</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="chapter" title="Chapter 19. Layout Managers"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-19"/>Chapter 19. Layout Managers</h1></div></div></div><p>A <span class="emphasis"><em>layout manager</em></span> arranges the child components of
a container, as shown in <a class="xref" href="ch19.html#learnjava3-CHP-19-FIG-1" title="Figure 19-1. A layout manager at work">Figure 19-1</a>. It
positions and sets the size of components within the container’s display
area according to a particular layout scheme. The layout manager’s job is to
fit the components into the available area while maintaining some spatial
relationships among them. AWT and Swing come with several standard layout
managers that will collectively handle most situations; you can also make
your own layout managers if you have special requirements.</p><div class="figure-float"><div class="figure"><a id="learnjava3-CHP-19-FIG-1"/><div class="figure-contents"><div class="mediaobject"><a id="I_19_tt1103"/><img src="httpatomoreillycomsourceoreillyimages1707678.png" alt="A layout manager at work"/></div></div><p class="title">Figure 19-1. A layout manager at work</p></div></div><p>Every container has a default layout manager. When you make a new
container, it comes with a <a id="I_indexterm19_id804703" class="indexterm"/><code class="literal">LayoutManager</code> object of the
appropriate type. You can install a new layout manager at any time by using
the <a id="I_indexterm19_id804715" class="indexterm"/><code class="literal">setLayout()</code> method. For
example, we can set the layout manager of a Swing container to a type called
<code class="literal">BorderLayout</code> like so:</p><a id="I_19_tt1104"/><pre class="programlisting"> <code class="n">myContainer</code><code class="o">.</code><code class="na">setLayout</code><code class="o">(</code> <code class="k">new</code> <code class="n">BorderLayout</code><code class="o">()</code> <code class="o">);</code></pre><p>Notice that although we have created a <a id="I_indexterm19_id804743" class="indexterm"/><code class="literal">BorderLayout</code>, we haven’t
bothered to save a reference to it. This is typical; after installing a
layout manager, it usually does its work behind the scenes by interacting
with the container. You rarely call the layout manager’s methods directly,
so you don’t usually need a reference (a notable exception is <code class="literal">CardLayout</code>). However, you do need to know what the
layout manager is going to do with your components as you work with
them.</p><p>The <code class="literal">LayoutManager</code> is consulted
whenever a container’s <a id="I_indexterm19_id804773" class="indexterm"/><code class="literal">doLayout()</code> method is called
to reorganize the contents. It does its job by calling the <code class="literal">setLocation()</code> or <a id="I_indexterm19_id804790" class="indexterm"/><code class="literal">setBounds()</code> methods of the
individual child components to arrange them in the container’s display area.
A container is laid out the first time it is displayed and thereafter
whenever the container’s <a id="I_indexterm19_id804804" class="indexterm"/><code class="literal">revalidate()</code> method is
called. Containers that are a subclass of the <code class="literal">Window</code> class (<code class="literal">Frame</code>, <code class="literal">JFrame</code>,
and <code class="literal">JWindow</code>) are automatically validated
whenever they are packed or resized. Calling <a id="I_indexterm19_id804837" class="indexterm"/><code class="literal">pack()</code> sets the window’s
size as small as possible while granting all its components their preferred
sizes.</p><p>Every component provides three important pieces of information used by
the layout manager in placing and sizing it: a minimum size, a maximum size,
and a preferred size. These sizes are reported by the <a id="I_indexterm19_id804853" class="indexterm"/><code class="literal">getMinimumSize()</code>,
<a id="I_indexterm19_id804864" class="indexterm"/><code class="literal">getMaximumSize()</code>, and
<a id="I_indexterm19_id804875" class="indexterm"/><code class="literal">getPreferredSize()</code> methods
of <code class="literal">Component</code>, respectively. For example,
a plain <code class="literal">JButton</code> object can normally be
changed to any size. However, the button’s designer can provide a preferred
size for a good-looking button. The layout manager might use this size when
there are no other constraints, or it might ignore it, depending on its
scheme. If we give the button a label, the button may need a new minimum
size to display itself properly. The layout manager should generally respect
the button’s minimum size and guarantee that it has at least that much
space. Similarly, a particular component might not be able to display itself
properly if it is too large (perhaps it has to scale up an image); it can
use <code class="literal">getMaximumSize()</code> to report the
largest size it considers acceptable.</p><p>The preferred size of a <code class="literal">Container</code>
object has the same meaning as for any other type of component. However,
because a <code class="literal">Container</code> may hold its own
components and want to arrange them in its own layout, its preferred size is
a function of its layout manager. The layout manager is, therefore, involved
in both sides of the issue. It asks the components in its container for
their preferred (or minimum) sizes in order to arrange them. Based on those
values, it calculates the preferred size for its own container (which can
then be communicated to the container’s parent and so on).</p><p>When a layout manager is called to arrange its components, it is
working within a fixed area. It usually begins by looking at its container’s
dimensions and the preferred or minimum sizes of the child components. It
then doles out screen area and sets the sizes of components according to its
scheme and specific constraints.</p><p>You can set the minimum, preferred, and maximum sizes for a component
with the <a id="I_indexterm19_id804942" class="indexterm"/><code class="literal">setMinimumSize()</code>,
<a id="I_indexterm19_id804952" class="indexterm"/><code class="literal">setMaximumSize()</code>, and
<a id="I_indexterm19_id804963" class="indexterm"/><code class="literal">setPreferredSize()</code> methods.
Take care when setting these properties because generally those values
should be calculated based on the real conditions of the component, not just
fixed at a static value that looks good in one particular case. You can
override the <a id="I_indexterm19_id804977" class="indexterm"/><code class="literal">getMinimumSize()</code>,
<a id="I_indexterm19_id804988" class="indexterm"/><code class="literal">getMaximumSize()</code>, and
<a id="I_indexterm19_id804999" class="indexterm"/><code class="literal">getPreferredSize()</code> methods
of your own components to allow them to calculate those values, but you
should do this only if you are specializing the component and it has new
needs. In general, if you find yourself fighting with a layout manager
because it’s changing the size of one of your components, you are probably
using the wrong kind of layout manager or not composing your user interface
properly. Often it’s easier to use a number of <code class="literal">JPanel</code> objects in a given display, each one with
its own <code class="literal">LayoutManager</code>. Try breaking down
the problem: place related components in their own <code class="literal">JPanel</code> and then arrange the panels in the
container. When that becomes unwieldy, use a constraint-based layout manager
such as <code class="literal">GridBagLayout</code> or <code class="literal">SpringLayout</code>, which we’ll discuss later in this
chapter.</p></div></body></html>