|  | <html> | 
|  | <head> | 
|  | <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/> | 
|  | <title>Eclipse Forms: Rich UI for Rich Client Applications</title> | 
|  | <link href="../default_style.css" rel="stylesheet"/> | 
|  | </head> | 
|  | <body> | 
|  | <div align="right"> | 
|  | Copyright © 2005 International Business Machines Corp. | 
|  | <table border="0" cellpadding="2" cellspacing="0" width="100%"> | 
|  | <tr> | 
|  | <td bgcolor="#0080C0" colspan="2" valign="top"> | 
|  | <p><font color="#FFFFFF"><b> Eclipse Corner | 
|  | Article</b></font></p> | 
|  | </td> | 
|  | </tr> | 
|  | </table> | 
|  | </div> | 
|  | <div> | 
|  | <h1><img class="center" height="86" src="images/Idea.jpg" width="120"/></h1> | 
|  | </div> | 
|  | <h1 class="center">Eclipse Forms: Rich UI for the Rich Client</h1> | 
|  | <blockquote> | 
|  | <p><b>Summary</b></p> | 
|  |  | 
|  | <p>Spice up your rich client with rich user experience using | 
|  | Eclipse Forms. Written as a thin layer on top of SWT, Eclipse | 
|  | Forms allow you to achieve the Web look in your desktop | 
|  | applications without using the embedded browser. This allows you | 
|  | to retain full control of the widgets in the UI and to maintain | 
|  | portability across all operating systems Eclipse already runs on. | 
|  | This article will take you from baby steps to advanced topics of | 
|  | the rich user interface experience of Eclipse Forms.</p> | 
|  |  | 
|  | <p><b>By Dejan Glozic, IBM Canada Ltd.</b></p> | 
|  | <p>January 16, 2005</p> | 
|  | </blockquote> | 
|  |  | 
|  | <hr width="100%"/> | 
|  |  | 
|  | <h2>The History (as we see it)</h2> | 
|  |  | 
|  | <p>One of the fundamental features of the Eclipse platform is that | 
|  | applications built on top of it look, feel and smell like genuine | 
|  | native applications. Thanks to SWT, menus, windows, trees, tables, | 
|  | buttons and other widgets all feel 'right' no matter what | 
|  | OS or windowing system you are on. Being one of the first members | 
|  | of the Eclipse team, I remember the days when I could get hours | 
|  | of joy by playing with our prototype Eclipse code. Menus are | 
|  | real. Tool bars are real. Combos, text, button, check boxes, radios are | 
|  | all real. There is not a drawn widget in sight, all are native widgets.</p> | 
|  |  | 
|  | <p>For a long time, if your plug-ins contributed Eclipse user | 
|  | interface artifacts, they would generally fall into the following | 
|  | categories:</p> | 
|  |  | 
|  | <ol> | 
|  | <li>Editors</li> | 
|  | <li>Views</li> | 
|  | <li>Wizards</li> | 
|  | <li>Dialogs</li> | 
|  | </ol> | 
|  |  | 
|  | <p>There are clear presentation rules for artifacts in these categories. | 
|  | We are used to seeing trees and | 
|  | tables in views, documents in editors and grids of simple widgets | 
|  | like buttons and text fields in wizards and dialogs. These rules | 
|  | are easy to follow and live by as long as your application is | 
|  | similar in principle to Eclipse SDK.</p> | 
|  |  | 
|  | <p>The RCP (Rich Client Platform) concept in Eclipse 3.x represents | 
|  | a fundamental broadening of the platform scope. It brought as a | 
|  | corollary an effective explosion of the problem domains. You can now build Rich | 
|  | client applications on top of Eclipse that have | 
|  | little in common with IDEs. While generic workbench parts like | 
|  | views and editors continue to work well, the widgets that are | 
|  | populating these parts in IDEs (trees, tables, text editors, etc...) | 
|  | may not be the best solution for this class of applications. | 
|  | Available since Eclipse 3.0, Eclipse Forms are designed to offer | 
|  | appealing alternatives.</p> | 
|  |  | 
|  | <p>Ironically, we developed Eclipse Forms as a solution for a | 
|  | concrete problem in the Eclipse SDK long before RCP existed as a | 
|  | concept. Developers of the PDE (Plug-in Development Environment) | 
|  | working on the plug-in manifest editor did not feel happy with | 
|  | following a Java editor paradigm of offering a color-coded, | 
|  | context-assisted text editor for the plugin.xml file. There is | 
|  | nothing wrong with Java editor in Eclipse by itself - in fact, it | 
|  | is very powerful and ideally suited for the task. However, it was | 
|  | designed for editing Java source files. In plug-in manifests, XML | 
|  | was used as a format to describe data at a higher level of | 
|  | abstraction. Editing XML by hand, even with color-coding and | 
|  | context assist/code completion was not perceived as the correct | 
|  | level of abstraction for the majority of users. In a plug-in | 
|  | manifest, the syntax itself is not important (yet another thing to | 
|  | learn). It is the data and what it represents that is important.</p> | 
|  |  | 
|  | <p>A good example of different ways of looking at markup | 
|  | is HTML authoring tools. At the source code level, all we can see | 
|  | are nested elements with the associated attributes. Although we see | 
|  | the syntax, it is hard to visualize what it really represents. A | 
|  | WYSIWYG view of the document can reveal a table, colors, some texts that span tables, images, etc. | 
|  | Working with HTML files at this level of | 
|  | abstraction is vastly more productive because syntax and markup are | 
|  | hidden in the background (which is the reason why I am typing this | 
|  | article on a WYSIWYG HTML authoring tool instead of hacking HTML | 
|  | tags).</p> | 
|  |  | 
|  | <p>It is easy to understand what WYSIWYG concept means for HTML | 
|  | documents. Since the HTML tags represent instructions for the web | 
|  | browser on how to compose a document from text, presentation | 
|  | attributes, hyperlinks and images, WYSIWYG in this context means | 
|  | editing the document in its final form -- as close as possible to | 
|  | the way it will appear in the browser. It was harder to figure out | 
|  | what the alternative presentation would mean for the plug-in | 
|  | manifest editor. Ultimately, the team made the following decisions:</p> | 
|  |  | 
|  | <ol> | 
|  |  | 
|  | <li>Represent each section of the manifest in the way | 
|  | most suitable for its nature. For example, vital information | 
|  | like plug-in name, provider etc. can be easily edited in a text | 
|  | field. Hierarchical structure of extensions maps nicely into the | 
|  | tree widget etc.</li> | 
|  |  | 
|  | <li>Show sections of the manifest on separate editor pages, | 
|  | regardless of their physical order in the source</li> | 
|  |  | 
|  | <li>Pages of the editor would keep a document feel and would be | 
|  | able to host a mix of widgets, hyperlinks, images and text, and | 
|  | offer scroll bars when content is too large for the page | 
|  | size.</li> | 
|  |  | 
|  | </ol> | 
|  |  | 
|  | <p class="center"><img border="0" height="488" | 
|  | src="images/plugin-overview.jpg" width="546"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 1: </b>The Plug-in manifest editor as it | 
|  | first appeared in Eclipse SDK 1.0. It offered a mixture SWT | 
|  | widgets, hyperlinks and images that could scroll when there is not | 
|  | enough space (as you would expect in a web browser). Note how all | 
|  | the widgets have the 'flat' look that was selected for | 
|  | less clutter and better fit in the document context.</p> | 
|  |  | 
|  | <p>The third point effectively spelled the birth of a plug-in that | 
|  | now goes by the name of Eclipse Forms. Soon after release 1.0, | 
|  | other developers wanted to replicate the rich user interface that | 
|  | appeared in PDE multi-page editors. It was finally made available | 
|  | as a plug-in with public APIs in Eclipse 3.0. </p> | 
|  |  | 
|  | <p>In the following text, we will show you what Eclipse Forms are | 
|  | (and what they are not) and how to use them to create rich UI with | 
|  | little effort.</p> | 
|  |  | 
|  | <h2>Eclipse Forms Mission</h2> | 
|  |  | 
|  | <p>Now that we know how Eclipse Forms came into being, it is useful | 
|  | to describe their mission before going into details:</p> | 
|  |  | 
|  | <blockquote> | 
|  |  | 
|  | <p><i><b>Eclipse Forms is an</b></i> <img align="baseline" | 
|  | height="13" src="images/tag_1.gif" width="24"/><i><b>optional | 
|  | Rich Client plug-in</b></i> <img align="baseline" height="13" | 
|  | src="images/tag_2.gif" width="24"/><i><b>based on SWT and JFace | 
|  | that provides the support for creating</b></i> | 
|  | <img align="baseline" height="13" src="images/tag_3.gif" | 
|  | width="24"/><i><b>portable web-style user interfaces</b></i> | 
|  | <img align="baseline" height="13" src="images/tag_4.gif" | 
|  | width="24"/><i><b>across all Eclipse UI categories.</b></i></p> | 
|  |  | 
|  | </blockquote> | 
|  |  | 
|  | <p>Let's look at the mission statement in more detail:</p> | 
|  |  | 
|  | <blockquote> | 
|  |  | 
|  | <table border="0" bordercolor="#111111" cellpadding="0" cellspacing="0" id="AutoNumber1" style="border-collapse: collapse" width="90%"> | 
|  |  | 
|  | <tr> | 
|  |  | 
|  | <td valign="top" width="25"><img class="center" alt="1" | 
|  | height="13" src="images/tag_1.gif" width="24"/></td> | 
|  |  | 
|  | <td width="744"> | 
|  |  | 
|  | <b>Optional Rich Client plug-in</b> - Eclipse Forms have | 
|  | been rewritten in the 3.0 release to depend only on the | 
|  | platform UI plug-in, and no longer rely on the PDE UI | 
|  | plug-in. Despite they are not part of the minimal RCP | 
|  | layer, you can add Eclipse Forms to any RCP application. | 
|  |  | 
|  | </td> | 
|  |  | 
|  | </tr> | 
|  |  | 
|  | <tr> | 
|  |  | 
|  | <td valign="top" width="25"><img class="center" alt="2" | 
|  | height="13" src="images/tag_2.gif" width="24"/></td> | 
|  |  | 
|  | <td width="744"><b>Based on SWT and JFace</b> - Eclipse Forms | 
|  | were not designed to compete with or offer an alternative to | 
|  | SWT or JFace. The plug-in consists of a few carefully chosen | 
|  | custom widgets, layouts and support classes to achieve the | 
|  | desired effect when used with SWT and JFace.</td> | 
|  |  | 
|  | </tr> | 
|  |  | 
|  | <tr> | 
|  |  | 
|  | <td valign="top" width="25"><img class="center" alt="3" | 
|  | height="13" src="images/tag_3.gif" width="24"/></td> | 
|  |  | 
|  | <td width="744"><b>Portable web-style user interfaces</b> -- | 
|  | obviously, an Eclipse Form often looks like a web page. | 
|  | The fact that each aspect of the form is | 
|  | programmatically accessible at all times makes forms | 
|  | powerful and attractive. Achieving the same flexibility in a | 
|  | browser would require extensive DOM support and often | 
|  | proprietary interactions. Eclipse Forms are portable, | 
|  | being written on top of SWT and JFace.</td> | 
|  |  | 
|  | </tr> | 
|  |  | 
|  | <tr> | 
|  |  | 
|  | <td valign="top" width="25"><img class="center" alt="4" | 
|  | height="13" src="images/tag_4.gif" width="24"/></td> | 
|  |  | 
|  | <td width="744"><b>Across all Eclipse UI categories</b> - | 
|  | Eclipse Forms breaks the mode by which certain classes of | 
|  | widgets are be expected only in certain Eclipse UI categories | 
|  | (editors, views, wizards, dialogs). An Eclipse form can | 
|  | appear in any UI category, expanding development | 
|  | possibilities. The UI developers can use the most appropriate | 
|  | concept for the task.</td> | 
|  |  | 
|  | </tr> | 
|  |  | 
|  | </table> | 
|  |  | 
|  | </blockquote> | 
|  |  | 
|  | <p>Point <img align="baseline" alt="2" height="13" | 
|  | src="images/tag_2.gif" width="24"/> cannot be underestimated. When | 
|  | building interfaces in Eclipse Forms, you are using SWT. There is | 
|  | no Eclipse Forms button, or Eclipse Forms tree widget as an | 
|  | alternative to SWT widget. Instead, you are using Eclipse Forms | 
|  | support to tweak subtly the existing widget set to achieve a richer | 
|  | user experience.</p> | 
|  |  | 
|  | <p>Eclipse Forms make these rich user interfaces possible with the | 
|  | following elements:</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li>A concept of a 'form' that is suitable for | 
|  | inclusion in content areas such as views and editors</li> | 
|  |  | 
|  | <li>A toolkit to manage colors, hyperlink groups and other | 
|  | aspects of a form, and serve as a factory for many SWT | 
|  | controls</li> | 
|  |  | 
|  | <li>A new layout manager that lays out controls in a manner | 
|  | similar to an HTML table layout algorithm</li> | 
|  |  | 
|  | <li>A set of custom controls designed to fit in the form | 
|  | (hyperlink, image hyperlink, scrollable composite, section)</li> | 
|  |  | 
|  | <li>A multi-page editor where most or all of the pages are forms | 
|  | (e.g. PDE manifest editors)</li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <p><img border="0" height="13" src="images/tip.gif" width="62"/> | 
|  | Although nothing in the design of Eclipse Forms prevents you from | 
|  | creating a form in a dialog, most of the usage scenarios have been | 
|  | focused on using forms in views and editors, rather than dialog and | 
|  | wizards. It is a matter of consistency -- having only a few | 
|  | form-based dialogs or wizards would look very strange when all | 
|  | other dialogs are 'normal'. Nevertheless, it is an | 
|  | interesting area to explore in the future.</p> | 
|  |  | 
|  | <h2>Baby steps</h2> | 
|  |  | 
|  | <p>It is very easy to start using Eclipse Forms in your user | 
|  | interfaces. You can start by adding a dependency on | 
|  | <b>org.eclipse.ui.forms</b> plug-in. We will create an Eclipse view | 
|  | that hosts a form and gradually fill in the content. Note that the | 
|  | plug-in with all the source code used in this article is available | 
|  | as a <a>zip archive</a>.</p> | 
|  |  | 
|  | <h3>Hello, Eclipse Forms</h3> | 
|  |  | 
|  | <p>We will start playing by adding an empty form to a view:</p> | 
|  |  | 
|  | <blockquote> | 
|  |  | 
|  | <pre>public class FormView extends ViewPart { | 
|  | private FormToolkit toolkit; | 
|  | private ScrolledForm form; | 
|  |  | 
|  | /** | 
|  | * The constructor. | 
|  | */ | 
|  | public FormView() { | 
|  | } | 
|  |  | 
|  | /** | 
|  | * This is a callback that will allow us to create the viewer and | 
|  | * initialize it. | 
|  | */ | 
|  | public void createPartControl(Composite parent) { | 
|  | <img align="baseline" height="13" src="images/tag_1.gif" width="24"/> toolkit = new FormToolkit(parent.getDisplay()); | 
|  | <img align="baseline" height="13" src="images/tag_2.gif" width="24"/> form = toolkit.createScrolledForm(parent); | 
|  | <img align="baseline" height="13" src="images/tag_3.gif" width="24"/> form.setText("Hello, Eclipse Forms"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Passing the focus request to the form. | 
|  | */ | 
|  | public void setFocus() { | 
|  | form.setFocus(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Disposes the toolkit | 
|  | */ | 
|  | public void dispose() { | 
|  | toolkit.dispose(); | 
|  | super.dispose(); | 
|  | } | 
|  | }</pre> | 
|  | </blockquote> | 
|  |  | 
|  | <p>As you can see from this code snippet, it does not take much to | 
|  | create a form. We start by creating an instance of a toolkit ( | 
|  | <img align="baseline" height="13" src="images/tag_1.gif" | 
|  | width="24"/>). We use the toolkit to <img align="baseline" | 
|  | height="13" src="images/tag_2.gif" width="24"/>create a scrolled | 
|  | form using the provided composite as a parent. We set the | 
|  | <img align="baseline" height="13" src="images/tag_3.gif" | 
|  | width="24"/> title of the form. We also make sure to transfer | 
|  | focus to the form when needed and dispose the toolkit when the view | 
|  | is disposed.</p> | 
|  |  | 
|  | <p>When we register the view using the class shown above and launch | 
|  | the second Eclipse instance, the view should look like this:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="221" | 
|  | src="images/hello1.gif" width="217"/> <img border="0" | 
|  | src="images/hello2.gif"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 2:</b> A simple empty form in a view. | 
|  | Making the view narrower will cause the form title to wrap. Once | 
|  | there is no more space to fit the entire form, scroll bars will | 
|  | appear.</p> | 
|  |  | 
|  | <p>Note that we have used scrolled form because we placed it in a | 
|  | view that can be resized. In the more complex situations where a | 
|  | form needs to be a child in a layout, a non-scrolled version is | 
|  | available. In this case, we would have called | 
|  | <code>FormToolkit.createForm()</code> instead and let the outmost | 
|  | parent worry about scrolling the overall content.</p> | 
|  |  | 
|  | <h3>Adding some content</h3> | 
|  |  | 
|  | <p>Now that we have the form view running, we can start adding some | 
|  | content to it. Eclipse forms have a body and we should create all | 
|  | the content there:</p> | 
|  |  | 
|  | <pre>public void createPartControl(Composite parent) { | 
|  | toolkit = new FormToolkit(parent.getDisplay()); | 
|  | form = toolkit.createForm(parent); | 
|  | form.setText("Hello, Eclipse Forms"); | 
|  | GridLayout layout = new GridLayout(); | 
|  | <img align="baseline" height="13" src="images/tag_1.gif" width="24"></img> form.getBody().setLayout(layout); | 
|  | <img align="baseline" height="13" src="images/tag_2.gif" width="24"></img> Hyperlink link = toolkit.createHyperlink(form.getBody(), | 
|  | "Click here.", SWT.WRAP); | 
|  | <img align="baseline" height="13" src="images/tag_3.gif" width="24"></img> link.addHyperlinkListener(new HyperlinkAdapter() { | 
|  | public void linkActivated(HyperlinkEvent e) { | 
|  | System.out.println("Link activated!"); | 
|  | } | 
|  | }); | 
|  | }</pre> | 
|  | <p>The body of the form is the usable space below the form title. | 
|  | Since this space is a SWT <code>Composite</code>, it can serve as a | 
|  | parent for other widgets. In the code above, we | 
|  | <img align="baseline" height="13" src="images/tag_1.gif" | 
|  | width="24"/> set the layout on the body, then <img align="baseline" | 
|  | height="13" src="images/tag_2.gif" width="24"/> create a | 
|  | hyperlink. The hyperlink is one of the few custom widgets that | 
|  | Eclipse Forms provide. The widget allows us to <img align="baseline" | 
|  | height="13" src="images/tag_3.gif" width="24"/> add a hyperlink | 
|  | listener so that we can be notified when the user clicks on the | 
|  | link.</p> | 
|  |  | 
|  | <p>The updated view should look like this:</p> | 
|  |  | 
|  | <p align="center"><img border="0" height="222" | 
|  | src="images/click-here.gif" width="198"/></p> | 
|  |  | 
|  | <p align="center"><b>Figure 3</b>: A simple form with a | 
|  | hyperlink</p> | 
|  |  | 
|  | <p>Note how hyperlink has a focus rectangle painted around it. Upon | 
|  | view activation, focus is transferred to the form, which passes it | 
|  | to the first control capable of accepting focus -- our link in this | 
|  | case. With the keyboard focus in the link, simply pressing the | 
|  | 'Enter' key would activate the link.</p> | 
|  |  | 
|  | <h4>Hyperlink Groups</h4> | 
|  |  | 
|  | <p>Form toolkit has a hyperlink group object. Each created | 
|  | hyperlink is added to this group object. Hyperlink groups serve | 
|  | several roles. They define colors -- for normal, hover and active states -- for all links in the group. They change colors of the managed links based on their | 
|  | state. They change underline style of the managed links based on | 
|  | their state. They manage cursors and show busy cursor before link | 
|  | listeners process the link activation, and revert it after. | 
|  | </p> | 
|  |  | 
|  | <p>You can change the default settings of the hyperlink group by | 
|  | getting the object from the toolkit with | 
|  | <code>getHyperlinkGroup()</code>.</p> | 
|  |  | 
|  | <h3>Creating common controls</h3> | 
|  |  | 
|  | <p>One of the design goals of Eclipse Forms was to allow the | 
|  | creation of common SWT controls in the editor/view content space. | 
|  | Since form body is a normal composite, you can use any layout and | 
|  | control you want inside it. However, remember that 'raw' | 
|  | SWT controls come with a widget background. We will now create some | 
|  | controls using their constructors:</p> | 
|  |  | 
|  | <pre>  layout.numColumns = 2; | 
|  | GridData gd = new GridData(); | 
|  | gd.horizontalSpan = 2; | 
|  | link.setLayoutData(gd); | 
|  | Label label = new Label(form.getBody(), SWT.NULL); | 
|  | label.setText("Text field label:"); | 
|  | Text text = new Text(form.getBody(), SWT.BORDER); | 
|  | text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | 
|  | Button button = new Button(form.getBody(), SWT.CHECK); | 
|  | button.setText("An example of a checkbox in a form"); | 
|  | gd = new GridData(); | 
|  | gd.horizontalSpan = 2; | 
|  | button.setLayoutData(gd);</pre> | 
|  | <p>We are now using two columns and creating a label, a text field | 
|  | and a checkbox. The result is below:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="183" | 
|  | src="images/no-toolkit.gif" width="240"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 4</b>: A form with SWT controls created | 
|  | directly using their constructors</p> | 
|  |  | 
|  | <p>What is wrong with this picture? The background of controls we | 
|  | created directly matches the system dialog background, not the form | 
|  | background. In addition, the text field looks fine because the | 
|  | screen capture was taken on Windows XP. On other windowing systems, | 
|  | it would look out of place due to the addition of a 3D border. To | 
|  | fix this problem, we will create these controls using the | 
|  | toolkit's factory methods instead:</p> | 
|  |  | 
|  | <pre>  Label label = toolkit.createLabel(form.getBody(), "Text field label:"); | 
|  | Text text = toolkit.createText(form.getBody(), ""); | 
|  | text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | 
|  | Button button = toolkit.createButton(form.getBody(), "A checkbox in a form", SWT.CHECK); | 
|  | gd = new GridData(); | 
|  | gd.horizontalSpan = 2; | 
|  | button.setLayoutData(gd);</pre> | 
|  | <p>The view will now look better:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="177" | 
|  | src="images/with-toolkit.gif" width="233"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 5:</b> A form with SWT controls created | 
|  | using the form toolkit as a factory</p> | 
|  |  | 
|  | <p>Factory methods provided by the form toolkit are there for your | 
|  | convenience. The toolkit is not all-inclusive --even for the SWT | 
|  | widget set-- and definitely not for the custom controls that you may | 
|  | have. A utility method <code>FormToolkit.adapt(Control control, | 
|  | boolean trackFocus, boolean trackKeyboard)</code> should be used to | 
|  | adapt an existing SWT control to fit into the form. Most of | 
|  | the factory methods call <code>adapt</code> themselves.</p> | 
|  |  | 
|  | <h4>Achieving the 'flat' look</h4> | 
|  |  | 
|  | <p>One of the recognizable attributes of Eclipse Forms used in PDE | 
|  | editors was the elegant 'flat' look of the controls. All | 
|  | the controls used there were without 3D borders that look fine in | 
|  | dialogs but less appealing in editors or views. This support is | 
|  | built into the FormToolkit class. However, on some platform it | 
|  | comes at a price of some custom rendering. For example, look at | 
|  | this screen capture from PDE editor (version 2.1):</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="507" | 
|  | src="images/plugin-dependencies.gif" width="545"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 6:</b> The flat look of Eclipse Forms | 
|  | circa Eclipse 2.1</p> | 
|  |  | 
|  | <p>Controls like tables, text entries, combo box etc. are rendered | 
|  | with a flat one-pixel border. These borders do not come from the | 
|  | controls themselves (SWT.BORDER style is not used). Instead -- if | 
|  | instructed -- the toolkit will add itself as a paint listener to | 
|  | each control's parent, and draw borders around controls during | 
|  | paint events. To make this happen, you need to call the toolkit | 
|  | method <code>paintBordersFor(parent)</code> for each composite | 
|  | where you created controls like text, tree, table etc. Note that | 
|  | one call per parent is enough: there is no need to make a call for | 
|  | each control of this type.</p> | 
|  |  | 
|  | <p>The Form toolkit knows which controls require a custom border. | 
|  | However, you may create a new one that also needs a border that is | 
|  | not on the list. You can give a hint to the toolkit by adding the | 
|  | following code:</p> | 
|  |  | 
|  | <div> | 
|  |  | 
|  | <blockquote> | 
|  |  | 
|  | <pre>Control myControl = new MyControl(parent); | 
|  | myControl.setData(FormToolkit.KEY_DRAW_BORDER, <strong>FormToolkit.TEXT_BORDER</strong>); | 
|  | // or myControl.setData(FormToolkit.KEY_DRAW_BORDER, <strong>FormToolkit.TREE_BORDER</strong>); | 
|  | toolkit.paintBordersFor(parent);</pre> | 
|  | </blockquote> | 
|  |  | 
|  | </div> | 
|  |  | 
|  | <p>As you can see from the picture above, 'structural' | 
|  | controls like trees and tables have a border style different from | 
|  | text areas and you can choose which one to render for your control. | 
|  | Note that this is not needed for controls created using | 
|  | toolkit's factory methods.</p> | 
|  |  | 
|  | <p><img height="13" src="images/win_only.gif" width="49"/> Since | 
|  | Eclipse 3.0 and on Windows XP, no border rendering is done when the | 
|  | file <code>javaw.exe.manifest</code> file is present in the | 
|  | Java virtual machine bin folder (I took all the screen shots in this article  on Windows XP). | 
|  | The presence of this file -- you can download | 
|  | one from the | 
|  | <a href="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/platform-swt-home/faq.html#xpthemes" | 
|  | >SWT home page</a> -- instructs the toolkit to use XP skins for | 
|  | native widgets. With XP skins, controls like text, table and tree | 
|  | are already flat and there is no need to adjust the look. For | 
|  | your code to be portable, you should always call | 
|  | <code>paintBordersFor(Composite)</code>, and let the toolkit choose | 
|  | what to do depending on the windowing system.</p> | 
|  |  | 
|  | <h2>Custom layouts</h2> | 
|  |  | 
|  | <p>Eclipse Forms offer two new layouts in addition to the base SWT layouts. | 
|  | These layouts extend the SWT <code>Layout</code> base class and | 
|  | can be used on any SWT composite, but are typically used in | 
|  | conjunction with Eclipse Forms.</p> | 
|  |  | 
|  | <h3>TableWrapLayout</h3> | 
|  |  | 
|  | <p>Now that we know how to populate the form, let's throw it a | 
|  | curve. We will change the hyperlink text to be much longer:</p> | 
|  |  | 
|  | <pre> link.setText("This is an example of a form that is much longer "+ | 
|  | "and will need to wrap.");</pre> | 
|  | <p>Let's see the result on screen:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="177" | 
|  | src="images/long-link.gif" width="233"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 7</b>: A form laid out using | 
|  | <code>GridLayout</code></p> | 
|  |  | 
|  | <p>What happened? Remember that we are using | 
|  | <code>GridLayout</code>. When it asked the link control to compute | 
|  | its size, it gave it the size needed to render the text in one long | 
|  | line. Although we instructed the control to wrap, it did not | 
|  | matter because <code>GridLayout</code> requires that a control | 
|  | return its size in isolation. The link itself -- as well as other | 
|  | SWT controls like <code>Label</code> -- is capable of computing the | 
|  | height given its width if you pass the width instead of | 
|  | <code>SWT.DEFAULT</code> in <code>computeSize</code>, but | 
|  | <code>GridLayout</code> is not passing the width as an argument.</p> | 
|  |  | 
|  | <p>What we need is a different layout algorithm that works more | 
|  | like HTML tables. We want the content to try to fit in the provided | 
|  | client area, and grow vertically to compensate. Eclipse Forms | 
|  | provide an alternative layout for just such a purpose called | 
|  | <code>TableWrapLayout</code>. There are many similarities between | 
|  | <code>GridLayout</code> and <code>TableWrapLayout</code>. Both | 
|  | organize parent's children in grids. Both have layout data | 
|  | that instructs the layout how to treat each control. Both can | 
|  | accept hints on which control should grab excess space etc.</p> | 
|  |  | 
|  | <p>However, they fundamentally differ in the approach to the | 
|  | layout. <code>TableWrapLayout</code> starts with columns. It | 
|  | computes minimal, preferred and maximum widths of each column and | 
|  | uses this information to assign excess space. It also tries to be | 
|  | fair when dividing space across columns so that there is no excess | 
|  | wrapping of some controls.</p> | 
|  |  | 
|  | <p>It is possible to mix <code>GridLayout</code> and | 
|  | <code>TableWrapLayout</code> but the branch of widgets tree where | 
|  | <code>GridLayout</code> is used is the one where wrapping stops. | 
|  | This is quite acceptable if you do not want it to wrap, | 
|  | typically if the composite contains controls that cannot wrap | 
|  | anyway, like text, buttons, trees etc... However, you should have an | 
|  | un-broken path from the form body to each text control that needs | 
|  | to wrap.</p> | 
|  |  | 
|  | <p>Let's rework our example to use <code>TableWrapLayout</code> | 
|  | (with changes highlighted):</p> | 
|  |  | 
|  | <pre> public void createPartControl(Composite parent) { | 
|  | toolkit = new FormToolkit(parent.getDisplay()); | 
|  | form = toolkit.createForm(parent); | 
|  | form.setText("Hello, Eclipse Forms"); | 
|  | <b><font color="#ff0000">TableWrapLayout layout = new TableWrapLayout();</font></b> | 
|  | form.getBody().setLayout(layout); | 
|  | Hyperlink link = toolkit.createHyperlink(form.getBody(),"Click here.", SWT.WRAP); | 
|  | link.addHyperlinkListener(new HyperlinkAdapter() { | 
|  | public void linkActivated(HyperlinkEvent e) { | 
|  | System.out.println("Link activated!"); | 
|  | } | 
|  | }); | 
|  | link.setText("This is an example of a form that is much longer and will need to wrap."); | 
|  | layout.numColumns = 2; | 
|  | <b><font color="#ff0000">TableWrapData td = new TableWrapData(); | 
|  | td.colspan = 2; | 
|  | link.setLayoutData(td);</font></b> | 
|  | Label label = toolkit.createLabel(form.getBody(), "Text field label:"); | 
|  | Text text = toolkit.createText(form.getBody(), ""); | 
|  | <b><font color="#ff0000">td = new TableWrapData(TableWrapData.FILL_GRAB); | 
|  | text.setLayoutData(td);</font></b> | 
|  | Button button = toolkit.createButton(form.getBody(), "A checkbox in a form", SWT.CHECK); | 
|  | <b><font color="#ff0000">td = new TableWrapData(); | 
|  | td.colspan = 2; | 
|  | button.setLayoutData(td);</font></b> | 
|  | }</pre> | 
|  | <p>We used the same concepts that for GridData. Some of | 
|  | the variables have different names (for example, | 
|  | <code>colspan</code> and <code>rowspan</code>, <code>align</code> | 
|  | and <code>valign</code> are taken from HTML TABLE attributes), but | 
|  | you are doing the same thing -- creating a grid with two columns | 
|  | where link and button span two columns. Since margins are the same | 
|  | as in <code>GridLayout</code>, the result will look similar except | 
|  | the link will now wrap:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="177" | 
|  | src="images/wrapped-link.gif" width="233"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 8:</b> A form laid out using | 
|  | <code>TableWrapLayout</code></p> | 
|  |  | 
|  | <p>One of the main differences between <code>TableWrapLayout</code> | 
|  | and <code>GridLayout</code> is that with the former you should stop | 
|  | thinking about the vertical dimension. In <code>GridLayout</code>, | 
|  | you would typically let the 'rigid' controls assume their | 
|  | natural positions and sizes and let 'flexible' controls | 
|  | (text, tree and table) grab horizontal and/or vertical excess space. | 
|  | In contrast, <code>TableWrapLayout</code> works top-down and when | 
|  | it places all the controls, its work is complete. The concept of grabbing | 
|  | excess space still exists in the horizontal dimension (as shown | 
|  | above). However, vertically you can only choose to FILL the cell in | 
|  | case it is taller than the control, or pick TOP, MIDDLE or BOTTOM | 
|  | vertical alignment.</p> | 
|  |  | 
|  | <p>You may notice one thing that may seem contradictory to the | 
|  | previous claim: <code>TableWrapData</code> still has | 
|  | <code>grabVertical</code> variable. However, the variable is here | 
|  | for a distinct purpose: when a fixed height control spans | 
|  | multiple rows, its height will create a local condition where vertical | 
|  | dimension is known, and controls in the spanned cells need to | 
|  | divide the extra space between them.</p> | 
|  |  | 
|  | <p>In order to have good results with <code>TableWrapLayout</code>, | 
|  | ensure that controls that can wrap have the appropriate style bit | 
|  | (<code>SWT.WRAP</code>). Composite custom controls provided by | 
|  | Eclipse Forms are wrap-enabled out of the box. This is achieved by | 
|  | using internal layouts that implement <code>ILayoutExtension</code> | 
|  | interface:</p> | 
|  |  | 
|  | <blockquote> | 
|  |  | 
|  | <pre>public interface ILayoutExtension { | 
|  | /** | 
|  | * Computes the minimum width of the parent. All widgets capable of word | 
|  | * wrapping should return the width of the longest word that cannot be | 
|  | * broken any further. | 
|  | * | 
|  | * @param parent the parent composite | 
|  | * @param changed <code>true</code> if the cached information should be | 
|  | * flushed, <code>false</code> otherwise. | 
|  | * @return the minimum width of the parent composite | 
|  | */ | 
|  | public int computeMinimumWidth(Composite parent, boolean changed); | 
|  |  | 
|  | /** | 
|  | * Computes the maximum width of the parent. All widgets capable of word | 
|  | * wrapping should return the length of the entire text with wrapping | 
|  | * turned off. | 
|  | * | 
|  | * @param parent the parent composite | 
|  | * @param changed <code>true</code> if the cached information | 
|  | * should be flushed, <code>false</code> otherwise. | 
|  | * @return the maximum width of the parent composite | 
|  | */ | 
|  | public int computeMaximumWidth(Composite parent, boolean changed); | 
|  | }</pre> | 
|  | </blockquote> | 
|  |  | 
|  | <p><code>TableWrapLayout</code> implements this interface itself, | 
|  | which allows it to handle cases where composites with this layout | 
|  | are children of the composite that is laid out. The additional two | 
|  | methods allow it to compute the two extreme cases - the absolute | 
|  | minimum width and the maximum width if all the controls are spread | 
|  | as wide as possible. The difference between the two allows the | 
|  | algorithm to distribute extra space fairly between columns to | 
|  | minimize excess wrapping.</p> | 
|  |  | 
|  | <p>Let's take a closer look at space distribution. We will comment | 
|  | the code we wrote so far in the view and replace it with the | 
|  | following:</p> | 
|  |  | 
|  | <pre> layout.numColumns = 3; | 
|  | Label label; | 
|  | TableWrapData td; | 
|  |  | 
|  | label = toolkit.createLabel(form.getBody(), | 
|  | "Some text to put in the first column", SWT.WRAP); | 
|  | label = toolkit.createLabel(form.getBody(), | 
|  | "Some text to put in the second column and make it a bit "+ | 
|  | "longer so that we can see what happens with column "+ | 
|  | distribution. This text must be the longest so that it can "+ | 
|  | "get more space allocated to the columns it belongs to.", | 
|  | SWT.WRAP); | 
|  | td = new TableWrapData(); | 
|  | td.colspan = 2; | 
|  | label.setLayoutData(td); | 
|  | label = toolkit.createLabel(form.getBody(), | 
|  | "This text will span two rows and should not grow the column.", | 
|  | SWT.WRAP); | 
|  | td = new TableWrapData(); | 
|  | td.rowspan = 2; | 
|  | label.setLayoutData(td); | 
|  | label = toolkit.createLabel(form.getBody(), | 
|  | "This text goes into column 2 and consumes only one cell", | 
|  | SWT.WRAP); | 
|  | label.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB)); | 
|  | label = toolkit.createLabel(form.getBody(), | 
|  | "This text goes into column 3 and consumes only one cell too", | 
|  | SWT.WRAP); | 
|  | label.setLayoutData(new TableWrapData(TableWrapData.FILL)); | 
|  | label = toolkit.createLabel(form.getBody(), | 
|  | "This text goes into column 2 and consumes only one cell", | 
|  | SWT.WRAP); | 
|  | label.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB)); | 
|  | label = toolkit.createLabel(form.getBody(), | 
|  | "This text goes into column 3 and consumes only one cell too", | 
|  | SWT.WRAP); | 
|  | label.setLayoutData(new TableWrapData(TableWrapData.FILL)); | 
|  | <img align="baseline" height="13" src="images/tag_1.gif" width="24" /> form.getBody().setBackground(form.getBody().getDisplay(). | 
|  | getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));</pre> | 
|  | <p>This code creates a number of wrapping labels with text of | 
|  | variable length. Some labels span columns, some span rows. To make | 
|  | the test easier, we will <img align="baseline" height="13" | 
|  | src="images/tag_1.gif" width="24"/> set the form background to | 
|  | widget background so that cells will be easy to spot. When we run | 
|  | the example, we will get the following:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="275" | 
|  | src="images/wrapped-layout.gif" width="266"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 9</b>: Excess space distribution in | 
|  | <code>TableWrapLayout</code></p> | 
|  |  | 
|  | <p>The key in space distribution is that the difference between | 
|  | control minimum and maximum width is compared. The greater the | 
|  | difference, the greater allocation of excess width will be for the | 
|  | column. Excess width is any width greater than the width needed to | 
|  | fit all the controls with their minimum widths taken into account. | 
|  | Notice how column 3 is slightly wider than column 2 because text in | 
|  | column 2 is somewhat longer. The overall goal is to avoid excessive | 
|  | empty space in cells. If you want to read more about the theory | 
|  | behind this layout algorithm, go to | 
|  | <a href="http://www.w3.org/TR/html4/appendix/notes.html#h-B.5.2.2"> | 
|  | W3C recommendations for HTML table auto-layout</a>.</p> | 
|  |  | 
|  | <h3>ColumnLayout</h3> | 
|  |  | 
|  | <p>Another Eclipse Forms custom layout is a variation of SWT | 
|  | <code>RowLayout</code>. If we configure <code>RowLayout</code> to | 
|  | place children vertically -- in columns-- and to make all controls | 
|  | have the same width within a column, we would get several columns, | 
|  | depending on the width of controls. However, the last column would | 
|  | typically not be completely filled -- depending on the number of | 
|  | controls. When placed in a form, we would again get all the | 
|  | controls in one column because <code>RowLayout</code> cannot do | 
|  | 'vertical' wrapping. If we use <code>GridLayout</code> | 
|  | instead, we would have to choose the number of columns up front and | 
|  | live with the choice.</p> | 
|  |  | 
|  | <p>There are situations in more complex forms where we want the | 
|  | number of columns to be adaptive. In other words, we would like the | 
|  | number to change depending on the width of the form -- use more | 
|  | when possible, drop the number down as the width decreases. We | 
|  | would also like to fill the form area equally like a newspaper | 
|  | layout, with all the columns roughly the same height. All this can | 
|  | be achieved with <code>ColumnLayout</code>.</p> | 
|  |  | 
|  | <p>Compared to <code>TableWrapLayout</code>, | 
|  | <code>ColumnLayout</code> is much simpler. Hardly any configuration | 
|  | is needed. The only choice you need to make is the range of columns | 
|  | you want to have (default is 1 to 3). The following example shows a | 
|  | form with a large number of sections (we will talk about sections | 
|  | later) using <code>ColumnLayout</code>. Initially, there is enough | 
|  | space to arrange the sections in two columns. | 
|  | When we make the editor narrower, the layout arranges the sections in only one column:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="481" | 
|  | src="images/two-columns.gif" width="583"/>  <img border="0" | 
|  | height="480" src="images/one-column.gif" width="413"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 10</b>: Sections arranged in columns | 
|  | using <code>ColumnLayout.</code> The layout started with two | 
|  | columns but dropped to one when there was not enough space to fit | 
|  | all the sections.</p> | 
|  |  | 
|  | <h2>Complex controls</h2> | 
|  |  | 
|  | <p>Eclipse Forms provide four complex custom controls that can help | 
|  | you build rich looking UI: expandable composite, section, image | 
|  | hyperlink and form text. Let's look closely at each of them.</p> | 
|  |  | 
|  | <h3>Expandable composite</h3> | 
|  |  | 
|  | <p>A common theme in sleek web pages is the ability to collapse a | 
|  | portion of the page content using a toggle control. Eclipse Forms | 
|  | offer such a control: <code>ExpandableComposite</code>.</p> | 
|  |  | 
|  | <div> | 
|  |  | 
|  | <pre> ExpandableComposite ec = toolkit.createExpandableComposite(form.getBody(), | 
|  | ExpandableComposite.TREE_NODE| | 
|  | ExpandableComposite.CLIENT_INDENT); | 
|  | ec.setText("Expandable Composite title"); | 
|  | String ctext = "We will now create a somewhat long text so that "+ | 
|  | "we can use it as content for the expandable composite. "+ | 
|  | "Expandable composite is used to hide or show the text using the " | 
|  | "toggle control"; | 
|  | Label client = toolkit.createLabel(ec, ctext, SWT.WRAP); | 
|  | ec.setClient(client); | 
|  | td = new TableWrapData(); | 
|  | td.colspan = 2; | 
|  | ec.setLayoutData(td); | 
|  | ec.addExpansionListener(new ExpansionAdapter() { | 
|  | public void expansionStateChanged(ExpansionEvent e) { | 
|  | form.reflow(true); | 
|  | } | 
|  | });</pre> | 
|  | </div> | 
|  |  | 
|  | <p>The composite accepts a number of styles that control its | 
|  | appearance and behavior. Style TREE_NODE will create the toggle | 
|  | control used in a tree widget for expanding and collapsing nodes, | 
|  | while TWISTIE will create a triangle-style toggle. Using EXPANDED | 
|  | will create the control in the initial expanded state. If style | 
|  | COMPACT is used, control will report width in the collapsed state | 
|  | enough to fit in the title line only (i.e. when collapsed, it will | 
|  | be as compact horizontally as possible). Finally, CLIENT_INDENT | 
|  | will indent the client to align with the title (otherwise, client | 
|  | will be aligned with the toggle control).</p> | 
|  |  | 
|  | <p><code>ExpandableComposite</code> is responsible for rendering | 
|  | the toggle control and the title. The client control to expand or | 
|  | collapse must be a direct child of the expandable composite.</p> | 
|  |  | 
|  | <p>We needed to add expansion listener to the control and 'reflow' | 
|  | the form on the state change. This is because expansion causes | 
|  | changes in expandable composite size, but the change will not take | 
|  | effect until the next time the parent is laid out (hence the need | 
|  | to force it). In general, every time you do something that causes | 
|  | the layout of the form to be invalid, you need to | 
|  | 'reflow' the form. 'Reflowing' the form will reposition the | 
|  | controls according to the new sizes and update the scroll bars.</p> | 
|  |  | 
|  | <p>Our view now looks like this:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="215" | 
|  | src="images/expandable-closed.gif" width="305"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 11</b>: An example of the expandable | 
|  | composite in the collapsed state</p> | 
|  |  | 
|  | <p>When you click on the '+' sign or on the title itself, | 
|  | composite expands to reveal the client:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="216" | 
|  | src="images/expandable-open.gif" width="304"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 12</b>: An example of the expandable | 
|  | composite in the expanded state</p> | 
|  |  | 
|  | <p>The expandable composite uses | 
|  | an internal layout implementing Eclipse Forms <code>ILayoutExtension</code>. Therefore you can add it to a parent that uses | 
|  | <code>TableWrapLayout</code>, as we did in the example above.</p> | 
|  |  | 
|  | <h3>Section</h3> | 
|  |  | 
|  | <p>One of the most versatile custom controls in Eclipse Forms (and | 
|  | seen in all PDE editors) is <code>Section</code>. It extends the | 
|  | expandable composite and introduces the following concepts:</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li> | 
|  | Separator - a separator control can be created below the | 
|  | title | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  | Description - an optional description can be added below the | 
|  | title (and below the separator, if present) | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  | Title bar - a title bar that encloses the section can be | 
|  | painted behind the title (note that separator and title bar | 
|  | should not be used simultaneously) | 
|  | </li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <p>The code is similar to the expandable composite code example:</p> | 
|  |  | 
|  | <pre> Section section = toolkit.createSection(form.getBody(), | 
|  | Section.DESCRIPTION|Section.TITLE_BAR| | 
|  | Section.TWISTIE|Section.EXPANDED); | 
|  | td = new TableWrapData(TableWrapData.FILL); | 
|  | td.colspan = 2; | 
|  | section.setLayoutData(td); | 
|  | section.addExpansionListener(new ExpansionAdapter() { | 
|  | public void expansionStateChanged(ExpansionEvent e) { | 
|  | form.reflow(true); | 
|  | } | 
|  | }); | 
|  | section.setText("Section title"); | 
|  | section.setDescription("This is the description that goes "+ | 
|  | below the title"); | 
|  | Composite sectionClient = toolkit.createComposite(section); | 
|  | sectionClient.setLayout(new GridLayout()); | 
|  | button = toolkit.createButton(sectionClient, "Radio 1", SWT.RADIO); | 
|  | button = toolkit.createButton(sectionClient, "Radio 2", SWT.RADIO); | 
|  | section.setClient(sectionClient);</pre> | 
|  | <p>This time, we used the TWISTIE toggle style, added the | 
|  | description and asked for the title bar to be painted. The view now | 
|  | looks like this:</p> | 
|  |  | 
|  | <p class="center"> <img border="0" height="255" | 
|  | src="images/section.gif" width="305"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 13</b>: An expandable section with a | 
|  | painted title bar and a description</p> | 
|  |  | 
|  | <h3>Image hyperlink</h3> | 
|  |  | 
|  | <p>Image hyperlink is a subclass of <code>Hyperlink</code> that | 
|  | adds an image before the link text. This combination is so common | 
|  | that it just made a lot of sense to make one control out of it and | 
|  | save on widgets. The control can be used as an image link only | 
|  | (when no text is set), or as a combination of link and image. | 
|  | Images for normal, hover and active (selected) state can be set.</p> | 
|  |  | 
|  | <p>The following is an example of a rich user experience that uses | 
|  | image hyperlinks:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="430" | 
|  | src="images/intro.gif" width="616"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 14</b>: A form taken from one of the | 
|  | Eclipse Welcome pages (this is a fallback presentation used for the | 
|  | cases when embedded browser creation fails)</p> | 
|  |  | 
|  | <h3>Form text control</h3> | 
|  |  | 
|  | <p>Using the combination of labels, hyperlinks, images and | 
|  | <code>TableWrapLayout</code>, it is possible to create complex and | 
|  | powerful forms. However, there are some things that are hard to do. | 
|  | Consider the following example from the PDE manifest editor:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="466" | 
|  | src="images/plugin-overview.gif" width="532"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 15</b>: An example of a complex Eclipse | 
|  | form that mixes wrapped text, images and hyperlinks</p> | 
|  |  | 
|  | <p>Notice how images, hyperlinks and text snippets are mixed | 
|  | together. This is very hard using separate label and hyperlink | 
|  | widgets. To remedy the problem, Eclipse Forms plug-in provides a | 
|  | very rudimentary text control that can do the following:</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li> | 
|  | Render plain wrapped text | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  | Render plain text but convert any segment that starts with | 
|  | <b>http://</b> into a hyperlink on the fly | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  | Render text with HTML-like tags (the form used in Figure 15 | 
|  | is using form text widgets in this mode) | 
|  | </li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <p>In all the modes, form text control is capable of rendering | 
|  | either a string or an input stream.</p> | 
|  |  | 
|  | <h4>Rendering normal text (label mode)</h4> | 
|  |  | 
|  | <div> | 
|  |  | 
|  | <pre> FormText formText = toolkit.createFormText(form.getBody(), true); | 
|  | td = new TableWrapData(TableWrapData.FILL); | 
|  | td.colspan = 2; | 
|  | formText.setLayoutData(td); | 
|  | String text = "Here is some plain text for the text to render."; | 
|  | formText.setText(text, false, false);</pre> | 
|  | </div> | 
|  |  | 
|  | <div> | 
|  |  | 
|  | <p>Second argument set to <code>false</code> means that we will | 
|  | not bother to parse the tags, and the third that we will not try | 
|  | to expand URLs if found.</p> | 
|  |  | 
|  | </div> | 
|  |  | 
|  | <h4>Automatic conversion of URLs into hyperlinks</h4> | 
|  |  | 
|  | <p>Now we will add a hyperlink to the text and turn the third | 
|  | argument into <code>true</code>:</p> | 
|  |  | 
|  | <pre> FormText formText = toolkit.createFormText(form.getBody(), true); | 
|  | td = new TableWrapData(TableWrapData.FILL); | 
|  | td.colspan = 2; | 
|  | formText .setLayoutData(td); | 
|  | String text = "Here is some plain text for the text to render; "+ | 
|  | this text is at http://www.eclipse.org web site."; | 
|  | formText .setText(text, false, <b>true</b>);</pre> | 
|  | <p>When we look at our view, it now looks like this:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="287" | 
|  | src="images/form-text1.gif" width="305"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 16</b>: Form text control with a URL | 
|  | automatically converted into a hyperlink</p> | 
|  |  | 
|  | <p>The URL has been converted into a link. The link is part of the | 
|  | wrapped text - we did not have to create a separate | 
|  | <code>Hyperlink</code> control and try to sandwich it between the | 
|  | two labels.</p> | 
|  |  | 
|  | <p>Since form text control can render hyperlinks, it accepts the | 
|  | same hyperlink listeners we used before. When created by the | 
|  | toolkit, the form text will use the hyperlink settings from the | 
|  | hyperlink group that belongs to the toolkit.</p> | 
|  |  | 
|  | <h4>Parsing formatting markup</h4> | 
|  |  | 
|  | <p>The most powerful use of the form text control is when | 
|  | formatting tags are added to the text. The expected root tag is | 
|  | 'form'. It can have one or more children that can either | 
|  | be <p> or <li>. Either of these can have normal text, | 
|  | text between <b> or <span> tags, images and links. | 
|  | Images are declared using <img href="<i>image | 
|  | key</i>"/> (no content), while links are expressed using | 
|  | <a href="<i>href</i>">text</a>.</p> | 
|  |  | 
|  | <p>Some of the tags mentioned above have additional attributes. Tag | 
|  | <a> can accept nowrap='true' to block | 
|  | the link from being wrapped into the new line. Tag <p> can | 
|  | have attribute vspace='false' (true by | 
|  | default) that adds additional space between paragraphs when set to | 
|  | 'true'. Tag <li> has more attributes:</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | <b>style</b> - can be "text", "bullet" | 
|  | and "image" (default is "bullet") | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  | <b>value</b> - not used for "bullet"; if style is | 
|  | "text", the value will be rendered instead in place | 
|  | of a bullet; if style is "image", value represents a | 
|  | key in the image table of an image to be rendered in place of a | 
|  | bullet | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  | <b>vspace</b> - the same as for the 'p' tag. | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  | <b>indent</b> - the number of pixels to indent text | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  | <b>bindent</b> - the number of pixels to indent the bullet | 
|  | (this number is independent from 'indent' - be | 
|  | careful not to overlap them) | 
|  | </li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <p>Tags that affect appearance of the normal text are <b> | 
|  | (works as expected), and <span>. The latter allows you to | 
|  | change font and/or color of the text within the tag. Finally, soft | 
|  | line breaks can be added using <br/> tag.</p> | 
|  |  | 
|  | <p><img border="0" height="13" src="images/tip.gif" width="62"/> | 
|  | Since Eclipse 3.1, it is possible to place an SWT control that is a | 
|  | child of the form text in the markup. The new element | 
|  | 'control' accepts attribute 'href' that is a | 
|  | key to the Control object set using | 
|  | <code>FormText.setControl(String key, Control control)</code>. | 
|  | Optionally, attribute "fill" can be set to | 
|  | <code>true</code> to make the control fill the entire width of the | 
|  | text. Form text is not responsible for creating or disposing | 
|  | controls, it only places them relative to the surrounding text. | 
|  | Similar to <img>, vertical position of the control relative | 
|  | to the surrounding text can be set using the 'align' | 
|  | attribute.</p> | 
|  |  | 
|  | <p>How does all this work in practice? Let's make data text | 
|  | that will use all of these tags together:</p> | 
|  |  | 
|  | <pre> StringBuffer buf = new StringBuffer(); | 
|  | buf.append("<form>"); | 
|  | buf.append("<p>"); | 
|  | buf.append("Here is some plain text for the text to render; "); | 
|  | buf.append("this text is at <a href=\"http://www.eclipse.org\" "+ | 
|  | "nowrap=\"true\">http://www.eclipse.org</a> web site."); | 
|  | buf.append("</p>"); | 
|  | buf.append("<p>"); | 
|  | buf.append("<span color=\"header\" font=\"header\">"+ | 
|  | "This text is in header font and color.</span>"); | 
|  | buf.append("</p>"); | 
|  | buf.append("<p>This line will contain some <b>bold</b> and "+ | 
|  | "some <span font=\"code\">source</span> text. "); | 
|  | buf.append("We can also add <img href=\"image\"/> an image. "); | 
|  | buf.append("</p>"); | 
|  | buf.append("<li>A default (bulleted) list item.</li>"); | 
|  | buf.append("<li>Another bullet list item.</li>"); | 
|  | buf.append("<li style=\"text\" value=\"1.\">A list item with text.</li>"); | 
|  | buf.append("<li style=\"text\" value=\"2.\">Another list "+ | 
|  | item with text</li>"); | 
|  | buf.append("<li style=\"image\" value=\"image\">List item with "+ | 
|  | "an image bullet</li>"); | 
|  | buf.append("<li style=\"text\" bindent=\"20\" indent=\"40\" value=\"3.\">"+ | 
|  | "A list item with text.</li>"); | 
|  | buf.append("<li style=\"text\" bindent=\"20\" indent=\"40\" value=\"4.\">"+ | 
|  | "A list item with text.</li>"); | 
|  | buf.append("<p>     leading blanks;      more white \n\n new "+ | 
|  | "lines   <br/>  \n   more <b>   bb   </b>  white  . </p>"); | 
|  | buf.append("</form>"); | 
|  | FormText formText = toolkit.createFormText(form.getBody(), true); | 
|  | formText.setWhitespaceNormalized(true); | 
|  | td = new TableWrapData(TableWrapData.FILL); | 
|  | td.colspan = 2; | 
|  | formText.setLayoutData(td); | 
|  | formText.setImage("image", FormArticlePlugin.getDefault(). | 
|  | getImageRegistry().get(FormArticlePlugin.IMG_SAMPLE)); | 
|  | formText.setColor("header", toolkit.getColors(). | 
|  | getColor(FormColors.TITLE)); | 
|  | formText.setFont("header", JFaceResources.getHeaderFont()); | 
|  | formText.setFont("code", JFaceResources.getTextFont()); | 
|  | formText.setText(buf.toString(), true, false); | 
|  | formText.addHyperlinkListener(new HyperlinkAdapter() { | 
|  | public void linkActivated(HyperlinkEvent e) { | 
|  | System.out.println("Link active: "+e.getHref()); | 
|  | } | 
|  | });</pre> | 
|  | <p>One common theme that can be observed is that the widget itself | 
|  | is not responsible for loading images, fonts, resolving links or | 
|  | colors. This is not a browser and it is much better to separate | 
|  | concerns and simply assign images and colors managed elsewhere. | 
|  | Both links and images simply have 'href' attribute to | 
|  | reference them. For links, the value of this attribute will be | 
|  | provided in the hyperlink event when listeners are notified. Images | 
|  | need to be registered with the text control using the matching | 
|  | 'href' key. This way, the control does not need to worry | 
|  | about loading the images - it has them in the hash table and can | 
|  | render them immediately.</p> | 
|  |  | 
|  | <p>A similar approach has been used for colors and fonts. Colors | 
|  | are already handled by the toolkit, so you can allocate as many as | 
|  | you want using a unique key and RGB values by calling | 
|  | <code>toolkit.getColors().createColor(String key, RGB rgb)</code>. | 
|  | What is left is to set all the colors referenced in the | 
|  | 'span' tag so that the control will be able to use them | 
|  | during rendering.</p> | 
|  |  | 
|  | <p>When the code above is executed, the view looks like this:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="545" | 
|  | src="images/form-text2.gif" width="308"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 17</b>: Form text rendered from the XML | 
|  | markup</p> | 
|  |  | 
|  | <p>If we expand the section and the expandable composite, and make | 
|  | the window narrower, the form still holds and everything wraps | 
|  | perfectly:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="651" | 
|  | src="images/form-text3.gif" width="236"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 18</b>: The sample view made taller and | 
|  | narrower</p> | 
|  |  | 
|  | <h2>Appropriate usage and limitations</h2> | 
|  |  | 
|  | <p>Although the image above is very promising, it is very important | 
|  | to contain excitement. A 'prime directive' of the form | 
|  | text control is:</p> | 
|  |  | 
|  | <blockquote> | 
|  |  | 
|  | <p><b>"Form text control is not, nor will it ever be, a web | 
|  | browser"</b></p> | 
|  |  | 
|  | </blockquote> | 
|  |  | 
|  | <p>It is very easy to spot limitations of the control. Tags within | 
|  | list items or paragraphs cannot be nested. Bold is supported, but | 
|  | not italic (although any font can be set and associated via the | 
|  | 'span' tag). Attributes for vertical alignment of text | 
|  | with respect to images are missing. List support is decidedly low | 
|  | level. There is no BIDI support.</p> | 
|  |  | 
|  | <p>Another important limitation to consider is performance. Form | 
|  | text is neither a performance nor memory hog, but it was written to | 
|  | be small and lean, not powerful. For that reason, it does not have | 
|  | sophisticated painting routines, dirty region management etc. These | 
|  | routines are cost-effective when the control owns the entire window | 
|  | and must be scalable. In contrast, form text is best suited for | 
|  | short snippets of tagged text that are mixed with other controls on | 
|  | a form. This way, the control is one of several children in the | 
|  | parent, allowing native dirty region management from the OS to | 
|  | handle repaints. The best results in Eclipse forms are achieved | 
|  | with a mixture that is similar to our example above.</p> | 
|  |  | 
|  | <p><img border="0" height="13" src="images/tip.gif" width="62"/> | 
|  | Performance and painting of the form text widget has been improved | 
|  | in Eclipse 3.1 and it can now handle more content without | 
|  | performance degradation. For example, the new Help view is using | 
|  | form text widget for rendering hundreds of images and search hits. | 
|  | Nevertheless, the usage guidelines outline above still stand.</p> | 
|  |  | 
|  | <p>If you have a problem with the form text limitations, you should | 
|  | consider alternatives:</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li>If you need editing capability and text styling (with | 
|  | different fonts and colors), use <code>StyledText</code> (used by | 
|  | styled text editors like Java editor in Eclipse)</li> | 
|  |  | 
|  | <li>If you only need read-only support but have complex text | 
|  | formatting needs, use | 
|  | <code>org.eclipse.swt.browser.Browser</code>. Embedded web | 
|  | browser works on most platforms and will give you full HTML | 
|  | support.</li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <p>What this widget is for is to provide for modest text formatting | 
|  | in combination with <code>TableWrapLayout</code> and other controls | 
|  | in a form. The power lies in the fact that you have full access to | 
|  | every control - a kind of direct access that you can only achieve | 
|  | in a browser if you use proprietary DOM access mechanisms. In | 
|  | contrast, Eclipse Forms are portable - they run everywhere SWT | 
|  | runs.</p> | 
|  |  | 
|  | <p>To conclude, use the form text widget:</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li>when the UI you want to render is not very long with many | 
|  | lines of text, hyperlinks and many images in complex layouts (use | 
|  | embedded browser for that)</li> | 
|  |  | 
|  | <li>when you want to mix text, hyperlinks and images with SWT | 
|  | controls like trees, tables and buttons.</li> | 
|  |  | 
|  | <li>when you want to run everywhere SWT runs</li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <p>In contrast, use embedded web browser:</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | when the UI you want to render contains many lines of text, | 
|  | hyperlinks and images arranged in complex layouts | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | when you do not need to mix SWT controls like trees and | 
|  | tables with the text | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | when you want to use complex web technologies like | 
|  | animation, sound or servlets/JSPs and/or render external web | 
|  | pages in-place | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | when you want to achieve complex rendering effects like | 
|  | transparency (all SWT widgets are opaque) | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | when you only need to ship on OS and/or window system | 
|  | combinations where the embedded browser is fully supported | 
|  |  | 
|  | </li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <h2>Advanced Topics</h2> | 
|  |  | 
|  | <p>As usual in the real-world development, there is a chasm between | 
|  | simple, happy examples that get you started and real code shipped | 
|  | in products. This section covers aspects of Eclipse Forms that are | 
|  | employed in production Eclipse code. You do not need to use | 
|  | them right away, but chances are you will recognize their | 
|  | advantages as your plug-in grows in complexity. In the following | 
|  | text, we will address color and toolkit management, managed forms, | 
|  | master/details block and multi-page editors.</p> | 
|  |  | 
|  | <h3>Color And Toolkit Management</h3> | 
|  |  | 
|  | <p>When using forms in a non-trivial way, it is important to share | 
|  | as much as possible to conserve resources. For this reason, color | 
|  | management should be separated from the toolkit when there is more | 
|  | than one form to handle.</p> | 
|  |  | 
|  | <p>Of course, it is possible to create one toolkit per form, but | 
|  | that is too wasteful if there are many forms. Instead:</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | Create one toolkit for all the forms that have the same life | 
|  | cycle. For example, if creating a multi-page editor, create one | 
|  | toolkit per editor and dispose it when editor is disposed. All | 
|  | the pages in the editor should share this toolkit. | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | Create one color manager (<code>FormColors</code>) per | 
|  | plug-in. When creating the toolkit, pass the color manager to | 
|  | the toolkit. The toolkit will know that the colors are shared | 
|  | and will not dispose them. | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | Use platform support for fonts and if possible, use | 
|  | <code>JFaceResources</code> predefined fonts. Between default, | 
|  | 'banner' and 'header' fonts, you can | 
|  | accomplish a lot. Using many fonts is very confusing for the | 
|  | user, and if you do manage your own, you must ensure | 
|  | alternatives across platforms. The JFace fonts are guaranteed | 
|  | to work on all the platforms Eclipse ships on. | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | Dispose the color manager on plug-in shutdown (do not | 
|  | assume that plug-in shutdown also means platform shutdown - in | 
|  | Eclipse 3.x OSGi can uninstall your plug-in dynamically with | 
|  | the platform still running). | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | Use form color manager to allocate all the colors needed by | 
|  | the forms. | 
|  |  | 
|  | </li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <h3>Managed forms</h3> | 
|  |  | 
|  | <p>Managed forms are wrappers that add life cycle management and | 
|  | notification to form members. A managed form is not a form by | 
|  | itself. It <i>has</i> a form and accepts registration of | 
|  | <code>IFormPart</code> element. For each <code>IFormPart</code>, it | 
|  | manages events like dirty state, saving, commit, focus, selection | 
|  | changes etc. In order to reach to the wrapped form widget, call the | 
|  | '<code>getfForm()'</code> method.</p> | 
|  |  | 
|  | <p>Not every control on the form needs to be a form part. It is | 
|  | better to group a number of controls and implement | 
|  | <code>IFormPart</code> interface for the group. Section is a | 
|  | natural group and Eclipse Form provides <code>SectionPart</code> | 
|  | implementation. It implements the interface and contains a | 
|  | <code>Section</code> instance (either created outside and passed | 
|  | into the constructor, or created in the part itself).</p> | 
|  |  | 
|  | <h3>Master/Details block</h3> | 
|  |  | 
|  | <p>'Master/Details' is a pattern used throughout the UI world. It | 
|  | consists of a list or a tree ('master') and a set of | 
|  | properties ('details') driven by the selection in the | 
|  | master. Eclipse Forms provide the implementation of the pattern as | 
|  | a useful building block with the following properties:</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | While 'details' part is managed by the class | 
|  | itself, the master part factory method is abstract and must be | 
|  | implemented by the subclass | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | Master and details parts are children of a sash form and the | 
|  | ratio of the form space allocated for each can be changed by | 
|  | moving the sash. | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | As usual with a sash form, master and details parts can be | 
|  | organized horizontally or vertically in the form. | 
|  |  | 
|  | </li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <p>The idea of master/details block is to create a tree or a table | 
|  | section that fires the selection notification via the managed form. | 
|  | If the details part can handle the selected object, it should | 
|  | switch to the page for it and display properties. When building on | 
|  | top of the provided master/details block, subclasses should:</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | Create the master part (the one that drives the details) | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | Contribute actions to the form tool bar (consumes | 
|  | upper-right portion of the form in the title area) | 
|  |  | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  |  | 
|  | Register details pages, one for each distinct input that can | 
|  | arrive from the master part | 
|  |  | 
|  | </li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <p>We will show how this looks in practice using the source code | 
|  | that accompanies this article. It creates a table for the master | 
|  | part and hooks a few dummy objects of two distinct types. Two | 
|  | details pages are registered to handle selections of these types. | 
|  | Pages can contain any number of controls - they are created on | 
|  | demand in the provided parent. The details area scrolls separately | 
|  | from the master area.</p> | 
|  |  | 
|  | <p>This part can now be used anywhere, but in this example it was | 
|  | placed inside an editor. Two distinct object types were used | 
|  | (<code>TypeOne</code> and <code>TypeTwo</code>), and their classes | 
|  | were used directly as keys (other mapping between details pages and | 
|  | objects are possible). Details pages registered with the Details | 
|  | part need to implement <code>IDetailsPage</code> interface.</p> | 
|  |  | 
|  | <p>The page is first initialized with the managed form to get | 
|  | access to the toolkit and other objects. It is then asked to create | 
|  | contents in the provided parent. It should also set focus on the | 
|  | first control when asked, be able to refresh, commit, dispose and | 
|  | react to the input changes. As long as objects selected in the | 
|  | master part are of a compatible type, the page will stay visible | 
|  | and <code>inputChanged</code> will be called.</p> | 
|  |  | 
|  | <p>Let's see how all this looks in practice:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="402" | 
|  | src="images/master-details1.gif" width="604"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 19</b>: An example of a master/details | 
|  | block in horizontal orientation hosted in an editor</p> | 
|  |  | 
|  | <p>An instance of <code>TypeOne</code> object is selected in the | 
|  | master part. The appropriate page for the type is loaded in the | 
|  | details part. The page can contain any number of controls | 
|  | introduced elsewhere in this article. The ratio of parts on the | 
|  | page can be changed by scrolling the sash (visible when mouse goes | 
|  | over the area between the parts). Also note two actions in the | 
|  | upper-right corner of the form - this is the form tool bar. In this | 
|  | case, two radio buttons were contributed to control orientation of | 
|  | the part (horizontal or vertical).</p> | 
|  |  | 
|  | <p>If we change the orientation and select one of the | 
|  | <code>TypeTwo</code> instances, we get into this state:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="403" | 
|  | src="images/master-details2.gif" width="604"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 20:</b> The same block in vertical | 
|  | orientation and with a different element type selected</p> | 
|  |  | 
|  | <p>Orientation is now vertical, and a different details page is | 
|  | shown for the type.</p> | 
|  |  | 
|  | <p>It is possible to register a detail page provider instead of | 
|  | registering pages up front. This allows dynamic resolution of the | 
|  | details page for the selected object. It is particularly important | 
|  | for cases when different pages are needed for objects of the same | 
|  | type depending on their states.</p> | 
|  |  | 
|  | <h3>Multi-page form editors</h3> | 
|  |  | 
|  | <p>It was a long way to get to this topic, yet PDE multi-page | 
|  | editors were the first to spark interest in Eclipse Forms. Today, | 
|  | multi-page editors still represent the most common use case of the | 
|  | technology, even though it now starts to appear in other places.</p> | 
|  |  | 
|  | <p>Eclipse Forms are designed to work in a variety of | 
|  | settings. For this reason, the plug-in cannot make assumptions on | 
|  | the types of editor inputs your editor can receive. A number of | 
|  | concepts employed in PDE UI cannot be used here because without | 
|  | knowing about the editor input in more detail, it is hard to | 
|  | provide a set of reusable classes. Nevertheless, Eclipse Forms | 
|  | provide the basic support for multi-page editors, which you can | 
|  | build on.</p> | 
|  |  | 
|  | <p>You should start building an Eclipse Forms multi-page editor by | 
|  | extending <code>FormEditor</code>:</p> | 
|  |  | 
|  | <blockquote> | 
|  |  | 
|  | <pre>public class SimpleFormEditor extends FormEditor { | 
|  |  | 
|  | public SimpleFormEditor() { | 
|  | } | 
|  |  | 
|  | protected FormToolkit createToolkit(Display display) { | 
|  | // Create a toolkit that shares colors between editors. | 
|  | return new FormToolkit(ExamplesPlugin.getDefault(). | 
|  | getFormColors(display)); | 
|  | } | 
|  |  | 
|  | protected void addPages() { | 
|  | try { | 
|  | addPage(new FreeFormPage(this)); | 
|  | addPage(new SecondPage(this)); | 
|  | addPage(new ThirdPage(this)); | 
|  | addPage(new MasterDetailsPage(this)); | 
|  | addPage(new PageWithSubPages(this)); | 
|  | } | 
|  | catch (PartInitException e) { | 
|  | // | 
|  | } | 
|  | } | 
|  |  | 
|  | public void doSave(IProgressMonitor monitor) { | 
|  | } | 
|  |  | 
|  | public void doSaveAs() { | 
|  | } | 
|  |  | 
|  | public boolean isSaveAsAllowed() { | 
|  | return false; | 
|  | }</pre> | 
|  | </blockquote> | 
|  |  | 
|  | <p>A very simple way to get started is to create pages and add them | 
|  | as above. Each page needs to implement <code>FormPage</code> and | 
|  | override <code>createFormContent(IManagedForm managedForm)</code>. | 
|  | Since there is already a managed form in each page, | 
|  | you should create contents in that enclosed form and register | 
|  | any form part that needs to be part of the managed life cycle.</p> | 
|  |  | 
|  | <p>In addition to form pages, you can add one or more text editors | 
|  | as a raw source alternative to the GUI pages. For this, you should | 
|  | call <code>addPage(IEditorPart, IEditorInput | 
|  | input)</code> method in the super class.</p> | 
|  |  | 
|  | <h3>Multi-page editor example</h3> | 
|  |  | 
|  | <p>The source code that comes with this article contains an example | 
|  | of a multi-page editor suitable for inclusion in an RCP application | 
|  | because it does not have any dependencies on IDE plug-ins.</p> | 
|  |  | 
|  | <p>Once you launch another Eclipse application, customize the | 
|  | perspective by checking the following checkbox in the test Eclipse | 
|  | window:</p> | 
|  |  | 
|  | <p>Window>Customize Perspective...>Commands>Eclipse Forms | 
|  | Article</p> | 
|  |  | 
|  | <p>This will add a menu to the menu bar called 'Form Article | 
|  | Editors'. The menu contains only one action - 'Simple | 
|  | Form Editor'. The action will open the editor. It has the | 
|  | following pages:</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="401" | 
|  | src="images/editor1.gif" width="604"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 21</b>: A multi-page editor page with a | 
|  | free-flowing text</p> | 
|  |  | 
|  | <p>The first page contains a page with a <code>TableWrapLayout</code> | 
|  | and some sample content including a <code>FormText</code> widget. The | 
|  | page content is free-form and will wrap and flow top to | 
|  | bottom.</p> | 
|  |  | 
|  | <p>In contrast, the second page contains 'stretchy' controls -- two | 
|  | table viewers -- that consume all the excess space on the page. Since | 
|  | the controls can scroll themselves, a | 
|  | <code>GridLayout</code> is used. Several PDE editor pages follow this pattern.</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="403" | 
|  | src="images/editor2.gif" width="603"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 22</b>: A multi-page editor page with | 
|  | sections and tables.</p> | 
|  |  | 
|  | <p>The third page (Flow Page) was shown before in the | 
|  | <code>ColumnLayout</code> section. It demonstrates how to | 
|  | use this layout to adjust to the available space. | 
|  | Master/Details sections are also shown above.</p> | 
|  |  | 
|  | <p>The last page shows how to embed a<code>CTabFolder</code> in | 
|  | order to add another dimension to a form. In this particular example, the | 
|  | actual content is not switched -- there is only one text control -- | 
|  | but its content is loaded from different objects depending on the | 
|  | selected tab.</p> | 
|  |  | 
|  | <p class="center"><img border="0" height="404" | 
|  | src="images/subpages.gif" width="606"/></p> | 
|  |  | 
|  | <p class="center"><b>Figure 23:</b> A multi-page editor page with | 
|  | nested tabs</p> | 
|  |  | 
|  | <h4>Recommended practices for Eclipse Forms multi-page editors</h4> | 
|  |  | 
|  | <p>There are many ways to write a form-based | 
|  | multi-page editor. It depends on the type of content you are | 
|  | editing and the proficiency of your users. You can approach it in two ways: | 
|  | </p> | 
|  |  | 
|  | <ol> | 
|  |  | 
|  | <li> | 
|  | If the typical users are using the editor infrequently, if raw | 
|  | source is hard to edit by hand or complex, if your users are not | 
|  | very technical, you should make COMPLETE pages capable of editing every aspect of the content without | 
|  | the need to turn to the raw source. In this approach, a source editor | 
|  | page is there only for occasional validation, rather than for | 
|  | regular work. In that case, you can get away with a basic | 
|  | text editor. The PDE extension point schema editor falls into | 
|  | this group. | 
|  | </li> | 
|  |  | 
|  | <li> | 
|  | If your users are more technical, if they have no problem editing | 
|  | the file by hand but would appreciate some help from time to | 
|  | time, then consider providing a mixed experience -- make a good | 
|  | source editor with all the add-ons like incremental outline, | 
|  | context assist, syntax highlighting etc. Then, add complex | 
|  | value-added functionality in form pages for actions that are hard to | 
|  | achieve when editing raw source. We have learned from experience that it is | 
|  | very hard to convince seasoned users to switch from source | 
|  | editing if the value added is marginal or debatable. However, | 
|  | when a function is only available in GUI pages and provides value and usability, it is adopted readily. | 
|  | </li> | 
|  |  | 
|  | </ol> | 
|  |  | 
|  | <p>Creating a quality multi-page editor with mixed GUI and | 
|  | source pages has its challenges. Accepting that users will switch | 
|  | pages frequently requires a good model of the underlying content. | 
|  | The model should be directly tied to the underlying document(s) to stay | 
|  | in sync  when users edit the raw text directly and | 
|  | when they change it structurally through the forms pages. Also, do not | 
|  | forget indirect changes caused by other workbench actions while | 
|  | the editor is open.</p> | 
|  |  | 
|  | <p>For ideas on how to do this, see the source code of PDE editors | 
|  | (org.eclipse.pde.ui plug-in) from the Eclipse <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.pde.ui/">CVS repository</a>.</p> | 
|  |  | 
|  | <h2>Conclusion</h2> | 
|  |  | 
|  | <p>The goal of this article was to introduce you to a great way | 
|  | to create powerful user interfaces in Eclipse 3.x. Eclipse Forms | 
|  | is neither a competing widget toolkit that you need to choose over | 
|  | SWT, nor does it make the embedded HTML browser widget obsolete. | 
|  | Instead, it is a carefully written extension of SWT that allows you | 
|  | to create surprisingly rich user interfaces in Eclipse while | 
|  | retaining the portability of SWT. In simple cases, it can also be a | 
|  | lightweight alternative to the SWT embedded browser widget. When | 
|  | used within its limitations, Eclipse Forms can spice up your | 
|  | applications and allow you to introduce a familiar Web-like metaphor.</p> | 
|  |  | 
|  | <h2>Source Code</h2> | 
|  |  | 
|  | <p>To run the example or view the source code for this article, go | 
|  | through the following steps:</p> | 
|  |  | 
|  | <ol> | 
|  |  | 
|  | <li>Unzip <a href="formsArticle.zip">formsArticle.zip</a> into | 
|  | your workspace location in the file system.</li> | 
|  |  | 
|  | <li>Import the extracted project (org.eclipse.ui.forms.article) | 
|  | into your workspace using 'File>Import>Existing | 
|  | Project into Workspace'</li> | 
|  |  | 
|  | <li>Browse the source code (under 'src' directory).</li> | 
|  |  | 
|  | <li>When ready, launch another Eclipse using 'Run>Run | 
|  | As>Eclipse Application'</li> | 
|  |  | 
|  | <li>To browse the sample view, use 'Window>Show | 
|  | View>Other...>Eclipse Forms Article Examples>Eclipse | 
|  | Form'</li> | 
|  |  | 
|  | <li>To browse the multi-page editor, check the | 
|  | 'Window>Customize Perspective>Commands>Eclipse | 
|  | Forms Article' checkbox to activate the action set. After | 
|  | that, activate the editor from the newly added 'Form Article | 
|  | Editors' menu.</li> | 
|  | </ol> | 
|  | </body> | 
|  | </html> | 
|  |  |