| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | 
 | <html> | 
 |  | 
 | <head> | 
 | <meta http-equiv="Content-Type" | 
 | 	content="text/html; charset=windows-1252"> | 
 | <title>Understanding Layouts in SWT</title> | 
 | <link rel="stylesheet" href="../article.css" type="text/css" /> | 
 | </head> | 
 | <body> | 
 | <h1>Understanding Layouts in SWT</h1> | 
 |  | 
 | <div class="summary"> | 
 | <h2>Summary</h2> | 
 | <p>When writing applications in SWT, you may need to use <i>layouts</i> | 
 | to give your windows a specific look. A layout controls the position and | 
 | size of children in a <code>Composite</code>. Layout classes are | 
 | subclasses of the abstract class <code>Layout</code>. This article shows | 
 | you how to work with standard layouts, and write your own custom layout | 
 | class.</p> | 
 |  | 
 | <div class="author">By Carolyn MacLeod, OTI</div> | 
 | <div class="copyright">Copyright © 2001, 2002 Object | 
 | Technology International, Inc.</div> | 
 | <div class="date">March 22, 2001</div> | 
 |  | 
 | <div class="author">Revised by Shantha Ramachandran, OTI</div> | 
 | <div class="date">May 02, 2002</div> | 
 |  | 
 | <div class="author">Revised by Wayne Beaton, The Eclipse Foundation</div> | 
 | <div class="copyright">Copyright © 2008 The Eclipse Foundation, Inc.</div> | 
 | <div class="date">May 30, 2008</div> | 
 |  | 
 | <div class="author">Revised by Wayne Beaton, The Eclipse Foundation</div> | 
 | <div class="copyright">Copyright © 2008 The Eclipse Foundation, Inc.</div> | 
 | <div class="date">May 13, 2009</div> | 
 | </div> | 
 |  | 
 | <div class="content"> | 
 |  | 
 | <h2>Overview</h2> | 
 |  | 
 | <p>When writing applications in the <a | 
 | 	href="http://www.eclipse.org/swt">Standard Widget Toolkit</a> (SWT), | 
 | you may need to use <i>layouts</i> to give your windows a specific look. | 
 | A layout controls the position and size of children in a <code>Composite</code>. | 
 | Layout classes are subclasses of the abstract class <code>Layout</code>. | 
 | SWT provides several standard layout classes, and you can write custom | 
 | layout classes.</p> | 
 |  | 
 | <p>In SWT, positioning and sizing does not happen automatically. | 
 | Applications can decide to size and place a <code>Composite</code>'s | 
 | children initially, or in a resize listener. Another option is to | 
 | specify a layout class to position and size the children. If children | 
 | are not given a size, they will have zero size and they cannot be seen.</p> | 
 |  | 
 | <p>The diagram below illustrates a few general terms that are used | 
 | when discussing layouts. The <code>Composite</code> (in this case, a <code>TabFolder</code>) | 
 | has a <i>location</i>, <i>clientArea</i> and <i>trim</i>. The size of | 
 | the <code>Composite</code> is the size of the <i>clientArea</i> plus the | 
 | size of the <code>trim</code>. This <code>Composite</code> has two | 
 | children that are laid out side by side. A <code>Layout</code> is | 
 | managing the size and position of the children. This <code>Layout</code> | 
 | allows <code>spacing</code> between the children, and a <i>margin</i> | 
 | between the children and the edges of the <code>Layout</code>. The size | 
 | of the <code>Layout</code> is the same as the size of the <code>Composite</code>'s | 
 | <i>clientArea</i>.</p> | 
 |  | 
 | <img src="images/GeneralTerms.jpg" /> | 
 |  | 
 | <p>The <i>preferred size</i> of a widget is the minimum size needed | 
 | to show its content. In the case of a <code>Composite</code>, the | 
 | preferred size is the smallest rectangle that contains all of its | 
 | children. If children have been positioned by the application, the <code>Composite</code> | 
 | computes its own preferred size based on the size and position of the | 
 | children. If a <code>Composite</code> is using a layout class to | 
 | position its children, it asks the <code>Layout</code> to compute the | 
 | size of its <code>clientArea</code>, and then it adds in the <code>trim</code> | 
 | to determine its preferred size.</p> | 
 |  | 
 | <h3>Standard Layouts</h3> | 
 |  | 
 | <p>The standard layout classes in the SWT library are:</p> | 
 |  | 
 | <ul> | 
 | 	<li><code>FillLayout</code> lays out equal-sized widgets in a | 
 | 	single row or column</li> | 
 | 	<li><code>RowLayout</code> lays out widgets in a row or rows, with | 
 | 	fill, wrap, and spacing options</li> | 
 | 	<li><code>GridLayout</code> lays out widgets in a grid</li> | 
 | 	<li><code>FormLayout</code> lays out widgets by creating | 
 | 	attachments for each of their sides</li> | 
 | </ul> | 
 |  | 
 | <p>To use the standard layouts, you need to import the SWT layout | 
 | package:</p> | 
 |  | 
 | <pre>import org.eclipse.swt.layout.*;</pre> | 
 |  | 
 | <p>Layouts are pluggable. To set a <code>Composite</code> widget's | 
 | layout, you use the widget's <code>setLayout(Layout)</code> method. In | 
 | the following code, a <code>Shell</code> (a subclass of <code>Composite</code>) | 
 | is told to position its children using a <code>RowLayout</code>:</p> | 
 |  | 
 | <pre>Shell shell = new Shell();
 | 
 | shell.setLayout(new RowLayout());</pre> | 
 |  | 
 | <p>A layout class may have a corresponding layout data class: a | 
 | subclass of <code>Object</code> that contains layout data for a specific | 
 | child. By convention, layout data classes are identified by substituting | 
 | "Data" for "Layout" in the class name. For example, | 
 | the standard layout class <code>RowLayout</code> has a layout data class | 
 | called <code>RowData</code>, the layout class <code>GridLayout</code> | 
 | uses a layout data class called <code>GridData</code>, and the layout | 
 | class <code>FormLayout</code> has a layout data class called <code>FormData</code>. | 
 | A widget's layout data class is set as follows:</p> | 
 |  | 
 | <pre>Button button = new Button(shell, SWT.PUSH);
 | 
 | button.setLayoutData(new RowData(50, 40));</pre> | 
 |  | 
 | <h3>Examples in this Document</h3> | 
 |  | 
 | <p>Most of the snapshots in this document were taken by running | 
 | variations on the following example code. We may change the type of | 
 | layout, the options used, or the type or number of children.</p> | 
 |  | 
 | <pre>import org.eclipse.swt.SWT; | 
 | import org.eclipse.swt.layout.RowLayout; | 
 | import org.eclipse.swt.widgets.Button; | 
 | import org.eclipse.swt.widgets.Display; | 
 | import org.eclipse.swt.widgets.Shell; | 
 |  | 
 | public class LayoutExample { | 
 |     public static void main(String[] args) { | 
 |         Display display = new Display(); | 
 |         Shell shell = new Shell(display); | 
 |         // Create the layout. | 
 |         RowLayout layout = new RowLayout(); | 
 |         // Optionally set layout fields. | 
 |         layout.wrap = true; | 
 |         // Set the layout into the composite. | 
 |         shell.setLayout(layout); | 
 |         // Create the children of the composite. | 
 |         new Button(shell, SWT.PUSH).setText("B1"); | 
 |         new Button(shell, SWT.PUSH).setText("Wide Button 2"); | 
 |         new Button(shell, SWT.PUSH).setText("Button 3"); | 
 |         shell.pack(); | 
 |         shell.open(); | 
 |          | 
 |         while (!shell.isDisposed()) { | 
 |             if (!display.readAndDispatch()) display.sleep(); | 
 |         } | 
 |     } | 
 | }</pre> | 
 |  | 
 | <p>Running the above code results in the following:</p> | 
 |  | 
 | <img src="images/LayoutExample.png" /> | 
 |  | 
 | <p>If the user resizes the shell so that there is no longer room for | 
 | Button 3 on the right, the <code>RowLayout</code> wraps Button 3 to the | 
 | next row, as follows:</p> | 
 |  | 
 | <img src="images/LayoutExampleResized.png" /> | 
 |  | 
 | <p>Using layouts is closely tied with resize, as we shall see. | 
 | Consequently, most of the examples in this document show what would | 
 | happen if the <code>Composite</code> becomes smaller or larger, in order | 
 | to illustrate how the <code>Layout</code> works.</p> | 
 |  | 
 | <h2>FillLayout</h2> | 
 |  | 
 | <p><code>FillLayout</code> is the simplest layout class. It lays out | 
 | widgets in a single row or column, forcing them to be the same size. | 
 | Initially, the widgets will all be as tall as the tallest widget, and as | 
 | wide as the widest. <code>FillLayout</code> does not wrap, and you | 
 | cannot specify margins or spacing. You might use it to lay out buttons | 
 | in a task bar or tool bar, or to stack checkboxes in a <code>Group</code>. | 
 | <code>FillLayout</code> can also be used when a <code>Composite</code> | 
 | only has one child. For example, if a <code>Shell</code> has a single <code>Group</code> | 
 | child, <code>FillLayout</code> will cause the <code>Group</code> to | 
 | completely fill the <code>Shell</code>.</p> | 
 |  | 
 | <p>Here is the relevant portion of the example code. First we create | 
 | a <code>FillLayout</code>, then (if we want vertical) we set its <code>type</code> | 
 | field to <code>SWT.VERTICAL</code>, and set it into the <code>Composite</code> | 
 | (a <code>Shell</code>). The <code>Shell</code> has three push button | 
 | children, "B1", "Wide Button 2", and "Button | 
 | 3". Note that in a <code>FillLayout</code>, children are always the | 
 | same size, and they fill all available space.</p> | 
 |  | 
 | <pre>FillLayout fillLayout = new FillLayout();
 | 
 | fillLayout.type = SWT.VERTICAL;
 | 
 | shell.setLayout(fillLayout);
 | 
 | new Button(shell, SWT.PUSH).setText("B1");
 | 
 | new Button(shell, SWT.PUSH).setText("Wide Button 2");
 | 
 | new Button(shell, SWT.PUSH).setText("Button 3");</pre> | 
 |  | 
 | <p>The following table shows the differences between a horizontal | 
 | and vertical <code>FillLayout</code>, initially and after the parent has | 
 | grown.</p> | 
 |  | 
 | <table> | 
 | 	<tr> | 
 | 		<td> </td> | 
 | 		<td> | 
 | 		<p>Initial</p> | 
 | 		</td> | 
 | 		<td> | 
 | 		<p>After resize</p> | 
 | 		</td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><code>fillLayout.type = SWT.HORIZONTAL</code> | 
 | 		<p>(default)</p> | 
 | 		</td> | 
 | 		<td><img src="images/FillLayoutSampleHorizontal.png" /></td> | 
 | 		<td><img src="images/FillLayoutSampleHorizontalResized.png" /></td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><code>fillLayout.type = SWT.VERTICAL</code></td> | 
 | 		<td><img src="images/FillLayoutSampleVertical.png" /></td> | 
 | 		<td><img src="images/FillLayoutSampleVerticalResized.png" /></td> | 
 | 	</tr> | 
 | </table> | 
 |  | 
 | <h2>RowLayout</h2> | 
 |  | 
 | <p><code>RowLayout</code> is more commonly used than <code>FillLayout</code> | 
 | because of its ability to wrap, and because it provides configurable | 
 | margins and spacing. <code>RowLayout</code> has a number of | 
 | configuration fields. In addition, the height and width of each widget | 
 | in a <code>RowLayout</code> can be specified by setting the widget's <code>RowData</code> | 
 | object using <code>setLayoutData</code>.</p> | 
 |  | 
 | <h3>RowLayoutConfiguration Fields</h3> | 
 |  | 
 | <p>The <code>type</code> field controls whether the <code>RowLayout</code> | 
 | lays out widgets in horizontal rows, or vertical columns. <code>RowLayouts</code> | 
 | are horizontal by default.</p> | 
 |  | 
 | <p>The <code>wrap</code> field controls whether or not the <code>RowLayout</code> | 
 | will wrap widgets into the next row if there isn't enough space in the | 
 | current row. <code>RowLayouts</code> wrap by default.</p> | 
 |  | 
 | <p>If the <code>pack</code> field is true, widgets in a <code>RowLayout</code> | 
 | will take their natural size ("natural size" varies by widget; | 
 | the natural size for a label or push button, for example, is large enough to | 
 | display its textual contents), and they will be aligned as far to the | 
 | left as possible. If pack is false, widgets will fill the available | 
 | space, similar to the widgets in a <code>FillLayout</code>. <code>RowLayouts</code> | 
 | pack by default.</p> | 
 |  | 
 | <p>If the <code>justify</code> field is true, widgets in a <code>RowLayout</code> | 
 | are spread across the available space from left to right. If the parent | 
 | <code>Composite</code> grows wider, the extra space is distributed | 
 | evenly among the widgets. If both <code>pack</code> and <code>justify</code> | 
 | are true, widgets take their natural size, and the extra space is placed | 
 | between the widgets in order to keep them fully justified. By default, <code>RowLayouts</code> | 
 | do not justify.</p> | 
 |  | 
 | <p>The <code>marginLeft</code>, <code>marginTop</code>, <code>marginRight</code>, | 
 | <code>marginBottom</code> and <code>spacing</code> fields control the | 
 | number of pixels between widgets (<code>spacing</code>) and the number | 
 | of pixels between a widget and the side of the parent <code>Composite</code> | 
 | (margin). By default, <code>RowLayouts</code> leave 3 pixels for margins | 
 | and spacing. The margin and spacing fields are shown in the following | 
 | diagram.</p> | 
 |  | 
 | <img src="images/RowLayoutMargins.png" /> | 
 |  | 
 | <h3>RowLayout Examples</h3> | 
 |  | 
 | <p>The following example code creates a <code>RowLayout</code>, sets | 
 | all of its fields to non-default values, and then sets it into a <code>Shell</code>.</p> | 
 |  | 
 | <pre>RowLayout rowLayout = new RowLayout();
 | 
 | rowLayout.wrap = false;
 | 
 | rowLayout.pack = false;
 | 
 | rowLayout.justify = true;
 | 
 | rowLayout.type = SWT.VERTICAL;
 | 
 | rowLayout.marginLeft = 5;
 | 
 | rowLayout.marginTop = 5;
 | 
 | rowLayout.marginRight = 5;
 | 
 | rowLayout.marginBottom = 5;
 | 
 | rowLayout.spacing = 0;
 | 
 | shell.setLayout(rowLayout);</pre> | 
 |  | 
 | <p>If you are using the default field values, you only need one line | 
 | of code:</p> | 
 |  | 
 | <pre>shell.setLayout(new RowLayout());</pre> | 
 |  | 
 | <p>The results of setting specific fields is shown below:</p> | 
 |  | 
 | <table> | 
 | 	<tr> | 
 | 		<td width="150"> </td> | 
 | 		<td> | 
 | 		<p>Initial</p> | 
 | 		</td> | 
 | 		<td> | 
 | 		<p>After resize</p> | 
 | 		</td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><pre>rowLayout.wrap = true; | 
 | rowLayout.pack = true; | 
 | rowLayout.justify = false; | 
 | rowLayout.type = SWT.HORIZONTAL;</pre> | 
 | 		<p>(defaults)</p> | 
 | 		</td> | 
 | 		<td><img src="images/RowLayoutSample01.png" /></td> | 
 | 		<td><img src="images/RowLayoutSample01Resized.png" /><p>and</p><img src="images/RowLayoutSample01ResizedNarrower.png" /></td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><pre>wrap = false</pre> | 
 | 		<p>(clips if not enough space)</p> | 
 | 		</td> | 
 | 		<td><img src="images/RowLayoutSample02.png" /></td> | 
 | 		<td><img src="images/RowLayoutSample02Resized.png" /></td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><pre>pack = false</pre> | 
 | 		<p>(all widgets are the same size)</p> | 
 | 		</td> | 
 | 		<td><img src="images/RowLayoutSample03.png" /></td> | 
 | 		<td><img src="images/RowLayoutSample03Resized.png" /></td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><pre>justify = true</pre> | 
 | 		<p>(widgets are spread across the available space)</p> | 
 | 		</td> | 
 | 		<td><img src="images/RowLayoutSample04.png" /></td> | 
 | 		<td><img src="images/RowLayoutSample04Resized.png" /></td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><pre>type = SWT.VERTICAL</pre> | 
 | 		<p>(widgets are arranged vertically in columns)</p> | 
 | 		</td> | 
 | 		<td><img src="images/RowLayoutSample05.png" /></td> | 
 | 		<td><img src="images/RowLayoutSample05Resized.png" /></td> | 
 | 	</tr> | 
 | </table> | 
 |  | 
 | <h3>Using RowData Objects with RowLayout</h3> | 
 |  | 
 | <p>Each widget controlled by a <code>RowLayout</code> can have its | 
 | initial width and height specified by setting its <code>RowData</code> | 
 | object. The following code uses <code>RowData</code> objects to change | 
 | the initial size of the <code>Buttons</code> in a <code>Shell</code>.</p> | 
 |  | 
 | <pre>package org.eclipse.articles.layouts.samples; | 
 | import org.eclipse.swt.SWT; | 
 | import org.eclipse.swt.layout.RowData; | 
 | import org.eclipse.swt.layout.RowLayout; | 
 | import org.eclipse.swt.widgets.Button; | 
 | import org.eclipse.swt.widgets.Display; | 
 | import org.eclipse.swt.widgets.Shell; | 
 |  | 
 | public class RowDataExample { | 
 | 	public static void main(String[] args) { | 
 | 		Display display = new Display(); | 
 | 		Shell shell = new Shell(display); | 
 | 		shell.setLayout(new RowLayout()); | 
 | 		Button button1 = new Button(shell, SWT.PUSH); | 
 | 		button1.setText("Button 1"); | 
 | 		button1.setLayoutData(new RowData(50, 40)); | 
 | 		Button button2 = new Button(shell, SWT.PUSH); | 
 | 		button2.setText("Button 2"); | 
 | 		button2.setLayoutData(new RowData(50, 30)); | 
 | 		Button button3 = new Button(shell, SWT.PUSH); | 
 | 		button3.setText("Button 3"); | 
 | 		button3.setLayoutData(new RowData(50, 20)); | 
 | 		shell.pack(); | 
 | 		shell.open(); | 
 | 		while (!shell.isDisposed()) { | 
 | 			if (!display.readAndDispatch()) | 
 | 				display.sleep(); | 
 | 		} | 
 | 	} | 
 | }</pre> | 
 |  | 
 | <p>Here is what you see when you run this code.</p> | 
 |  | 
 | <img src="images/RowDataExample.png" /> | 
 |  | 
 | <h2>GridLayout</h2> | 
 |  | 
 | <p>With a <code>GridLayout</code>, | 
 | the widget children of a <code>Composite</code> are laid out in a grid. | 
 | <code>GridLayout</code> has a number of configuration fields, and—like | 
 | <code>RowLayout</code>—the widgets it lays out can have an associated | 
 | layout data object, called <code>GridData</code>. The power of <code>GridLayout</code> | 
 | lies in the ability to configure <code>GridData</code> for each widget | 
 | controlled by the <code>GridLayout</code>.</p> | 
 |  | 
 | <h3>GridLayout Configuration Fields</h3> | 
 |  | 
 | <p>The <code>numColumns</code> field is the most important field in | 
 | a <code>GridLayout</code>, and it is usually the first field an | 
 | application will set. Widgets are laid out in columns from left to | 
 | right, and a new row is created when <code>numColumns</code> + 1 widgets | 
 | are added to the <code>Composite</code>. The default is to have only 1 | 
 | column. The following code creates a <code>Shell</code> with five <code>Button</code> | 
 | children of various widths, managed by a <code>GridLayout</code>. The | 
 | table below shows the grid when <code>numColumns</code> is set to one, two, | 
 | or three.</p> | 
 |  | 
 | <pre>Display display = new Display();
 | 
 | Shell shell = new Shell(display);
 | 
 | GridLayout gridLayout = new GridLayout();
 | 
 | gridLayout.numColumns = 3;
 | 
 | shell.setLayout(gridLayout);
 | 
 | new Button(shell, SWT.PUSH).setText("B1");
 | 
 | new Button(shell, SWT.PUSH).setText("Wide Button 2");
 | 
 | new Button(shell, SWT.PUSH).setText("Button 3");
 | 
 | new Button(shell, SWT.PUSH).setText("B4");
 | 
 | new Button(shell, SWT.PUSH).setText("Button 5");
 | 
 | shell.pack();
 | 
 | shell.open(); | 
 | 
 | 
 | while (!shell.isDisposed()) {
 | 
 | 	if (!display.readAndDispatch()) display.sleep();
 | 
 | }</pre> | 
 |  | 
 | <table> | 
 | 	<tr> | 
 | 		<td><pre>numColumns = 1</pre></td> | 
 | 		<td><pre>numColumns = 2</pre></td> | 
 | 		<td><pre>numColumns = 3</pre></td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><img src="images/GridLayoutSampleNumColumns1.png" /></td> | 
 | 		<td><img src="images/GridLayoutSampleNumColumns2.png" /></td> | 
 | 		<td><img src="images/GridLayoutSampleNumColumns3.png" /></td> | 
 | 	</tr> | 
 | </table> | 
 |  | 
 | <p>The <code>makeColumnsEqualWidth</code> field forces the columns | 
 | to be the same width. The default is <code>false</code>. If we change the example | 
 | above to have three columns of equal width, this is what we would get (note | 
 | that in the absence of further instruction, widgets are left-justified | 
 | in their columns).</p> | 
 |  | 
 | <img src="images/GridLayoutSampleEqualWidth.png" /> | 
 |  | 
 | <p>The <code>marginWidth</code>, <code>marginHeight</code>, <code>horizontalSpacing</code>, | 
 | and <code>verticalSpacing</code> fields in a <code>GridLayout</code> are | 
 | similar to those in a <code>RowLayout</code>. The difference is that the | 
 | left and right margins are grouped into <code>marginWidth</code>, and | 
 | the top and bottom margins are grouped into <code>marginHeight</code>. | 
 | Also, in a <code>GridLayout</code> you can specify <code>horizontalSpacing</code> | 
 | and <code>verticalSpacing</code> independently, whereas in a <code>RowLayout</code>, | 
 | <code>spacing</code> applies to horizontal or vertical depending on the | 
 | type of the <code>RowLayout</code>.</p> | 
 |  | 
 | <h3>GridData Object Fields</h3> | 
 |  | 
 | <p><code>GridData</code> is the layout data object associated with <code>GridLayout</code>. | 
 | To set a widget's <code>GridData</code> object, you use the <code>setLayoutData</code> | 
 | method. For example, to set the <code>GridData</code> for a <code>Button</code>, | 
 | we could do the following:</p> | 
 |  | 
 | <pre>Button button1 = new Button(shell, SWT.PUSH);
 | 
 | button1.setText("B1");
 | 
 | button1.setLayoutData(new GridData());</pre> | 
 |  | 
 | <p>Of course, this code just creates a <code>GridData</code> object | 
 | with all of its fields set to their default values, which is the same as | 
 | not setting the layout data at all. There are two ways to create a <code>GridData</code> | 
 | object with certain fields set. The first is to set the fields directly:</p> | 
 |  | 
 | <pre>GridData gridData = new GridData();
 | 
 | gridData.horizontalAlignment = GridData.FILL;
 | 
 | gridData.grabExcessHorizontalSpace = true;
 | 
 | button1.setLayoutData(gridData);</pre> <img | 
 | 	src="images/GridDataSampleHorizontalFill.png" /> | 
 |  | 
 | <p>One final note about <code>GridData</code> objects before we get | 
 | into their fields: do not reuse <code>GridData</code> objects. Every | 
 | widget in a <code>Composite</code> that is managed by a <code>GridLayout</code> | 
 | must have a unique <code>GridData</code> object. If the layout data for | 
 | a widget in a <code>GridLayout</code> is null at layout time, a unique <code>GridData</code> | 
 | object is created for it.</p> | 
 |  | 
 | <p>The <code>horizontalAlignment</code> and <code>verticalAlignment</code> | 
 | fields specify where to place a widget horizontally and/or vertically | 
 | within its grid cell. Each alignment field can have one of the following | 
 | values:</p> | 
 |  | 
 | <ul> | 
 | 	<li><code>BEGINNING</code></li> | 
 | 	<li><code>CENTER</code></li> | 
 | 	<li><code>END</code></li> | 
 | 	<li><code>FILL</code></li> | 
 | </ul> | 
 |  | 
 | <p>The default horizontalAlignment is BEGINNING (or left-aligned). | 
 | The default verticalAlignment is CENTER.</p> | 
 |  | 
 | <p>Let's go back to our five-button example with three columns, and | 
 | we will vary the <code>horizontalAlignment</code> of Button 5.</p> | 
 |  | 
 | <table> | 
 | 	<tr> | 
 | 		<td><pre>horizontalAlignment = GridData.BEGINNING</pre> | 
 | 		<p>(default)</p> | 
 | 		</td> | 
 | 		<td><img src="images/GridDataSampleBeginning.png" /></td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><pre>horizontalAlignment = GridData.CENTER</pre></td> | 
 | 		<td><img src="images/GridDataSampleCenter.png" /></td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><pre>horizontalAlignment = GridData.END</pre></td> | 
 | 		<td><img src="images/GridDataSampleEnd.png" /></td> | 
 | 	</tr> | 
 | 	<tr> | 
 | 		<td><pre>horizontalAlignment = GridData.FILL</pre></td> | 
 | 		<td><img src="images/GridDataSampleFill.png" /></td> | 
 | 	</tr> | 
 | </table> | 
 |  | 
 | <p>The <code>horizontalIndent</code> field allows you to move a | 
 | widget to the right by a specified number of pixels. This field is | 
 | typically only useful when the <code>horizontalAlignment</code> is <code>BEGINNING</code>. | 
 | We cannot use a style bit to set the indent, so we will indent "Button 5" | 
 | in our example by four pixels as follows:</p> | 
 |  | 
 | <pre>GridData gridData = new GridData(); | 
 | gridData.horizontalIndent = 4; | 
 | button5.setLayoutData(gridData);</pre> <img | 
 | 	src="images/GridDataSampleIndent.png" /> | 
 |  | 
 | <p>The <code>horizontalSpan</code> and <code>verticalSpan</code> | 
 | fields let widgets occupy more than one grid cell. They are often used | 
 | in conjunction with <code>FILL</code> alignment. We can make "Button 5" in our example | 
 | span the last two cells as follows:</p> | 
 |  | 
 | <pre>GridData gridData = new GridData(); | 
 | gridData.horizontalAlignment = GridData.FILL; | 
 | gridData.horizontalSpan = 2; | 
 | button5.setLayoutData(gridData);</pre> <img | 
 | 	src="images/GridDataSampleSpan01.png" /> | 
 |  | 
 | <p>If we decide to make "Wide Button 2" span two cells instead, we | 
 | would end up with this:</p> | 
 |  | 
 | <pre>GridData gridData = new GridData(); | 
 | gridData.horizontalAlignment = GridData.FILL; | 
 | gridData.horizontalSpan = 2; | 
 | button2.setLayoutData(gridData);</pre> <img | 
 | 	src="images/GridDataSampleSpan02.png" /> | 
 |  | 
 | <p>Or we could make "Button 3" span two cells vertically:</p> | 
 |  | 
 | <pre>GridData gridData = new GridData(); | 
 | gridData.verticalAlignment = GridData.FILL; | 
 | gridData.verticalSpan = 2; | 
 | button3.setLayoutData(gridData);</pre> <img | 
 | 	src="images/GridDataSampleSpan03.png" /> | 
 |  | 
 | <p>The <code>grabExcessHorizontalSpace</code> and <code>grabExcessVerticalSpace</code> | 
 | fields are typically used for larger widgets such as <code>Text,</code> | 
 | <code>List</code> or <code>Canvas</code> to allow them to grow if their | 
 | containing <code>Composite</code> grows. If a <code>Text</code> is | 
 | grabbing excess horizontal space and the user resizes the <code>Shell</code> | 
 | wider, then the <code>Text</code> will get all of the new horizontal | 
 | space and other widgets in the same row will stay their original width. | 
 | Of course, the widget that is grabbing excess space is also the first | 
 | one to shrink when the <code>Shell</code> gets smaller. It is easiest to | 
 | always think of the <b>grabExcessSpace</b> fields in the context of | 
 | resizing. For a simple example, let's reuse the previous example where | 
 | "Button 3" spanned two cells vertically. Here it is again:</p> | 
 |  | 
 | <img src="images/GridDataSampleSpan03.png" /> | 
 |  | 
 | <p>If we resize this window, the only thing that happens is that the | 
 | window gets bigger:</p> | 
 |  | 
 | <img src="images/GridDataSampleSpan03Resized.png" /> | 
 |  | 
 | <p>Now we will tell "Button 3" to grab excess horizontal and vertical | 
 | space, and "B1" and "B4" to fill vertically (without grabbing), and we | 
 | resize the window again:</p> | 
 |  | 
 | <pre>Button button1 = new Button(shell, SWT.PUSH); | 
 | button1.setText("B1"); | 
 | GridData gridData = new GridData(); | 
 | gridData.verticalAlignment = GridData.FILL; | 
 | button1.setLayoutData(gridData); | 
 |  | 
 | new Button(shell, SWT.PUSH).setText("Wide Button 2"); | 
 |  | 
 | Button button3 = new Button(shell, SWT.PUSH); | 
 | button3.setText("Button 3"); | 
 | gridData = new GridData(); | 
 | gridData.verticalAlignment = GridData.FILL; | 
 | gridData.verticalSpan = 2; | 
 | gridData.grabExcessVerticalSpace = true; | 
 | gridData.horizontalAlignment = GridData.FILL; | 
 | gridData.grabExcessHorizontalSpace = true; | 
 | button3.setLayoutData(gridData); | 
 |  | 
 | Button button4 = new Button(shell, SWT.PUSH); | 
 | button4.setText("B4"); | 
 | gridData = new GridData(); | 
 | gridData.verticalAlignment = GridData.FILL; | 
 | button4.setLayoutData(gridData); | 
 |  | 
 | new Button(shell, SWT.PUSH).setText("Button 5");</pre> <img | 
 | 	src="images/GridDataSampleGrab01.png" /> | 
 |  | 
 | <p>This time, "Button 3" grew in both directions, and "B4" grew | 
 | vertically. The other buttons stayed their original sizes. Because | 
 | "Button 3" was grabbing vertically and it spans two rows, the <i>last</i> | 
 | row that it spans grew taller. Note that "B1" did not | 
 | grow—although it is filling vertically—because its row did | 
 | not grow. Since "Button 3" was grabbing horizontally, its column grew | 
 | wider, and since it was filling horizontally, it grew wider to fill the | 
 | column.</p> | 
 |  | 
 | <p>In a typical application window, you often want to have at least | 
 | one widget that is grabbing. If more than one widget is trying to grab | 
 | the same space, then the excess space is shared evenly among the | 
 | grabbing widgets:</p> | 
 |  | 
 | <pre>import org.eclipse.swt.SWT; | 
 | import org.eclipse.swt.layout.GridData; | 
 | import org.eclipse.swt.layout.GridLayout; | 
 | import org.eclipse.swt.widgets.Display; | 
 | import org.eclipse.swt.widgets.Label; | 
 | import org.eclipse.swt.widgets.List; | 
 | import org.eclipse.swt.widgets.Shell; | 
 | import org.eclipse.swt.widgets.Text; | 
 |  | 
 | public class SampleGrabExcess { | 
 | 	public static void main(String[] args) { | 
 | 		Display display = new Display(); | 
 | 		Shell shell = new Shell(display); | 
 | 		shell.setLayout(new GridLayout(2, false)); | 
 | 		 | 
 | 		Label nameLabel = new Label(shell, SWT.NONE); | 
 | 		nameLabel.setText("Name:"); | 
 | 		 | 
 | 		Text nameText = new Text(shell, SWT.BORDER); | 
 | 		GridData gridData = new GridData(); | 
 | 		gridData.horizontalAlignment = SWT.FILL; | 
 | 		gridData.grabExcessHorizontalSpace = true; | 
 | 		nameText.setLayoutData(gridData); | 
 | 		nameText.setText("Text grows horizontally"); | 
 | 		 | 
 | 		Label addressLabel = new Label(shell, SWT.NONE); | 
 | 		addressLabel.setText("Address:"); | 
 | 		gridData = new GridData(); | 
 | 		gridData.verticalAlignment = SWT.TOP; | 
 | 		addressLabel.setLayoutData(gridData); | 
 | 		 | 
 | 		Text addressText = new Text(shell, SWT.BORDER | SWT.WRAP | SWT.MULTI); | 
 | 		gridData = new GridData(); | 
 | 		gridData.horizontalAlignment = SWT.FILL; | 
 | 		gridData.grabExcessHorizontalSpace = true; | 
 | 		gridData.verticalAlignment = SWT.FILL; | 
 | 		gridData.grabExcessVerticalSpace = true; | 
 | 		addressText.setLayoutData(gridData); | 
 | 		addressText.setText("This text field and the List\nbelow share any excess space."); | 
 |  | 
 | 		Label sportsLabel = new Label(shell, SWT.NONE); | 
 | 		sportsLabel.setText("Sports played:"); | 
 | 		gridData = new GridData(); | 
 | 		gridData.horizontalSpan = 2; | 
 | 		sportsLabel.setLayoutData(gridData); | 
 | 		 | 
 | 		List sportsList = new List(shell, SWT.BORDER | SWT.MULTI); | 
 | 		gridData = new GridData(); | 
 | 		gridData.horizontalSpan = 2; | 
 | 		gridData.horizontalAlignment = SWT.FILL; | 
 | 		gridData.grabExcessHorizontalSpace = true; | 
 | 		gridData.verticalAlignment = SWT.FILL; | 
 | 		gridData.grabExcessVerticalSpace = true; | 
 | 		sportsList.setLayoutData(gridData); | 
 | 		sportsList.add("Hockey"); | 
 | 		sportsList.add("Street Hockey"); | 
 | 				 | 
 | 		shell.pack(); | 
 | 		shell.open(); | 
 |  | 
 | 		while (!shell.isDisposed()) { | 
 | 			if (!display.readAndDispatch()) | 
 | 				display.sleep(); | 
 | 		} | 
 | 	} | 
 | }</pre>  | 
 |  | 
 | <p><img src="images/GridLayoutGrabExcess.png" /></p> | 
 |  | 
 | <p>When resized, the single line (top-most) <code>Text</code> grows | 
 | to consume all available horizontal space, and the second <code>Text</code> | 
 | and the <code>List</code> grow to consume all remaining space (both | 
 | vertically and horizontally):</p> | 
 |  | 
 | <p><img src="images/GridLayoutGrabExcessResized.png" /></p> | 
 |  | 
 | <p>One final point to note about grabbing: if a widget is set to | 
 | grab excess horizontal space and its parent <code>Composite</code> grows | 
 | wider, then the entire <i>column</i> containing that widget grows wider. | 
 | If a widget is grabbing excess vertical space and its parent <code>Composite</code> | 
 | grows taller, then the entire <i>row</i> containing that widget grows | 
 | taller. The implication of this is that if any other widget in the | 
 | affected column or row has <i>fill</i> alignment, then it will stretch | 
 | also. Widgets that have beginning, center, or end alignment will not | 
 | stretch: they will stay at the beginning, center or end of the wider | 
 | column or taller row.</p> | 
 |  | 
 | <p>The <code>widthHint</code> and <code>heightHint</code> fields | 
 | indicate the number of pixels wide or tall that you would like a widget | 
 | to be, assuming that it does not conflict with other requirements in the | 
 | <code>GridLayout</code>'s constraint system. Looking back at the | 
 | five-button, three-column example, say we want "Button 5" to be 70 pixels | 
 | wide and 40 pixels tall. We code it as follows:</p> | 
 |  | 
 | <pre>GridData gridData = new GridData();
 | 
 | gridData.widthHint = 70;
 | 
 | gridData.heightHint = 40;
 | 
 | button5.setLayoutData(gridData);</pre> | 
 |  | 
 | <p>The natural size of "Button 5" is shown in the window on the left, | 
 | below, and the 70-pixel wide, 40-pixel tall "Button 5" is on the right.</p> | 
 |  | 
 | <img src="images/GridLayoutSampleNumColumns3.png" /> <img | 
 | 	src="images/GridDataSampleSpan04.png" /> | 
 |  | 
 | <p>Note, however, that if the <code>horizontalAlignment</code> of | 
 | "Button 5" was <code>FILL</code>, then the <code>GridLayout</code> would not have been | 
 | able to honor the request for a width of 70 pixels.</p> | 
 |  | 
 | <p>One final comment about using width and height hints: something | 
 | that looks good on one platform may not look good on another. The | 
 | variation between font sizes and natural widget sizes across platforms | 
 | means that hard-coding pixel values is not usually the best way to lay | 
 | out windows. So, keep the use of size hints to a minimum, if you use | 
 | them at all.</p> | 
 |  | 
 | <h3>A Complex GridLayout Example</h3> | 
 |  | 
 | <p>So far, the <code>GridLayout</code> examples have been fairly | 
 | simple, in order to show how each field works. Now, we will put them all | 
 | together to create a more complicated example. We start by hand-drawing | 
 | a rough sketch of the window we want to create, to determine things like | 
 | how many columns the grid should contain, and whether or not any widgets | 
 | need to span.</p> | 
 | <img src="images/DogShowHandDrawn.gif" /> | 
 |  | 
 | <p>Then we start coding the example from the diagram. The code is | 
 | below. Note that we have added a bit of logic to make the code more | 
 | interesting, for example, "Browse..." opens a <code>FileDialog</code> | 
 | to read an <code>Image</code> file which the <code>Canvas</code> | 
 | displays in a paint listener, "Delete" deletes the <code>Image</code>, and | 
 | Enter prints the current dog and owner info.</p> | 
 |  | 
 | <pre>package org.eclipse.articles.layouts.samples; | 
 | import org.eclipse.swt.SWT; | 
 | import org.eclipse.swt.events.DisposeEvent; | 
 | import org.eclipse.swt.events.DisposeListener; | 
 | import org.eclipse.swt.events.PaintEvent; | 
 | import org.eclipse.swt.events.PaintListener; | 
 | import org.eclipse.swt.events.SelectionAdapter; | 
 | import org.eclipse.swt.events.SelectionEvent; | 
 | import org.eclipse.swt.graphics.Image; | 
 | import org.eclipse.swt.graphics.Rectangle; | 
 | import org.eclipse.swt.layout.GridData; | 
 | import org.eclipse.swt.layout.GridLayout; | 
 | import org.eclipse.swt.widgets.Button; | 
 | import org.eclipse.swt.widgets.Canvas; | 
 | import org.eclipse.swt.widgets.Combo; | 
 | import org.eclipse.swt.widgets.Display; | 
 | import org.eclipse.swt.widgets.FileDialog; | 
 | import org.eclipse.swt.widgets.Group; | 
 | import org.eclipse.swt.widgets.Label; | 
 | import org.eclipse.swt.widgets.List; | 
 | import org.eclipse.swt.widgets.Shell; | 
 | import org.eclipse.swt.widgets.Text; | 
 |  | 
 | public class DogShowRegistrationWindow { | 
 | 	Text dogName; | 
 | 	Combo dogBreed; | 
 | 	Canvas dogPhoto; | 
 | 	Image dogImage; | 
 | 	List categories; | 
 | 	Text ownerName; | 
 | 	Text ownerPhone; | 
 |  | 
 | 	public static void main(String[] args) { | 
 | 		Display display = new Display(); | 
 | 		Shell shell = new DogShowRegistrationWindow().createShell(display); | 
 | 		shell.open(); | 
 | 		while (!shell.isDisposed()) { | 
 | 			if (!display.readAndDispatch()) | 
 | 				display.sleep(); | 
 | 		} | 
 | 	} | 
 | 	 | 
 | 	public Shell createShell(final Display display) { | 
 | 		final Shell shell = new Shell(display); | 
 | 		shell.setText("Dog Show Entry"); | 
 | 		GridLayout gridLayout = new GridLayout(); | 
 | 		gridLayout.numColumns = 3; | 
 | 		shell.setLayout(gridLayout); | 
 | 		 | 
 | 		new Label(shell, SWT.NONE).setText("Dog's Name:"); | 
 | 		 | 
 | 		dogName = new Text(shell, SWT.SINGLE | SWT.BORDER); | 
 | 		GridData gridData = new GridData(GridData.FILL, GridData.CENTER, true, false); | 
 | 		gridData.horizontalSpan = 2; | 
 | 		dogName.setLayoutData(gridData); | 
 | 		 | 
 | 		new Label(shell, SWT.NONE).setText("Breed:"); | 
 | 		 | 
 | 		dogBreed = new Combo(shell, SWT.NONE); | 
 | 		dogBreed.setItems(new String[] { "Collie", "Pitbull", "Poodle", | 
 | 				"Scottie", "Black Lab" }); | 
 | 		dogBreed.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); | 
 | 		 | 
 | 		Label label = new Label(shell, SWT.NONE); | 
 | 		label.setText("Categories"); | 
 | 		label.setLayoutData(new GridData(GridData.CENTER, GridData.CENTER, true, false)); | 
 | 		 | 
 | 		new Label(shell, SWT.NONE).setText("Photo:"); | 
 | 		dogPhoto = new Canvas(shell, SWT.BORDER); | 
 | 		gridData = new GridData(GridData.FILL, GridData.FILL, true, true); | 
 | 		gridData.widthHint = 80; | 
 | 		gridData.heightHint = 80; | 
 | 		gridData.verticalSpan = 3; | 
 | 		dogPhoto.setLayoutData(gridData); | 
 | 		dogPhoto.addPaintListener(new PaintListener() { | 
 | 			public void paintControl(final PaintEvent event) { | 
 | 				if (dogImage != null) { | 
 | 					event.gc.drawImage(dogImage, 0, 0); | 
 | 				} | 
 | 			} | 
 | 		}); | 
 | 		 | 
 | 		categories = new List(shell, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL); | 
 | 		categories.setItems(new String[] { "Best of Breed", "Prettiest Female", | 
 | 				"Handsomest Male", "Best Dressed", "Fluffiest Ears", | 
 | 				"Most Colors", "Best Performer", "Loudest Bark", | 
 | 				"Best Behaved", "Prettiest Eyes", "Most Hair", "Longest Tail", | 
 | 				"Cutest Trick" }); | 
 | 		gridData = new GridData(GridData.FILL, GridData.FILL, true, true); | 
 | 		gridData.verticalSpan = 4; | 
 | 		int listHeight = categories.getItemHeight() * 12; | 
 | 		Rectangle trim = categories.computeTrim(0, 0, 0, listHeight); | 
 | 		gridData.heightHint = trim.height; | 
 | 		categories.setLayoutData(gridData); | 
 | 		 | 
 | 		Button browse = new Button(shell, SWT.PUSH); | 
 | 		browse.setText("Browse..."); | 
 | 		gridData = new GridData(GridData.FILL, GridData.CENTER, true, false); | 
 | 		gridData.horizontalIndent = 5; | 
 | 		browse.setLayoutData(gridData); | 
 | 		browse.addSelectionListener(new SelectionAdapter() { | 
 | 			public void widgetSelected(SelectionEvent event) { | 
 | 				String fileName = new FileDialog(shell).open(); | 
 | 				if (fileName != null) { | 
 | 					dogImage = new Image(display, fileName); | 
 | 				} | 
 | 			} | 
 | 		}); | 
 | 		 | 
 | 		Button delete = new Button(shell, SWT.PUSH); | 
 | 		delete.setText("Delete"); | 
 | 		gridData = new GridData(GridData.FILL, GridData.BEGINNING, true, false); | 
 | 		gridData.horizontalIndent = 5; | 
 | 		delete.setLayoutData(gridData); | 
 | 		delete.addSelectionListener(new SelectionAdapter() { | 
 | 			public void widgetSelected(SelectionEvent event) { | 
 | 				if (dogImage != null) { | 
 | 					dogImage.dispose(); | 
 | 					dogImage = null; | 
 | 					dogPhoto.redraw(); | 
 | 				} | 
 | 			} | 
 | 		}); | 
 | 		 | 
 | 		Group ownerInfo = new Group(shell, SWT.NONE); | 
 | 		ownerInfo.setText("Owner Info"); | 
 | 		gridLayout = new GridLayout(); | 
 | 		gridLayout.numColumns = 2; | 
 | 		ownerInfo.setLayout(gridLayout); | 
 | 		gridData = new GridData(GridData.FILL, GridData.CENTER, true, false); | 
 | 		gridData.horizontalSpan = 2; | 
 | 		ownerInfo.setLayoutData(gridData); | 
 | 		 | 
 | 		new Label(ownerInfo, SWT.NONE).setText("Name:"); | 
 | 		ownerName = new Text(ownerInfo, SWT.SINGLE | SWT.BORDER); | 
 | 		ownerName.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); | 
 | 		 | 
 | 		new Label(ownerInfo, SWT.NONE).setText("Phone:"); | 
 | 		ownerPhone = new Text(ownerInfo, SWT.SINGLE | SWT.BORDER); | 
 | 		ownerPhone.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); | 
 | 		 | 
 | 		Button enter = new Button(shell, SWT.PUSH); | 
 | 		enter.setText("Enter"); | 
 | 		gridData = new GridData(GridData.END, GridData.CENTER, false, false); | 
 | 		gridData.horizontalSpan = 3; | 
 | 		enter.setLayoutData(gridData); | 
 | 		enter.addSelectionListener(new SelectionAdapter() { | 
 | 			public void widgetSelected(SelectionEvent event) { | 
 | 				System.out.println("\nDog Name: " + dogName.getText()); | 
 | 				System.out.println("Dog Breed: " + dogBreed.getText()); | 
 | 				System.out.println("Owner Name: " + ownerName.getText()); | 
 | 				System.out.println("Owner Phone: " + ownerPhone.getText()); | 
 | 				System.out.println("Categories:"); | 
 | 				String cats[] = categories.getSelection(); | 
 | 				for (int i = 0; i > cats.length; i++) { | 
 | 					System.out.println("\t" + cats[i]); | 
 | 				} | 
 | 			} | 
 | 		}); | 
 | 		 | 
 | 		shell.addDisposeListener(new DisposeListener() { | 
 | 			public void widgetDisposed(DisposeEvent arg0) { | 
 | 				if (dogImage != null) { | 
 | 					dogImage.dispose(); | 
 | 					dogImage = null; | 
 | 				} | 
 | 			}			 | 
 | 		}); | 
 | 		 | 
 | 		shell.pack(); | 
 | 		 | 
 | 		return shell; | 
 | 	} | 
 | }</pre> | 
 |  | 
 |  | 
 | <p>Here is what the window looks like after Mary Smith enters | 
 | Bifford in the dog show:</p> | 
 | <img src="images/DogShowBiff.png" /> | 
 |  | 
 | <p>If this window is resized larger, the layout adjusts as follows:</p> | 
 |  | 
 | <img src="images/DogShowBiffResized.png" /> | 
 |  | 
 | <p>Notice the following:</p> | 
 | <ul> | 
 | 	<li>There are three columns and seven rows.</li> | 
 | 	<li>The <code>dogPhoto</code> <code>Canvas</code> grew wider and | 
 | 	taller because it is filling and grabbing horizontally and vertically | 
 | 	(we did not resize the <code>Image</code>, but we could have).</li> | 
 |  | 
 | 	<li>The <code>dogBreed</code> <code>Combo</code> grew wider | 
 | 	because it is filling horizontally, and it is in the same column as the | 
 | 	<code>Canvas</code>.</li> | 
 |  | 
 | 	<li>The <code>dogName</code> <code>Text</code> grew wider because | 
 | 	it is filling horizontally, and one of the columns it spans is the | 
 | 	column containing the <code>Canvas</code>.</li> | 
 |  | 
 | 	<li>The <code>categories</code> <code>List</code> grew taller | 
 | 	because it is filling vertically, and it spans the same rows that the <code>Canvas</code> | 
 | 	does.</li> | 
 |  | 
 | 	<li>Because the <code>categories</code> <code>List</code> grew | 
 | 	taller, its vertical scrollbar disappeared (it did not grow wider).</li> | 
 |  | 
 | 	<li>The <code>ownerInfo</code> <code>Group</code> grew wider | 
 | 	because it is filling horizontally, and one of the columns it spans is | 
 | 	the column containing the <code>Canvas</code>.</li> | 
 |  | 
 | 	<li>The <code>ownerInfo</code> <code>Group</code>, as a subclass | 
 | 	of <code>Composite</code>, has its own <code>GridLayout</code> with 2 | 
 | 	columns and 2 rows.</li> | 
 |  | 
 | 	<li>The <code>ownerName</code> and <code>ownerPhone</code> <code>Texts</code> | 
 | 	grew wider because the <code>Group</code> grew wider, and they are | 
 | 	filling and grabbing horizontally in the <code>Group</code>'s <code>GridLayout</code>.</li> | 
 |  | 
 | 	<li>The <code>browse</code> and <code>delete</code> <code>Buttons</code> | 
 | 	are indented slightly, and because they both fill horizontally, they | 
 | 	are the same width.</li> | 
 |  | 
 | 	<li>The <code>delete</code> <code>Button</code> is vertically | 
 | 	aligned at the top of its row.</li> | 
 |  | 
 | 	<li>The "Categories" <code>Label</code> is centered over | 
 | 	the <code>categories</code> <code>List</code>. | 
 | 	 | 
 | 	<li>The <code>enter</code> <code>Button</code> is horizontally | 
 | 	aligned to the right of the 3 columns it spans.</li> | 
 |  | 
 | 	<li>The <code>dogPhoto</code> <code>Canvas</code> was created with | 
 | 	width and height hints because we want the <code>Image</code> to be 80 | 
 | 	pixels x 80 pixels, if possible.</li> | 
 |  | 
 | 	<li>The <code>categories</code> <code>List</code> was created with | 
 | 	a height hint that was based on the <code>List</code>'s font times 12, | 
 | 	because we want try to get the <code>List</code> to show 12 items | 
 | 	initially.</li> | 
 | </ul> | 
 |  | 
 | <h2>FormLayout</h2> | 
 |  | 
 | <p><code>FormLayout</code> works by creating <code>FormAttachment</code>s | 
 | for each side of the widget, and storing them in the layout data. An | 
 | attachment 'attaches' a specific side of the widget either to a position | 
 | in the parent <code>Composite</code> or to another widget within the | 
 | layout. This provides tremendous flexibility when laying out, as it | 
 | allows you to specify the placement of individual widgets within the | 
 | layout.</p> | 
 |  | 
 | <h3>FormLayout Configuration Fields</h3> | 
 |  | 
 | <p>The <code>marginWidth</code>, and <code>MarginHeight</code> | 
 | fields in <code>FormLayout</code> are similar to those in <code>GridLayout</code>. | 
 | Left and right margins are defined by <code>marginWidth</code>, and top | 
 | and bottom margins are defined by <code>marginHeight</code>. Margins can | 
 | also be defined on a per-widget basis in the attachments. <code>FormLayout</code> | 
 | margins are zero by default.</p> | 
 |  | 
 | <p>To set the margins, we create a <code>FormLayout</code>, and set | 
 | the margin fields. The following code will set a margin of five pixels | 
 | around all four sides of the parent <code>Composite</code>:</p> | 
 |  | 
 | <pre>Display display = new Display (); | 
 | Shell shell = new Shell (display); | 
 | FormLayout layout= new FormLayout (); | 
 | layout.marginHeight = 5; | 
 | layout.marginWidth = 5; | 
 | shell.setLayout(layout);</pre> | 
 |  | 
 | <h3>FormData Object Fields</h3> | 
 |  | 
 | <p><code>FormData</code> objects specify how each widget in a <code>FormLayout</code> | 
 | will be laid out. Each <code>FormData</code> object defines the | 
 | attachments for all four sides of the widget. These attachments tell | 
 | where to position each side of the widget. To set a widget's <code>FormData</code> | 
 | object, you use the <code>setLayoutData(Object)</code> method, for example:</p> | 
 |  | 
 | <pre>Button button1 = new Button(shell, SWT.PUSH); | 
 | button1.setText("B1"); | 
 | button1.setLayoutData(new FormData());</pre> | 
 |  | 
 | <p>This code creates a <code>FormData</code> object with no | 
 | attachments. In this case, default attachments are defined, which | 
 | defeats the whole purpose and utility of <code>FormLayout</code>. The | 
 | default attachments attach the widget to the top and left edges of the | 
 | parent <code>Composite</code>. If every widget in a <code>FormLayout</code> | 
 | used the default attachments, they would all be laid out one on top of | 
 | another in the top left corner of the parent <code>Composite</code>.</p> | 
 |  | 
 | <p>The <code>left</code>, <code>right</code>, <code>top</code>, and | 
 | <code>bottom</code> fields of <code>FormData</code> specify the <code>FormAttachment</code> | 
 | objects that are associated with the left, right, top and bottom sides | 
 | of the widget, respectively. These fields are set in the following | 
 | example:</p> | 
 |  | 
 | <pre>FormData formData = new FormData(); | 
 | formData.top = new FormAttachment(0,60); | 
 | formData.bottom = new FormAttachment(100,-5); | 
 | formData.left = new FormAttachment(20,0); | 
 | formData.right = new FormAttachment(100,-3); | 
 | button1.setLayoutData(formData);</pre> <img | 
 | 	src="images/FormLayoutSample01.png" /> | 
 |  | 
 | <p>A <code>FormAttachment</code> object defines the attachment of a | 
 | specific side of a widget. There are many ways that a side can be | 
 | attached: to a position in the parent <code>Composite</code>, to an edge | 
 | of the <code>Composite</code>, to the adjacent side of another widget, | 
 | to the opposite side of another widget, or centered on another widget. | 
 | Attaching to a position places the side of the widget so that it is | 
 | always at a percentage of the <code>Composite</code>. To attach to an | 
 | edge of the <code>Composite</code>, the percentage is either 0% or 100%. | 
 | Attaching to the adjacent side of another widget ensures that the | 
 | specified side of the widget is always next to the closest side of the | 
 | other widget. Attaching to the opposite side of another widget ensures | 
 | that the specific side of the widget is aligned with the furthest side | 
 | of the other widget. Finally, attaching to the center of another widget | 
 | centers the widget on the other widget. Any of these ways can be done | 
 | with or without an offset.</p> | 
 |  | 
 | <p>The <code>width</code> and <code>height</code> fields of <code>FormData</code> | 
 | specify the requested width and the height of the widget. If a requested | 
 | width or height conflicts with constraints set by the attachments, then | 
 | that width or height will not be honored. Although setting attachments can | 
 | also determine width and height, there are some cases when you do not | 
 | want to define attachments for all sides of the widget. In this case, it | 
 | may be useful to set the width and height of the widget as follows:</p> | 
 |  | 
 | <pre>FormData formData = new FormData(20,30); | 
 | formData.top = new FormAttachment(0,60); | 
 | formData.left = new FormAttachment(20,0); | 
 | button1.setLayoutData(formData);</pre>  | 
 |  | 
 | <p>If you wish to set only the width or the height, you can directly | 
 | set the width or height field in the <code>FormData</code> object:</p> | 
 |  | 
 | <pre>FormData formData = new FormData(); | 
 | formData.width = 30; | 
 | formData.top = new FormAttachment(0,60);
 | 
 | formData.bottom = new FormAttachment(100,-5); | 
 | formData.left = new FormAttachment(20,0); | 
 | button1.setLayoutData(formData);</pre>  | 
 |  | 
 | <p>Note that if a button is attached to the parent <code>Composite</code> | 
 | on both sides, when the <code>Composite</code> is resized, the button | 
 | will grow or shrink along with it.</p> | 
 |  | 
 | <h3>FormAttachment Objects</h3> | 
 |  | 
 | <p>A <code>FormAttachment</code> is an object that defines the | 
 | attachment for a specific side of a widget. It is not always necessary | 
 | to set an attachment for all four sides of a widget. Often, specifying | 
 | one or more sides of a widget can fully specify its placement in the | 
 | layout. In order to properly place your widgets, you should define an | 
 | attachment for at least one of <code>left</code> or <code>right</code> | 
 | in the <code>FormData</code>, and at least one of <code>top</code> or <code>bottom</code>. | 
 | If you only wish to attach the left side of a widget and not the right, | 
 | then the widget will be positioned based on its left side, and the | 
 | widget will take its natural size (or its requested size, if one was set | 
 | for it). If you do not attach the left or the right, default positioning | 
 | will attach your widget to the left side of the form. The same logic | 
 | applies for the top and bottom sides.</p> | 
 |  | 
 | <h3>Attaching to a Position</h3> | 
 | <p>There are many types of attachment. The first is to attach the | 
 | widget to a position in the parent <code>Composite</code>. This can be | 
 | done by defining a percentage value out of 100, for example:</p> | 
 |  | 
 | <pre>FormData formData = new FormData(); | 
 | formData.top = new FormAttachment(50,0); | 
 | button1.setLayoutData(formData);</pre> <img | 
 | 	src="images/FormLayoutSamplePosition50.png" /> | 
 |  | 
 | <p>This sets the top of the <code>Button</code> to a position that | 
 | represents 50% of the height of the parent <code>Composite</code> (a <code>Shell</code>), | 
 | with an offset of 0. When the shell is resized, the top side of the <code>Button</code> | 
 | will still be at 50%, like so:</p> | 
 |  | 
 | <img src="images/FormLayoutSamplePosition50Resized.png" /> | 
 |  | 
 | <p>If we chose to set an offset value, the top side of the <code>Button</code> | 
 | would have been set to 50% of the <code>Composite</code> plus or minus | 
 | the number of pixels set for the offset.</p> | 
 |  | 
 | <p>We can also define the position of the button using an arbitrary scale, for example:</p> | 
 |  | 
 | <pre>FormData formData = new FormData(); | 
 | formData.top = new FormAttachment(30,70,10); | 
 | button1.setLayoutData(formData);</pre> | 
 |  | 
 | <p>If the height of the <code>Composite</code> is defined as being | 
 | 70 units, this sets the top of the <code>Button</code> to a position | 
 | representing 30 units down from the top of the <code>Composite</code>, | 
 | plus 10 pixels (i.e. 3/7ths of the height of the composite plus 10 pixels).</p> | 
 |  | 
 | <p>To attach a side of a widget to an edge of | 
 | the parent <code>Composite</code>, set the position to either 0% or 100%. The 0 | 
 | position is defined as the top of the <code>Composite</code> when going | 
 | vertically, and the left when going horizontally. The right and bottom | 
 | edges of the <code>Composite</code> are defined as the 100 position. | 
 | Therefore, if we want to attach a widget to the right edge of the <code>Composite</code>, | 
 | we simply have to create an attachment that sets the position to 100:</p> | 
 |  | 
 | <pre>FormData formData = new FormData(); | 
 | formData.right = new FormAttachment(100,-5); | 
 | button1.setLayoutData(formData);</pre> <img | 
 | 	src="images/FormLayoutSampleParent100.png" /> | 
 |  | 
 | <p>This attaches the right side of the <code>Button</code> to the | 
 | right edge of the parent (a <code>Shell</code>), with an offset of five | 
 | pixels. Note that the offsets go in one direction only. If you want a | 
 | widget offset down or to the right, the offset should be positive. For | 
 | offsets that shift the widget up or to the left, the offset should be | 
 | negative. When the <code>Shell</code> is resized, the <code>Button</code> | 
 | will always be five pixels away from the right edge:</p> | 
 |  | 
 | <img src="images/FormLayoutSampleParent100Resized.png" /> | 
 |  | 
 | <h3>Attaching to Another Widget</h3> | 
 | <p>The third type of attachment is to attach the side of the widget | 
 | to another control within the parent <code>Composite</code>. The side | 
 | can be attached to the adjacent side of the other control (the default), | 
 | to the opposite side of the other control, or the widget can be centered | 
 | on the other control, all with or without and offset.</p> | 
 |  | 
 | <p>The most common way to attach to another control is to attach to | 
 | its adjacent side. For example, the following code:</p> | 
 |  | 
 | <pre>FormData formData = new FormData(); | 
 | formData.top = new FormAttachment(20,0); | 
 | button1.setLayoutData(formData); | 
 |  | 
 | FormData formData2 = new FormData(); | 
 | formData2.top = new FormAttachment(button1,10); | 
 | button2.setLayoutData(formData2);</pre> <img | 
 | 	src="images/FormLayoutSampleAttachWidget01.png" /> | 
 |  | 
 | <p>This example attaches the top of button2 to the bottom of | 
 | button1. Note that when the window is resized, button1 will move so that | 
 | its top side is always positioned at 20% of the <code>Shell</code>, and | 
 | button2 will move so that its top side is always 10 pixels below the | 
 | adjacent (bottom) side of button1.</p> | 
 |  | 
 | <img src="images/FormLayoutSampleAttachWidget01Resized.png" /> | 
 |  | 
 | <p>While the default is to attach the side of a widget to the | 
 | adjacent side of a control, <code>FormAttachment</code>s can also be | 
 | created to attach to the opposite side of a control. This is useful when | 
 | lining up widgets. In this case, you create the attachment to the other | 
 | control using <code>TOP</code>, <code>BOTTOM</code>, <code>LEFT</code> | 
 | or <code>RIGHT</code> alignment, for example:</p> | 
 |  | 
 | <pre>formData2.top = new FormAttachment(button1,0,SWT.TOP);</pre> | 
 |  | 
 | <p>In the following example, the top side of <code>button1</code> is positioned | 
 | at 20% of the <code>Shell</code>. <code>button2</code>'s top side is aligned with | 
 | <code>button1</code>'s top side, using <code>TOP</code> alignment. This means that the top side of | 
 | <code>button2</code> is also positioned at 20% of the <code>Shell</code>. Note that | 
 | when specifying the top attachment, only the vertical placement of the | 
 | widget is being defined. It is still necessary to set the left | 
 | attachment for <code>button2</code> so that the <code>Button</code>s are not stacked | 
 | on top of each other.</p> | 
 |  | 
 | <pre>FormData formData = new FormData(50,50); | 
 | formData.top = new FormAttachment(20,0); | 
 | button1.setLayoutData(formData); | 
 | 
 | 
 | FormData formData2 = new FormData(); | 
 | formData2.left = new FormAttachment(button1,5); | 
 | formData2.top = new FormAttachment(button1,0,SWT.TOP);  | 
 | button2.setLayoutData(formData2);</pre> <img | 
 | 	src="images/FormLayoutSampleAttachWidget02.png" /> | 
 |  | 
 | <p>The final way to attach a widget to another control is to center | 
 | it on the other control. This is useful when the widgets are different | 
 | sizes. In this case, you create the attachment to the other control with | 
 | <code>CENTER</code> alignment, for example:</p> | 
 |  | 
 | <pre>formData.top = new FormAttachment(button1,0,SWT.CENTER);</pre> | 
 |  | 
 | <p>This will place the top of the widget in a position that will | 
 | allow the widget to be centered on the other control, with an offset of | 
 | 0. Setting only the top, or the bottom, or both as a center attachment | 
 | will produce the same result. The top side of the widget is not | 
 | centered, but the entire widget is centered, so this only needs to be | 
 | specified once. Here is an example:</p> | 
 |  | 
 | <pre>FormData formData1 = new FormData (50,50);
 | 
 | button1.setLayoutData(formData1); | 
 |  | 
 | FormData formData2 = new FormData (); | 
 | formData2.left = new FormAttachment (button1,5); | 
 | formData2.top = new FormAttachment (button1,0,SWT.CENTER); | 
 | button2.setLayoutData(formData2);</pre> <img | 
 | 	src="images/FormLayoutSampleAttachWidget03.png" /> | 
 |  | 
 | <p>Using the different types of <code>FormAttachment</code> allows | 
 | layouts to be defined in many different ways. <code>FormLayout</code> | 
 | covers certain cases that cannot be solved using <code>FillLayout</code>, | 
 | <code>RowLayout</code> or <code>GridLayout</code>, making it a very | 
 | useful class for defining layouts.</p> | 
 |  | 
 | <p><b>Important: </b>Do <b>not</b> define circular | 
 | attachments. For example, do not attach the right edge of button1 | 
 | to the left edge of button2 and then attach the left edge button2 to the | 
 | right edge of button1. This will over-constrain the layout, causing | 
 | undefined behavior. The algorithm will terminate, but the results | 
 | are undefined. Therefore, make sure that you do not over-constrain your | 
 | widgets. Only provide the attachments necessary to properly lay out the | 
 | widgets.</p> | 
 |  | 
 | <h3>A FormLayout Example</h3> | 
 |  | 
 | <p>So far, all the examples using <code>FormLayout</code> have | 
 | involved one or two <code>Button</code>s, to show how <code>FormAttachment</code>s | 
 | work. Next, we will do a simple example using more <code>Button</code>s | 
 | to show how a layout can be arranged using the attachments. We'll start | 
 | by drawing a basic diagram outlining the attachments that we wish to | 
 | create.</p> | 
 |  | 
 | <p><img src="images/FormExampleHandDrawn.jpg" /></p>  | 
 |  | 
 | <pre>FormData data1 = new FormData(); | 
 | data1.left = new FormAttachment(0,5); | 
 | data1.right = new FormAttachment(25,0); | 
 | button1.setLayoutData(data1); | 
 |  | 
 | FormData data2 = new FormData(); | 
 | data2.left = new FormAttachment(button1,5); | 
 | data2.right = new FormAttachment(100,-5); | 
 | button2.setLayoutData(data2); | 
 |  | 
 | FormData data3 = new FormData(60,60); | 
 | data3.top = new FormAttachment(button1,5); | 
 | data3.left = new FormAttachment(50,-30); | 
 | data3.right = new FormAttachment(50,30); | 
 | button3.setLayoutData(data3); | 
 |  | 
 | FormData data4 = new FormData(); | 
 | data4.top = new FormAttachment(button3,5); | 
 | data4.bottom = new FormAttachment(100,-5); | 
 | data4.left = new FormAttachment(25,0); | 
 | button4.setLayoutData(data4); | 
 |  | 
 | FormData data5 = new FormData(); | 
 | data5.bottom = new FormAttachment(100,-5); | 
 | data5.left = new FormAttachment(button4,5); | 
 | button5.setLayoutData(data5);</pre> | 
 |  | 
 | <p>In this case, since no top attachment was defined for <code>button1</code> or | 
 | <code>button2</code>, they are attached to the top of the layout. <code>button3</code> is centred | 
 | in the layout using percentages and offsets on the left and right sides. | 
 | <code>button4</code> and <code>button5</code> are attached to the bottom of the layout with a five | 
 | pixel offset.</p> | 
 |  | 
 | <img src="images/FormLayoutSample5Buttons01.png" /> | 
 |  | 
 | <p>When we resize, the attachments become more visible. <code>button1</code> is | 
 | attached on the left and the right side, so when the window is resized, | 
 | it grows. Note that the right side will always be at 25% of the window. | 
 | The same resize results apply for <code>button2</code>, as both sides are attached. | 
 | The left side is attached to <code>button1</code>, so it will always be at 25% plus five | 
 | pixels. <code>button3</code> stays in the center of the window, horizontally. <code>button4</code> | 
 | is attached at the top and the bottom, so it grows vertically when the | 
 | window is resized, but it is only attached on the left and not the | 
 | right, so it does not grow horizontally. <code>button5</code> will not grow or | 
 | shrink, but it will always stay five pixels away from <code>button4</code> on the left, | 
 | and five pixels away from the bottom of the window.</p> | 
 |  | 
 | <img src="images/FormLayoutSample5Buttons01Resized.png" /> | 
 |  | 
 | <h3>A Complex FormLayout Example</h3> | 
 |  | 
 | <p>To illustrate how <code>FormLayout</code> can be used for more | 
 | complicated arrangements, the Dog Show Entry example done previously for | 
 | <code>GridLayout</code> is redone using <code>FormLayout</code>. This | 
 | code produces an identical layout, but uses different concepts to | 
 | achieve it.</p> | 
 |  | 
 | <pre>import org.eclipse.swt.SWT; | 
 | import org.eclipse.swt.events.PaintEvent; | 
 | import org.eclipse.swt.events.PaintListener; | 
 | import org.eclipse.swt.events.SelectionAdapter; | 
 | import org.eclipse.swt.events.SelectionEvent; | 
 | import org.eclipse.swt.graphics.Image; | 
 | import org.eclipse.swt.layout.FormAttachment; | 
 | import org.eclipse.swt.layout.FormData; | 
 | import org.eclipse.swt.layout.FormLayout; | 
 | import org.eclipse.swt.widgets.Button; | 
 | import org.eclipse.swt.widgets.Canvas; | 
 | import org.eclipse.swt.widgets.Combo; | 
 | import org.eclipse.swt.widgets.Display; | 
 | import org.eclipse.swt.widgets.FileDialog; | 
 | import org.eclipse.swt.widgets.Group; | 
 | import org.eclipse.swt.widgets.Label; | 
 | import org.eclipse.swt.widgets.List; | 
 | import org.eclipse.swt.widgets.Shell; | 
 | import org.eclipse.swt.widgets.Text; | 
 |  | 
 | public class DogShowRegistrationWindowWithFormLayout { | 
 | 	Image dogImage; | 
 | 	Text dogNameText; | 
 | 	Combo dogBreedCombo; | 
 | 	Canvas dogPhoto; | 
 | 	List categories; | 
 | 	Text nameText; | 
 | 	Text phoneText; | 
 |  | 
 | 	public static void main(String[] args) { | 
 | 		Display display = new Display(); | 
 | 		Shell shell = new DogShowRegistrationWindow().createShell(display); | 
 | 		shell.open(); | 
 | 		while (!shell.isDisposed()) { | 
 | 			if (!display.readAndDispatch()) | 
 | 				display.sleep(); | 
 | 		} | 
 | 	} | 
 | 	 | 
 | 	public Shell createShell(final Display display) { | 
 | 		final Shell shell = new Shell(display); | 
 | 		FormLayout layout = new FormLayout(); | 
 | 		layout.marginWidth = 5; | 
 | 		layout.marginHeight = 5; | 
 | 		shell.setLayout(layout); | 
 | 		shell.setText("Dog Show Entry"); | 
 | 		 | 
 | 		Group ownerInfo = new Group(shell, SWT.NONE); | 
 | 		ownerInfo.setText("Owner Info"); | 
 | 		FormLayout ownerLayout = new FormLayout(); | 
 | 		ownerLayout.marginWidth = 5; | 
 | 		ownerLayout.marginHeight = 5; | 
 | 		ownerInfo.setLayout(ownerLayout); | 
 | 		 | 
 | 		Label dogName = new Label(shell, SWT.NONE); | 
 | 		dogName.setText("Dog's Name:"); | 
 | 		dogNameText = new Text(shell, SWT.SINGLE | SWT.BORDER); | 
 | 		 | 
 | 		Label dogBreed = new Label(shell, SWT.NONE); | 
 | 		dogBreed.setText("Breed:"); | 
 | 		 | 
 | 		dogBreedCombo = new Combo(shell, SWT.NONE); | 
 | 		dogBreedCombo.setItems(new String[] { "Collie", "Pitbull", "Poodle", | 
 | 				"Scottie", "Black Lab" }); | 
 | 		 | 
 | 		Label photo = new Label(shell, SWT.NONE); | 
 | 		photo.setText("Photo:"); | 
 | 		dogPhoto = new Canvas(shell, SWT.BORDER); | 
 | 		 | 
 | 		Button browse = new Button(shell, SWT.PUSH); | 
 | 		browse.setText("Browse..."); | 
 | 		 | 
 | 		Button delete = new Button(shell, SWT.PUSH); | 
 | 		delete.setText("Delete"); | 
 | 		 | 
 | 		Label cats = new Label(shell, SWT.NONE); | 
 | 		cats.setText("Categories"); | 
 | 		categories = new List(shell, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | 
 | 				| SWT.H_SCROLL); | 
 | 		categories.setItems(new String[] { "Best of Breed", "Prettiest Female", | 
 | 				"Handsomest Male", "Best Dressed", "Fluffiest Ears", | 
 | 				"Most Colors", "Best Performer", "Loudest Bark", | 
 | 				"Best Behaved", "Prettiest Eyes", "Most Hair", "Longest Tail", | 
 | 				"Cutest Trick" }); | 
 | 		 | 
 | 		Button enter = new Button(shell, SWT.PUSH); | 
 | 		enter.setText("Enter"); | 
 | 		FormData data = new FormData(); | 
 | 		data.top = new FormAttachment(dogNameText, 0, SWT.CENTER); | 
 | 		dogName.setLayoutData(data); | 
 | 		data = new FormData(); | 
 | 		data.left = new FormAttachment(dogName, 5); | 
 | 		data.right = new FormAttachment(100, 0); | 
 | 		dogNameText.setLayoutData(data); | 
 | 		 | 
 | 		data = new FormData(); | 
 | 		data.top = new FormAttachment(dogBreedCombo, 0, SWT.CENTER); | 
 | 		dogBreed.setLayoutData(data); | 
 | 		data = new FormData(); | 
 | 		data.top = new FormAttachment(dogNameText, 5); | 
 | 		data.left = new FormAttachment(dogNameText, 0, SWT.LEFT); | 
 | 		data.right = new FormAttachment(categories, -5); | 
 | 		dogBreedCombo.setLayoutData(data); | 
 | 		 | 
 | 		data = new FormData(80, 80); | 
 | 		data.top = new FormAttachment(dogBreedCombo, 5); | 
 | 		data.left = new FormAttachment(dogNameText, 0, SWT.LEFT); | 
 | 		data.right = new FormAttachment(categories, -5); | 
 | 		data.bottom = new FormAttachment(ownerInfo, -5); | 
 | 		dogPhoto.setLayoutData(data); | 
 | 		dogPhoto.addPaintListener(new PaintListener() { | 
 | 			public void paintControl(final PaintEvent event) { | 
 | 				if (dogImage != null) { | 
 | 					event.gc.drawImage(dogImage, 0, 0); | 
 | 				} | 
 | 			} | 
 | 		}); | 
 | 		data = new FormData(); | 
 | 		data.top = new FormAttachment(dogPhoto, 0, SWT.TOP); | 
 | 		photo.setLayoutData(data); | 
 | 		data = new FormData(); | 
 | 		data.top = new FormAttachment(photo, 5); | 
 | 		data.right = new FormAttachment(dogPhoto, -5); | 
 | 		browse.setLayoutData(data); | 
 | 		browse.addSelectionListener(new SelectionAdapter() { | 
 | 			public void widgetSelected(SelectionEvent event) { | 
 | 				String fileName = new FileDialog(shell).open(); | 
 | 				if (fileName != null) { | 
 | 					dogImage = new Image(display, fileName); | 
 | 				} | 
 | 			} | 
 | 		}); | 
 | 		 | 
 | 		data = new FormData(); | 
 | 		data.left = new FormAttachment(browse, 0, SWT.LEFT); | 
 | 		data.top = new FormAttachment(browse, 5); | 
 | 		data.right = new FormAttachment(dogPhoto, -5); | 
 | 		delete.setLayoutData(data); | 
 | 		delete.addSelectionListener(new SelectionAdapter() { | 
 | 			public void widgetSelected(SelectionEvent event) { | 
 | 				if (dogImage != null) { | 
 | 					dogImage.dispose(); | 
 | 					dogImage = null; | 
 | 					dogPhoto.redraw(); | 
 | 				} | 
 | 			} | 
 | 		}); | 
 | 		 | 
 | 		data = new FormData(90, 140); | 
 | 		data.top = new FormAttachment(dogPhoto, 0, SWT.TOP); | 
 | 		data.right = new FormAttachment(100, 0); | 
 | 		data.bottom = new FormAttachment(enter, -5); | 
 | 		categories.setLayoutData(data); | 
 | 		 | 
 | 		data = new FormData(); | 
 | 		data.bottom = new FormAttachment(categories, -5); | 
 | 		data.left = new FormAttachment(categories, 0, SWT.CENTER); | 
 | 		cats.setLayoutData(data); | 
 | 		 | 
 | 		data = new FormData(); | 
 | 		data.right = new FormAttachment(100, 0); | 
 | 		data.bottom = new FormAttachment(100, 0); | 
 | 		enter.setLayoutData(data); | 
 | 		enter.addSelectionListener(new SelectionAdapter() { | 
 | 			public void widgetSelected(SelectionEvent event) { | 
 | 				System.out.println("\nDog Name: " + dogNameText.getText()); | 
 | 				System.out.println("Dog Breed: " + dogBreedCombo.getText()); | 
 | 				System.out.println("Owner Name: " + nameText.getText()); | 
 | 				System.out.println("Owner Phone: " + phoneText.getText()); | 
 | 				System.out.println("Categories:"); | 
 | 				String cats[] = categories.getSelection(); | 
 | 				for (int i = 0; i < cats.length; i++) { | 
 | 					System.out.println("\t" + cats[i]); | 
 | 				} | 
 | 			} | 
 | 		}); | 
 | 		 | 
 | 		data = new FormData(); | 
 | 		data.bottom = new FormAttachment(enter, -5); | 
 | 		data.left = new FormAttachment(0, 0); | 
 | 		data.right = new FormAttachment(categories, -5); | 
 | 		ownerInfo.setLayoutData(data); | 
 | 		 | 
 | 		Label name = new Label(ownerInfo, SWT.NULL); | 
 | 		name.setText("Name:"); | 
 | 		 | 
 | 		Label phone = new Label(ownerInfo, SWT.PUSH); | 
 | 		phone.setText("Phone:"); | 
 | 		 | 
 | 		nameText = new Text(ownerInfo, SWT.SINGLE | SWT.BORDER); | 
 | 		phoneText = new Text(ownerInfo, SWT.SINGLE | SWT.BORDER); | 
 | 		 | 
 | 		data = new FormData(); | 
 | 		data.top = new FormAttachment(nameText, 0, SWT.CENTER); | 
 | 		name.setLayoutData(data); | 
 | 		 | 
 | 		data = new FormData(); | 
 | 		data.top = new FormAttachment(phoneText, 0, SWT.CENTER); | 
 | 		phone.setLayoutData(data); | 
 | 		 | 
 | 		data = new FormData(); | 
 | 		data.left = new FormAttachment(phone, 5); | 
 | 		data.right = new FormAttachment(100, 0); | 
 | 		nameText.setLayoutData(data); | 
 | 		 | 
 | 		data = new FormData(); | 
 | 		data.left = new FormAttachment(nameText, 0, SWT.LEFT); | 
 | 		data.right = new FormAttachment(100, 0); | 
 | 		data.top = new FormAttachment(55, 0); | 
 | 		phoneText.setLayoutData(data); | 
 | 		 | 
 | 		shell.pack(); | 
 | 		 | 
 | 		return shell; | 
 | 	}	 | 
 | }</pre> | 
 |  | 
 | <p>This is what the layout looks like after Mary Smith enters | 
 | Bifford in the dog show:</p> | 
 |  | 
 | <img src="images/DogShowBiffWithFormLayout.png" /> | 
 |  | 
 | <p>When the window is resized, the same controls are resized as in | 
 | the <code>GridLayout</code> example.</p> | 
 |  | 
 | <img src="images/DogShowBiffWithFormLayoutResized.png" /> | 
 |  | 
 | <h2>Writing Your Own Layout Class</h2> | 
 |  | 
 | <p>Occasionally, you may want to write your own <code>Layout</code> | 
 | class. Perhaps your layout needs are very complex. Maybe you have the | 
 | same look in many places, and you want to take advantage of code reuse. | 
 | Or you want to leverage domain knowledge to create a very efficient | 
 | layout class. Whatever the reason, there are things to consider before | 
 | writing a new class:</p> | 
 |  | 
 | <ul> | 
 | 	<li>Can the layout be done using a <code>GridLayout</code> or <code>FormLayout</code>, | 
 | 	with maybe a few nested layouts?</li> | 
 | 	<li>Can the desired effect be more easily achieved with a resize | 
 | 	listener?</li> | 
 | 	<li>Are you defining a general layout algorithm or just | 
 | 	positioning widgets?</li> | 
 | </ul> | 
 |  | 
 | <p>Unless you are writing a very generic <code>Layout</code> type | 
 | that will be used by several <code>Composite</code> widgets, it is often | 
 | better and easier to simply calculate sizes and position children in a | 
 | resize listener. Many of the SWT custom widgets were written this way. | 
 | Although a new widget can be implemented as a <code>Composite</code>/<code>Layout</code> | 
 | pair, implementing it as a <code>Composite</code> that does its layout | 
 | in a resize listener and computes its preferred size in <code>computeSize</code> | 
 | is clearer, and does not involve writing an extra class.</p> | 
 |  | 
 | <p>First, we will look at how layouts work, and then we will create | 
 | a new <code>Layout</code> class. Another example of writing your own <code>Layout</code> | 
 | can be found in the <i>Compound Widget Example</i> section of <a | 
 | 	href="http://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm">Creating | 
 | Your Own Widgets Using SWT</a>, which shows how to achieve the same look | 
 | using either a resize listener or a new <code>Layout</code> class.</p> | 
 |  | 
 | <h3>How Layouts Work</h3> | 
 |  | 
 | <p><code>Layout</code> is the abstract superclass of all layouts. It | 
 | only has two methods: <code>computeSize</code> and <code>layout</code>. | 
 | The class is defined as follows:</p> | 
 |  | 
 | <pre>public abstract class Layout { | 
 |     protected abstract Point computeSize(Composite composite, int widthHint, int heightHint, boolean flushCache); | 
 |     protected abstract void layout(Composite composite, boolean flushCache); | 
 | }</pre> | 
 |  | 
 | <p>The <code>computeSize</code> method calculates the width and | 
 | height of a rectangle that encloses all of the <code>Composite</code>'s | 
 | children once they have been sized and placed according to the layout | 
 | algorithm encoded in the <code>Layout</code> class. The hint parameters | 
 | allow the width and/or height to be constrained. For example, a layout | 
 | may choose to grow in one dimension if constrained in another. A hint of | 
 | SWT.DEFAULT means to use the preferred size.</p> | 
 |  | 
 | <p>The <code>layout</code> method positions and sizes the <code>Composite</code>'s | 
 | children. A <code>Layout</code> can choose to cache layout-related | 
 | information, such as the preferred extent of each of the children. The <code>flushCache</code> | 
 | parameter tells the <code>Layout</code> to flush cached data.</p> | 
 |  | 
 | <p>Since a <code>Layout</code> controls the size and placement of | 
 | widgets in a <code>Composite</code>, there are several methods in <code>Composite</code> | 
 | that are used with <code>Layout</code>s.</p> | 
 |  | 
 | <p>The first two methods allow setting and getting a <code>Layout</code> | 
 | object in a <code>Composite</code>.</p> | 
 |  | 
 | <pre>public void setLayout(Layout layout); | 
 | public Layout getLayout();</pre> | 
 |  | 
 | <p>An application can force a <code>Layout</code> to recalculate the | 
 | sizes of and reposition children by sending <code>layout()</code> to the | 
 | parent <code>Composite</code>.</p> | 
 |  | 
 | <pre>public void layout(boolean changed);
 | 
 | public void layout(); | 
 |     // calls layout(true);</pre> | 
 |  | 
 | <p>You would do this after changing anything about the children that | 
 | might affect their size or position, such as changing the font of a | 
 | child, changing the text or image of a child, adding a new child, or | 
 | adding children to a child (If the child can accommodate the change, | 
 | then layout may not be necessary; for example, changing the font or | 
 | text of a scrollable multi-line <code>Text</code>). Since these changes | 
 | are done programmatically, they do not cause events to happen. | 
 | Consequently, the parent doesn't know about the changes, and has to be | 
 | told through the <code>layout</code> method. This strategy reduces flash | 
 | because the application can make several changes and then tell the | 
 | parent to layout, and the children are only redrawn once instead of once | 
 | per change. If <code>layout()</code> is not called and changes are made | 
 | after the shell is opened, then the children may not be correctly laid | 
 | out until the shell is somehow resized. Note that <code>shell.open()</code> | 
 | causes a layout to occur.</p> | 
 |  | 
 | <p>The <code>computeSize</code> methods of a <code>Composite</code> | 
 | calculate the Composite's preferred size, which is the size of its | 
 | client area as determined by the <code>Layout</code>, plus its trim.</p> | 
 |  | 
 | <pre>public Point computeSize(int widthHint, int heightHint, boolean changed); | 
 | public Point computeSize(int widthHint, int heightHint); | 
 |     // calls computeSize(widthHint, heightHint, true);</pre> | 
 |  | 
 | <p>The <b>clientArea</b> of a <code>Composite</code> is the | 
 | rectangle that will contain all of the children. A <code>Layout</code> | 
 | positions the children inside the client area.</p> | 
 |  | 
 | <pre>public Rectangle getClientArea ();</pre> | 
 |  | 
 | <p>The <b>trim</b> of a <code>Composite</code> is the area outside | 
 | the client area. For some composites, the size of the trim is zero. The | 
 | trim can be computed by passing the dimensions of the client area into | 
 | the method <code>computeTrim</code>.</p> | 
 |  | 
 | <pre>public Rectangle computeTrim (int x, int y, int width, int height);</pre> | 
 |  | 
 | <p>Sending <code>pack</code> to a <code>Composite</code> resizes it | 
 | to its preferred size.</p> | 
 |  | 
 | <pre>public void pack(boolean changed); | 
 |     // calls setSize(computeSize(SWT.DEFAULT, SWT.DEFAULT, changed)); | 
 | public void pack(); | 
 |     // calls pack(true);</pre> | 
 |  | 
 | <p>The boolean parameter to the <code>layout</code>, <code>computeSize</code>, | 
 | and <code>pack</code> methods is the <code>changed</code> flag. If <code>true</code>, | 
 | it indicates that the <code>Composite</code>'s contents have changed in | 
 | some way that affects its preferred size, therefore any caches that the | 
 | <code>Layout</code> may have been keeping need to be flushed. When a <code>Composite</code> | 
 | is resized, it asks its <code>Layout</code> to lay out its children by | 
 | calling layout(false); therefore widget content caches are <i>not</i> | 
 | flushed. This lets the <code>Layout</code> perform any expensive | 
 | calculations only when necessary.</p> | 
 |  | 
 | <p>Caching can increase performance, but it can also be tricky. You | 
 | can choose not to cache at all: in fact, it is best not to try caching | 
 | until your code is stable. When considering what to cache, be certain | 
 | not to store any widget state, such as the text of a label, or the | 
 | number of items in a list.</p> | 
 |  | 
 | <h3>Custom Layout Example</h3> | 
 |  | 
 | <p>If you have several vertically oriented <code>Composite</code> | 
 | widgets in your application, you might choose to write <code>ColumnLayout</code>. | 
 | We will show a simple version of a <code>Layout</code> class that lays | 
 | out <code>Composite</code> children into a single column. The class has | 
 | fixed margins and spacing. Children are given the same width, but they | 
 | take their natural height. (Note that <code>RowLayout</code> will have <code>ColumnLayout</code> | 
 | behaviour if its type is set to <code>SWT.VERTICAL</code>. This example is, | 
 | therefore, just an example. In practice, if you need to lay widgets out | 
 | in a column, you would use <code>RowLayout.</code>)</p> | 
 |  | 
 | <p>The code for the <code>ColumnLayout</code> class is below. Note | 
 | that we cache the width of the widest child, and the sum of the child | 
 | heights (plus spacing), and these values are used to compute the size | 
 | and lie out the children. They are recalculated if <code>flushCache</code> | 
 | is <code>true</code>.</p> | 
 |  | 
 | <pre>import org.eclipse.swt.*; | 
 | import org.eclipse.swt.graphics.*; | 
 | import org.eclipse.swt.widgets.*; | 
 | import org.eclipse.swt.layout.*; | 
 |  | 
 | public class ColumnLayout extends Layout { | 
 |     // fixed margin and spacing | 
 |     public static final int MARGIN = 4; | 
 |     public static final int SPACING = 2; | 
 |     // cache | 
 |     Point[] sizes; | 
 |     int maxWidth, totalHeight; | 
 |  | 
 |     protected Point computeSize(Composite composite, int wHint, int hHint, | 
 |             boolean flushCache) { | 
 |         Control children[] = composite.getChildren(); | 
 |         if (flushCache || sizes == null || sizes.length != children.length) { | 
 |             initialize(children); | 
 |         } | 
 |         int width = wHint, height = hHint; | 
 |         if (wHint == SWT.DEFAULT) | 
 |             width = maxWidth; | 
 |         if (hHint == SWT.DEFAULT) | 
 |             height = totalHeight; | 
 |         return new Point(width + 2 * MARGIN, height + 2 * MARGIN); | 
 |     } | 
 |  | 
 |     protected void layout(Composite composite, boolean flushCache) { | 
 |         Control children[] = composite.getChildren(); | 
 |         if (flushCache || sizes == null || sizes.length != children.length) { | 
 |             initialize(children); | 
 |         } | 
 |         Rectangle rect = composite.getClientArea(); | 
 |         int x = MARGIN, y = MARGIN; | 
 |         int width = Math.max(rect.width - 2 * MARGIN, maxWidth); | 
 |         for (int i = 0; i < children.length; i++) { | 
 |             int height = sizes[i].y; | 
 |             children[i].setBounds(x, y, width, height); | 
 |             y += height + SPACING; | 
 |         } | 
 |     } | 
 |  | 
 |     void initialize(Control children[]) { | 
 |         maxWidth = 0; | 
 |         totalHeight = 0; | 
 |         sizes = new Point[children.length]; | 
 |         for (int i = 0; i < children.length; i++) { | 
 |             sizes[i] = children[i].computeSize(SWT.DEFAULT, SWT.DEFAULT, true); | 
 |             maxWidth = Math.max(maxWidth, sizes[i].x); | 
 |             totalHeight += sizes[i].y; | 
 |         } | 
 |         totalHeight += (children.length - 1) * SPACING; | 
 |     } | 
 | }</pre> | 
 |  | 
 | <p>Here is some simple test code to test the <code>ColumnLayout</code>. | 
 | The <b>grow</b> and <b>shrink</b> <code>Buttons</code> show a call to | 
 | the <code>Shell</code>'s <code>layout()</code> method to force a | 
 | re-layout after changing the width of one of the children. Calling <code>layout()</code> | 
 | is the same as calling <code>layout(true</code>) which tells the <code>ColumnLayout</code> | 
 | to flush its caches before setting the bounds of the children. The <code>Shell</code> | 
 | is also told to <code>pack()</code> after laying out the children. This | 
 | forces the <code>Shell</code> to take the new size.</p> | 
 |  | 
 | <pre>import org.eclipse.swt.*; | 
 | import org.eclipse.swt.widgets.*; | 
 | import org.eclipse.swt.layout.*; | 
 | import org.eclipse.swt.events.*; | 
 |  | 
 | public class ColumnLayoutTest { | 
 |     static Shell shell; | 
 |     static Button button3; | 
 |  | 
 |     public static void main(String[] args) { | 
 |         Display display = new Display(); | 
 |         shell = new Shell(display); | 
 |         shell.setLayout(new ColumnLayout()); | 
 |         new Button(shell, SWT.PUSH).setText("B1"); | 
 |         new Button(shell, SWT.PUSH).setText("Very Wide Button 2"); | 
 |         (button3 = new Button(shell, SWT.PUSH)).setText("Button 3"); | 
 |         Button grow = new Button(shell, SWT.PUSH); | 
 |         grow.setText("Grow Button 3"); | 
 |         grow.addSelectionListener(new SelectionAdapter() { | 
 |             public void widgetSelected(SelectionEvent e) { | 
 |                 button3.setText("Extreemely Wide Button 3"); | 
 |                 shell.layout(); | 
 |                 shell.pack(); | 
 |             } | 
 |         }); | 
 |         Button shrink = new Button(shell, SWT.PUSH); | 
 |         shrink.setText("Shrink Button 3"); | 
 |         shrink.addSelectionListener(new SelectionAdapter() { | 
 |             public void widgetSelected(SelectionEvent e) { | 
 |                 button3.setText("Button 3"); | 
 |                 shell.layout(); | 
 |                 shell.pack(); | 
 |             } | 
 |         }); | 
 |         shell.pack(); | 
 |         shell.open(); | 
 |         while (!shell.isDisposed()) { | 
 |             if (!display.readAndDispatch()) | 
 |                 display.sleep(); | 
 |         } | 
 |     } | 
 | }</pre> | 
 |  | 
 | <p>If we run the test code, the window on the left appears. Pressing | 
 | the Grow Button 3 button results in the window on the right. Resizing | 
 | the window with the mouse will also make the buttons wider (or narrower) | 
 | but they do not grow taller.</p> | 
 |  | 
 | <img src="images/CustomLayout.png" /> <img | 
 | 	src="images/CustomLayoutResized.png" /> | 
 |  | 
 | <h3>Overriding Composite</h3> | 
 |  | 
 | <p>If you are writing your own widget, as outlined in <a | 
 | 	href="http://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm">Creating | 
 | Your Own Widgets Using SWT</a>, and you subclass Composite, then here are a | 
 | few points to consider for your implementation:</p> | 
 |  | 
 | <ul> | 
 | 	<li>If you are providing trimmings in your new <code>Composite</code>, | 
 | 	make sure to override both <code>computeTrim()</code> and <code>getClientArea()</code>.</li> | 
 | 	<li>Never override <code>layout()</code>, but you may override <code>layout(boolean)</code>.</li> | 
 | </ul> | 
 |  | 
 | <p>Sometimes you want your new <code>Composite</code> to have a | 
 | specific look, and you don't want the application to be able to specify | 
 | a layout. Your new <code>Composite</code> would either do its layout in | 
 | a resize handler or using a private custom layout. In either case, you | 
 | will probably want to do the following:</p> | 
 |  | 
 | <ul> | 
 | 	<li>Override <code>setLayout()</code> to do nothing.</li> | 
 | 	<li>Override <code>layout(boolean)</code> to call your layout | 
 | 	code.</li> | 
 | 	<li>Override <code>computeSize()</code> to correctly compute the | 
 | 	size of your <code>Composite</code>.</li> | 
 | </ul> | 
 |  | 
 |  | 
 | <h2>Summary</h2> | 
 |  | 
 | <p>SWT provides several different ways to lay out widgets. The | 
 | simplest method, and the one you will typically use, is to use one of | 
 | the standard <code>Layout</code> classes: <code>FillLayout</code>, <code>RowLayout</code>, | 
 | <code>GridLayout</code> or <code>FormLayout</code>.</p> | 
 |  | 
 |  | 
 | <p>In certain cases you may want to write your own <code>Layout</code> | 
 | class to provide a very specific look or to reuse very similar layout | 
 | code, but often a resize listener on the parent widget will suffice.</p> | 
 |  | 
 |  | 
 |  | 
 | <p>For further assistance in understanding the standard SWT <code>Layout</code> | 
 | classes, see the <a href="http://www.eclipse.org/swt/snippets">SWT Snippets</a>.</p> | 
 | </div> | 
 |  | 
 | </body> | 
 |  | 
 |  | 
 |  | 
 |  | 
 | </html> |