<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Tomas Pavek&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/tpavek/" />
<modified>2007-01-03T15:09:15Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/tpavek/311</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2006, tpavek</copyright>
<entry>
<title>Getting to know GroupLayout, part 2</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/tpavek/archive/2006/03/getting_to_know_1.html" />
<modified>2007-01-03T15:09:15Z</modified>
<issued>2006-03-01T14:43:49Z</issued>
<id>tag:weblogs.java.net,2006:/blog/tpavek/311.4223</id>
<created>2006-03-01T14:43:49Z</created>
<summary type="text/plain">The  first part of this article provided the theory behind GroupLayout. Now it&apos;s time to try it on a real example.</summary>
<author>
<name>tpavek</name>

<email>Tomas.Pavek@sun.com</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/tpavek/">
<![CDATA[<style type="text/css">
<!--
.java-block-comment {color: #737373}
.java-string-literal {color: #99006b}
.java-layer-method {font-weight: bold}
.java-keywords {color: #000099; font-weight: bold}
.java-numeric-literals {color: #780000}
.java-highlighted { background-color: #d0d0d0}
-->
</style>

<p><i><b>Note:</b> Since Java 6 release, an updated version of this text, including the code samples, is available as part of the Swing trail of Java Tutorial:
<a href="http://java.sun.com/docs/books/tutorial/uiswing/layout/group.html">How to Use GroupLayout</a>, <a href="http://java.sun.com/docs/books/tutorial/uiswing/layout/groupExample.html">GroupLayout example</a></i></p><hr width="20%" align="left">

<p>The <a href="http://weblogs.java.net/blog/tpavek/archive/2006/02/getting_to_know_1.html"> first part</a> of this article provided the theory behind <code>GroupLayout</code>. Now it's time to try it on a real example.
So let's create a layout for this
dialog:</p>
<p><img border="0" src="http://weblogs.java.net/blog/tpavek/find.png" width="348" height="121"></p>
<p>A good way to analyze the layout is to use a top-down decomposition. I'll
describe
the procedure that proved useful to me; step by step to make it clear. Once you get used to
&quot;group thinking&quot;, you'll be able to proceed much
faster.</p>
<p><i>Horizontal layout</i></p>
<p>Examining the horizontal dimension <i> from left to right</i>,&nbsp;we
can see there are 3 groups in a sequence. The first one is actually not a group,
just a component -- the label. The second one is a group containing the text field and
the checkboxes (we'll decompose it later). And the third is a group of the two
buttons. As illustrated here:</p>
<p><img border="0" src="http://weblogs.java.net/blog/tpavek/find_a1.PNG" width="348" height="105"></p>
<p>Let's sketch out the sequential group in code. Note that
<code>GroupLayout.LEADING</code> corresponds to left alignment in the horizontal dimension. Also note we don't specify gaps, assuming the <i>gap auto-insertion</i> feature is turned on.</p>
<pre>    layout.<span class="java-layer-method">setHorizontalGroup</span>(layout.createSequentialGroup()
        .<span class="java-layer-method">add</span>(label)
        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING))
        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING))
    );</pre>

<p>Now let's decompose the group in the middle. This is the hardest one. There's a text field in
parallel with a sequence of two parallel groups each containing two checkboxes.
See the following illustration:</p>

<p><img border="0" src="http://weblogs.java.net/blog/tpavek/find_a2.PNG" width="210" height="111"></p>

<p>Let's add the corresponding code:</p>
<pre>    layout.<span class="java-layer-method">setHorizontalGroup</span>(layout.createSequentialGroup()
        .<span class="java-layer-method">add</span>(label)</pre>
<span class="java-highlighted"><pre style="background-color: #d0d0d0">        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
            .<span class="java-layer-method">add</span>(textField)
            .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createSequentialGroup</span>()
                .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
                    .<span class="java-layer-method">add</span>(caseCheckBox)
                    .<span class="java-layer-method">add</span>(wholeCheckBox))
                .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
                    .<span class="java-layer-method">add</span>(wrapCheckBox)
                    .<span class="java-layer-method">add</span>(backCheckBox))))</pre></span>
<pre>        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING))
    );</pre>

<p>Note we want the text field to be resizable, but that happens automatically
since <code>JTextField</code> returns the right maximum size by default.</p>

<p>The remaining group on the right is trivial: it contains just two buttons. We even don't need the picture ;-) Here's the code:</p>
<pre>    layout.<span class="java-layer-method">setHorizontalGroup</span>(layout.createSequentialGroup()
        .<span class="java-layer-method">add</span>(label)
        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
            .<span class="java-layer-method">add</span>(textField)
            .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createSequentialGroup</span>()
                .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
                    .<span class="java-layer-method">add</span>(caseCheckBox)
                    .<span class="java-layer-method">add</span>(wholeCheckBox))
                .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
                    .<span class="java-layer-method">add</span>(wrapCheckBox)
                    .<span class="java-layer-method">add</span>(backCheckBox))))</pre>
<span class="java-highlighted"><pre style="background-color: #d0d0d0">        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
            .<span class="java-layer-method">add</span>(findButton)
            .<span class="java-layer-method">add</span>(cancelButton))</pre></span>
<pre>    );</pre>


<p>And finally, we'd like the buttons to have always the same size, so let's link
them:</p>
<pre>    layout.<span class="java-layer-method">linkSize</span>(<span class="java-keywords">new</span> Component[] { findButton, cancelButton },
                    GroupLayout.HORIZONTAL);</pre>

<p>Now we are done with the horizontal dimension. Let's switch to the vertical dimension. From now,
we'll only need to think about the y
axis.</p>

<p><i>Vertical layout</i></p>

<p>In the vertical dimension, we examine the layout from <i>top to bottom</i>. We
definitely want all the components on the first line aligned on baseline. So
along the vertical axis there is a sequence of the baseline group, followed by a
group of the remaining components. See the following picture.</p>

<p><img border="0" src="http://weblogs.java.net/blog/tpavek/find_a3.PNG" width="384" height="94"></p>

<p>Let's sketch out the code. First, we need to define two parallel groups. Note that
<code>GroupLayout.LEADING</code> corresponds to the top alignment in the
vertical dimension.</p>
<pre>    layout.<span class="java-layer-method">setVerticalGroup</span>(layout.<span class="java-layer-method">createSequentialGroup</span>()
        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.BASELINE))
        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING))
    );</pre>

<p>We can fill the baseline group right away:</p>
<pre>    layout.<span class="java-layer-method">setVerticalGroup</span>(layout.<span class="java-layer-method">createSequentialGroup</span>()</pre>
<span class="java-highlighted"><pre style="background-color: #d0d0d0">        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.BASELINE)
            .<span class="java-layer-method">add</span>(label)
            .<span class="java-layer-method">add</span>(textField)
            .<span class="java-layer-method">add</span>(findButton))</pre></span>
<pre>        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING))
    );</pre>

<p>Now let's look at the bottom group. Note the Cancel button is not on a shared
baseline with
the checkboxes; it is aligned at the top. So the second parallel group comprises
the button and a sequential group of two baseline groups with checkboxes:</p>

<p><img border="0" src="http://weblogs.java.net/blog/tpavek/find_a4.PNG" width="332" height="51"></p>

<p>The corresponding code looks as follows:</p>
<pre>    layout.<span class="java-layer-method">setVerticalGroup</span>(layout.<span class="java-layer-method">createSequentialGroup</span>()
        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.BASELINE)
            .<span class="java-layer-method">add</span>(label)
            .<span class="java-layer-method">add</span>(textField)
            .<span class="java-layer-method">add</span>(findButton))</pre>
<span class="java-highlighted"><pre style="background-color: #d0d0d0">        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
            .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createSequentialGroup</span>()
                .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.BASELINE)
                    .<span class="java-layer-method">add</span>(caseCheckBox)
                    .<span class="java-layer-method">add</span>(wrapCheckBox))
                .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.BASELINE)
                    .<span class="java-layer-method">add</span>(wholeCheckBox)
                    .<span class="java-layer-method">add</span>(backCheckBox)))
            .<span class="java-layer-method">add</span>(cancelButton))</pre></span>
<pre>    );</pre>


<p>So, that's it! We've created a
complete layout including resize behavior without specifying a single
number in pixels. That's a true cross platform layout! Note that we don't
need to specify gaps between components, we get correct spacing automatically
and according to the look and feel guidelines. Here's the complete code for
the Find dialog's layout:</p>

<pre>    GroupLayout layout = <span class="java-keywords">new</span> <span class="java-layer-method">GroupLayout</span>(<span class="java-layer-method">getContentPane</span>());
    <span class="java-layer-method">getContentPane</span>().<span class="java-layer-method">setLayout</span>(layout);
    layout.<span class="java-layer-method">setAutocreateGaps</span>(<span class="java-keywords">true</span>);
    layout.<span class="java-layer-method">setAutocreateContainerGaps</span>(<span class="java-keywords">true</span>);

    layout.<span class="java-layer-method">setHorizontalGroup</span>(layout.<span class="java-layer-method">createSequentialGroup</span>()
        .<span class="java-layer-method">add</span>(label)
        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
            .<span class="java-layer-method">add</span>(textField)
            .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createSequentialGroup</span>()
                .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
                    .<span class="java-layer-method">add</span>(caseCheckBox)
                    .<span class="java-layer-method">add</span>(wholeCheckBox))
                .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
                    .<span class="java-layer-method">add</span>(wrapCheckBox)
                    .<span class="java-layer-method">add</span>(backCheckBox))))
        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
            .<span class="java-layer-method">add</span>(findButton)
            .<span class="java-layer-method">add</span>(cancelButton))
    );
    layout.<span class="java-layer-method">linkSize</span>(<span class="java-keywords">new</span> Component[] { findButton, cancelButton },
                    GroupLayout.HORIZONTAL);

    layout.<span class="java-layer-method">setVerticalGroup</span>(layout.<span class="java-layer-method">createSequentialGroup</span>()
        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.BASELINE)
            .<span class="java-layer-method">add</span>(label)
            .<span class="java-layer-method">add</span>(textField)
            .<span class="java-layer-method">add</span>(findButton))
        .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
            .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createSequentialGroup</span>()
                .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.BASELINE)
                    .<span class="java-layer-method">add</span>(caseCheckBox)
                    .<span class="java-layer-method">add</span>(wrapCheckBox))
                .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.BASELINE)
                    .<span class="java-layer-method">add</span>(wholeCheckBox)
                    .<span class="java-layer-method">add</span>(backCheckBox)))
            .<span class="java-layer-method">add</span>(cancelButton))
    );</pre>

<p>Here is the complete <a href="http://weblogs.java.net/blog/tpavek/Find.java">Find.java</a> file. You can compile
it and run against the Swing Layout Extensions library. Try resizing the dialog
horizontally to see how the layout automatically adjusts to the new size.</p>
<blockquote> The easiest way to test <code>GroupLayout</code> is to use it with NetBeans 5.0
  where it is bundled (just make sure &quot;Swing Layout Extensions&quot; library
  is added in the libraries of the working project).
  <p>The layout manager and related extensions are hosted on <a href="http://swing-layout.dev.java.net">http://swing-layout.dev.java.net</a>
  as one of the <a href="http://swinglabs.dev.java.net/"> Swing Labs</a>
  projects (see the earlier Scott Violet's <a href="http://weblogs.java.net/blog/zixle/archive/2005/06/index.html">announcement</a>).
  You can get the latest version from the <a href="http://swing-layout.dev.java.net/servlets/ProjectDocumentList">download
  page</a>.</p>
</blockquote>
<hr width="20%" align="left">

<p>That's all for now. In future articles, I'll take a look at dynamic changes of the
layout, compare <code>GroupLayout</code> with other layout managers, describe its limitations,
and I'll cover other topics of interest based on your feedback.</p>]]>

</content>
</entry>
<entry>
<title>Getting to know GroupLayout, part 1</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/tpavek/archive/2006/02/getting_to_know_2.html" />
<modified>2007-01-03T15:07:47Z</modified>
<issued>2006-02-22T16:58:12Z</issued>
<id>tag:weblogs.java.net,2006:/blog/tpavek/311.4181</id>
<created>2006-02-22T16:58:12Z</created>
<summary type="text/plain">GroupLayout is a new layout manager that was developed as a Swing Labs project in conjunction with Matisse, the new GUI builder in NetBeans 5.0. Though the layout manager was originally designed to suit the GUI builder needs, it is also quite handy for manual coding. This article will help you get up to speed with how GroupLayout works and shows you how you can start building GUIs using GroupLayout, whether you choose to use Matisse or write your own code.</summary>
<author>
<name>tpavek</name>

<email>Tomas.Pavek@sun.com</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/tpavek/">
<![CDATA[<style type="text/css">
<!--
.java-block-comment {color: #737373}
.java-string-literal {color: #99006b}
.java-layer-method {font-weight: bold}
.java-keywords {color: #000099; font-weight: bold}
.java-numeric-literals {color: #780000}
.java-highlighted { background-color: #e0e0e0}
-->
</style>

<p><i><b>Note:</b> Since Java 6 release, an updated version of this text, including the code samples, is available as part of the Swing trail of Java Tutorial:
<a href="http://java.sun.com/docs/books/tutorial/uiswing/layout/group.html">How to Use GroupLayout</a>, <a href="http://java.sun.com/docs/books/tutorial/uiswing/layout/groupExample.html">GroupLayout example</a></i></p><hr width="20%" align="left">

<p><code>GroupLayout</code> is a new layout manager that was developed as a
Swing Labs project in conjunction
with Matisse, the new GUI builder in NetBeans 5.0. There is a chance that
<code>GroupLayout</code> will become a part of JDK in the future. Though the layout manager was
originally designed to suit the GUI builder needs, it is also quite handy for manual coding. This
article will help you get up to speed with how <code>GroupLayout</code> works and shows you
how you can start building GUIs using <code>GroupLayout</code>, whether you choose to
use Matisse or write your own code.</p>
<p>In this article, I'm going to cover some of the theory behind <code>GroupLayout</code>. If you prefer to start with
examples, you can skip this part and wait for the next post which will bring
a complete example with detailed explanation.</p>
<p><b>Design principle: independent dimensions</b></p>
<p>The first thing you need to know about <code>GroupLayout</code> is that it works with



horizontal and vertical layout separately. This is not that uncommon, but
unlike other layout managers <code>GroupLayout</code>  does not use a single <i>constraints</i>
object or method to completely specify a component's layout; the layout is defined for
each dimension independently. This might seem a bit unusual at first
sight, but
it actually makes things easier because the definition is simpler. When defining the <i> horizontal</i> 
layout, you don't need to worry about the <i> vertical</i>
 dimension, and vice versa. The layout along the horizontal axis is quite independent
of the layout along the vertical axis. By focusing just on one dimension at a
time you only have to solve half the problem,
the other dimension can be solved later. The downside of this approach is that each component needs to be defined twice in the layout.
You'll soon find out if you forgot to do this, because <code>GroupLayout</code> will generate
an exception ;-)</p>
<p>This dimension independence is quite a powerful concept, similar to <code>SpringLayout</code>,
because it provides flexibility other
layouts can't offer. We'll get back to this topic later; but first let's see what makes <code>GroupLayout</code> <i>different</i> from <code>SpringLayout</code>
and other layout managers.</p>
<p><b>Layout organization: hierarchical groups</b></p>
<p><code>GroupLayout</code> uses two types of arrangements -- sequential and parallel, combined with
hierarchical composition. These
principles are quite basic and well known from Swing.</p>
<p>(1) With <b>sequential</b> arrangement, the components are simply placed
one after another. Just like <code>BoxLayout</code> or <code>FlowLayout</code> would do along one
axis. The position of each component is defined as being relative to the
preceding component. This is important for platform independent layout.</p>
<p>(2) The second way places the components in <b>parallel</b>,&nbsp;on top of each other in the same space,
and aligned
along a common reference point. For example, the components can be right-aligned along
the horizontal
axis, or baseline-aligned along the vertical axis, etc.</p>
<p>Usually, components placed in parallel in one dimension are in a sequence in
the other, so they don't overlap. See the examples below.</p>
<p>What makes these two principles powerful is that they can be combined (nested)
hierarchically. For this purpose <code>GroupLayout</code> defines <b>layout
groups</b>.
A group is either sequential or parallel and may contain components, gaps and other groups.
The size of a sequential group is the sum of the sizes of the contained elements,
and the size of a parallel group corresponds to the size of the largest element.
Defining a
layout means defining how the components should be grouped by combining the
sequential and parallel arrangements. This resembles nested panels with
<code>BoxLayout</code>, but the groups are quite lightweight compared to panels. There is also a difference in the independent dimensions as
described above. Panels do nesting in both dimensions at once, while groups can
be nested as needed, for each dimension separately.</p>
<p>That's enough theory for now, let's take a look at how it works in practice
with a simple example.</p>
<p><b>Example</b></p>
<p>Let's start with something really simple, just three components in a row:</p>
<p><img border="0" src="http://weblogs.java.net/blog/tpavek/example1a.PNG" width="151" height="31"></p>
<p>We would like to express this layout using groups. Starting with the horizontal
axis it's easy to see there is a <i>sequential
group</i> of 3 components arranged from left to right. Along the vertical axis there is a <i> parallel group</i>
 of the same 3 components (at the same coordinate); let's say they are aligned
along a baseline. See this picture:</p>
<p><img border="0" src="http://weblogs.java.net/blog/tpavek/groups1a.PNG" width="397" height="69"></p>
<p>In pseudo code, the layout specification might look like this (the real code is further below):</p>
<pre>horizontal layout = sequential group { c1, c2, c3 }
vertical layout = parallel group (BASELINE) { c1, c2, c3 }</pre>
<p>Note this illustrates a principle I mentioned earlier; components grouped sequentially in one
dimension usually form a parallel group in the orthogonal dimension.</p>
<p>Now let's add one more component (C4):</p>
<p><img border="0" src="http://weblogs.java.net/blog/tpavek/example1b.PNG" width="160" height="62"></p>
<p>Along the horizontal axis the new component forms a parallel group with C3 (because it occupies the same horizontal space as C3),
let's say we want the components left aligned.
Along the vertical axis C4 forms a sequential group with the
original parallel group of the three components.</p>
<p><img border="0" src="http://weblogs.java.net/blog/tpavek/groups1b.PNG" width="413" height="112"></p>
<p>In pseudo code, the layout specification now looks like this:</p>
<pre>horizontal layout = sequential group { c1, c2, <b>parallel group (LEFT) { </b>c3,<b> c4 }</b> }
vertical layout = <b>sequential group {</b> parallel group (BASELINE) { c1, c2, c3 }, <b>c4 }</b></pre>
<p>Now that you understand the principle of groups, you know the most important
thing about designing layouts with <code>GroupLayout</code>! There are just a few more details
to explain: how to add gaps, how to define
resize behavior, how to write real code, etc.</p>
<p><b>Gaps</b></p>
<p>A gap can be thought of as an invisible component of certain size. Gaps of
arbitrary size can be added to groups just like components or other
groups. Using gaps you can precisely control the distance
between components or from the container border.</p>
<p><code>GroupLayout</code> also defines a symbolic <i>default gap</i> that corresponds to a
<i> preferred
distance</i> between neighboring components (or between a component and container border).
The size of such a gap is not defined by an explicit number, but computed dynamically based on the look and feel the
application is using (the <code>LayoutStyle</code> class is used for this). There
are two advantages to using <b>preferred gaps</b>: you don't have to specify the
pixel sizes of the gaps, and they automatically adjust to the environment the UI runs in,
reflecting the actual platform guidelines.</p>
<p><code>GroupLayout</code> distinguishes between (a) the preferred gap between two components and
(b) the preferred gap between a component and the
container border. There are corresponding methods in the <code>GroupLayout</code> API for adding these
gaps (<code>addPreferredGap</code> and <code>addContainerGap</code>). There are
three types of component gaps: <b>related</b>, <b> unrelated</b> and <b>indented</b>.
The <code>LayoutStyle</code>
class defines corresponding constants (to be used as the first parameter of the <code>addPreferredGap</code>
method): <code>RELATED</code>, <code>UNRELATED</code> and <code>INDENT</code>. The difference between
related and unrelated gap is just in size (the distance between unrelated components is a bit
bigger). Indented represents a preferred horizontal distance of two
components where one of them is positioned underneath the second with an indent.</p>
<p><img border="0" src="http://weblogs.java.net/blog/tpavek/gaps.PNG" width="340" height="77"></p>
<p>To make things easier, <code>GroupLayout</code> can <b>insert gaps
automatically</b>. If you don't add your
own gaps explicitly, it adds the <i>related</i> preferred gaps for you. This is not the
default behavior, you have to turn this feature on by invoking <code>setAutocreateGaps(true)</code> and <code>setAutocreateContainerGaps(true)</code> on the layout.
Then you'll get correct spacing almost for free!</p>
<p><b>How to write code</b></p>
<p>Now, let's take a look at the actual code to create the layout described
above.</p>
<p>Let's assume we have a container named <code>panel</code> and four
components (<code>c1</code>, <code>c2</code>, <code>c3</code>, <code>c4</code>)
which are already set up. First, we create a new <code>GroupLayout</code> object and
associate it with the panel:</p>
<pre>    GroupLayout layout = <span class="java-keywords">new</span> <span class="java-layer-method">GroupLayout</span>(panel);
    panel.<span class="java-layer-method">setLayout</span>(layout);</pre>
<p>We specify automatic gap insertion:</p>
<pre>    layout.<span class="java-layer-method">setAutocreateGaps</span>(<span class="java-keywords">true</span>);
    layout.<span class="java-layer-method">setAutocreateContainerGaps</span>(<span class="java-keywords">true</span>);</pre>
<p>Finally, we define groups and add the components. We establish a root group
for each dimension using
    <code>setHorizontalGroup</code> and <code>setVerticalGroup</code> methods.
Groups are created via <code>createSequentialGroup</code> and <code>createParallelGroup</code>
 methods. Components are added to groups by using a variant of the <code>add</code> method.</p>
<pre>    layout.<span class="java-layer-method">setHorizontalGroup</span>(
        layout.<span class="java-layer-method">createSequentialGroup</span>()
            .<span class="java-layer-method">add</span>(c1)
            .<span class="java-layer-method">add</span>(c2)
            .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING)
                .<span class="java-layer-method">add</span>(c3)
                .<span class="java-layer-method">add</span>(c4))
    );
    layout.<span class="java-layer-method">setVerticalGroup</span>(
        layout.<span class="java-layer-method">createSequentialGroup</span>()
            .<span class="java-layer-method">add</span>(layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.BASELINE)
                .<span class="java-layer-method">add</span>(c1)
                .<span class="java-layer-method">add</span>(c2)
                .<span class="java-layer-method">add</span>(c3))
            .<span class="java-layer-method">add</span>(c4)
    );</pre>

<p>Note that default alignment must be specified for parallel groups. It can be
    one of the following constants defined in the <code>GroupLayout</code> class: <code>LEADING</code>,
    <code>TRAILING</code> and <code>CENTER</code>. These constants are used for both dimensions; in the
    horizontal dimension <code>LEADING</code> means "left", while in the vertical dimension it
means "top". Similarly <code>TRAILING</code> maps to "right" or "bottom". The <code>BASELINE</code>
alignment is valid only in the vertical dimension.

<p>Some notes about the code:
<ul>
  <li><p>Components are not added to the container directly, they
    are added to groups.
    <code>GroupLayout</code>  adds the components to the container automatically
    for you.</p></li>
  <li><p>Note the chained calls of the <code>add</code> methods used to fill the groups.
    The <code>add</code>  method always returns the group on which it is called.
    Thanks to this you don't need to use local variables to hold the groups.</p></li>
  <li><p>It is a good idea to indent the code so it is easy to see the hierarchical structure of the groups. Give
    each component a new line, add one
level of indent for each new group in the hierarchy. A decent source editor will
    help you with pairing the parenthesis to close the <code>createXXXGroup</code> methods.
    By following these simple
    rules it is easier to add a new component, or remove an existing one.</p></li>
</ul>
<p><b>Size of components and resizability</b></p>
<p>The size of each component in a <code>GroupLayout</code> is constrained by three values;
minimum size, preferred size and maximum size. These sizes control how the
component resizes within the layout. The <code>GroupLayout.add(...)</code> method allows the size
constraints to be specified. There is no limit on the number of resizable
components in a layout.</p>
<p>If not specified explicitly, the layout asks the component for its default
sizes (by using the component's <code>getMinimumSize()</code>, <code>getPreferredSize()</code>
and <code>getMaximumSize()</code> methods). Thus you don't need to
specify anything for most of the components, e.g. to make <code>JTextField</code>
resizable or <code>JButton</code> fixed, because the components have the desired resizing
behavior as default. On the other hand you can override the default behavior.
For example you can make a
<code>JTextField</code> fixed or <code>JButton</code> resizable.</p>
<p><code>GroupLayout</code> defines constants that provide precise control over
resize behavior. They can be used as parameters in the <code>add(Component comp, int min, int pref, int max)</code>&nbsp;
method. Here are two examples:</p>
<p>1) To force a component to be resizable (allow shrinking and growing):</p>
<pre>    <i>group</i>.<span class="java-layer-method">add</span>(component, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ...</pre>
<p>This allows the component to resize between zero size (minimum) to any size (<code>Short.MAX_VALUE</code> 
as maximum size means &quot;infinite&quot;). If we wanted the component not to shrink
below its
default minimum size, we'd use <code>GroupLayout.DEFAULT_SIZE</code> instead of <code>0</code>
in the second parameter.</p>
<p>2) To make a component fixed size (suppress resizing):</p>
<pre>    <i>group</i>.<span class="java-layer-method">add</span>(component, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
              GroupLayout.PREFERRED_SIZE) ...</pre>
<p>In these examples the initial size of the component is not altered, its
default size is the component's preferred size. If we
wanted a specific size for the component, we would specify it in the second
parameter instead of using <code>GroupLayout.DEFAULT_SIZE</code>.</p>
<p><b>Resizable gaps</b></p>
<p>Specifying size and resizability applies to gaps as well, including the preferred ones.
For example, you can specify a preferred gap
between two components that acts like a <i> spring</i> pushing the components away
from each other (to the opposite sides of the container). The preferred distance
of the two components is only used as the minimum size of the gap. See the
following snippet:</p>
<pre>    layout.<span class="java-layer-method">createSequentialGroup</span>()
        .<span class="java-layer-method">add</span>(c1)
        .<span class="java-layer-method">addPreferredGap</span>(LayoutStyle.RELATED,
                         GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .<span class="java-layer-method">add</span>(c2);</pre>
<p><b>Justified layout</b></p>
<p>Resizable elements placed in a parallel group are stretched to fill the
space of the group determined by the largest element in the group, so they end up
aligned with the same size. <code>GroupLayout</code>
 also provides control over whether the enclosing parallel group itself should
resize. If group resizing is suppressed, it prevents the contained elements from
growing over the preferred size of the group. This way you can make a block of components
align on both sides, or constrain individual components to have the same size.</p>
<p>Let's try to achieve the same size for two components from our example (<code>c3</code> and <code>c4</code> in the horizontal
dimension):</p>
<pre>    layout.<span class="java-layer-method">createParallelGroup</span>(GroupLayout.LEADING, <span class="java-keywords">false</span>)
      .<span class="java-layer-method">add</span>(c3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
      .<span class="java-layer-method">add</span>(c4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE);</pre>
<p>The underlying mechanism works as follows:</p>
<ol>
  <li>The size of the parallel group is set to the preferred size of the largest
    element; so to the preferred size of <code>c4</code> in our example.</li>
  <li>Resizable elements are stretched to the size of the group. In our example,
    only <code>c3</code> is effectively stretched, the size of <code>c4</code> already corresponds to the size of the
    group.</li>
</ol>
<p>As a result, <code>c3</code> and <code>c4</code> would have the same width.
The components would not resize further because the parallel group itself is not
resizable.</p>
<p><img border="0" src="http://weblogs.java.net/blog/tpavek/same_size_stretched.PNG" width="160" height="62"></p>
<p>Question for attentive readers: Why do we define both components in the
parallel group as resizable in this example? It seems enough to have just <code>c3</code> 
resizable since <code>c4</code>  is not stretched anyway...</p>

<p>(The answer is simple: because of platform and localization independence.
Otherwise we
would have to rely on that <code>c4</code> component is always bigger than <code>c3</code>. But this
may change when the application runs on different platform or is translated to
another language. By having both components resizing they adjust to each other,
no matter which one is bigger at the moment.)</p>

<p><b>Same size of components</b></p>
<p>The previous case is special because the components are in the same parallel
group. But what if we wanted unrelated components to have the same size?
Clearly, the same size can't always be ensured by grouping. The OK and Cancel buttons
in a row at the bottom of a dialog are a good example. For this purpose
<code>GroupLayout</code> provides a <code>linkSize</code> method. This method allows
the size of
arbitrary components to be linked regardless of where they are placed. The resulting size
of the linked components is set
according to the largest component. For example:</p>
<pre>    layout.<span class="java-layer-method">linkSize</span>(<span class="java-keywords">new</span> Component[] { c3, c4 }, GroupLayout.HORIZONTAL);</pre>
<p>Note that in this example the size is linked selectively for the horizontal dimension.</p>
<hr width="20%" align="left">
<p>That's all for today. Now you should know enough about <code>GroupLayout</code> to
start using it!</p>
<blockquote><p>Note: The easiest way to test <code>GroupLayout</code> is to use it with NetBeans 5.0
  where it is bundled (just make sure &quot;Swing Layout Extensions&quot; library
  is present in the libraries of the working project).</p>
  <p>The layout manager and related extensions are hosted on <a href="http://swing-layout.dev.java.net">http://swing-layout.dev.java.net</a>
  as one of the <a href="http://swinglabs.dev.java.net/"> Swing Labs</a>
  projects (see the earlier Scott Violet's <a href="http://weblogs.java.net/blog/zixle/archive/2005/06/index.html">announcement</a>).
  You can get the latest version from the <a href="http://swing-layout.dev.java.net/servlets/ProjectDocumentList">download
  page</a>.</p></blockquote>

<p>Would you like to see more examples of using <code>GroupLayout</code>? In the continuation of this article
I will show how to create a layout for a sample dialog, with detailed
explanation of each step, illustrations, code samples, etc.</p>]]>

</content>
</entry>

</feed>