UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

80 lines (79 loc) 8.47 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <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>