Custom Wizard Pages

The following properties can be used to define custom pages in the wizard. <i> is an integer page ID (starting with 1); its ordering defines the order of wizard pages.

page.<i>.file
The name of the XSWT file that describes the wizard page layout.
page.<i>.class
In addition to XSWT files, custom Java pages may also be defined in Java code. This can be useful when the wizard page would be too complex to describe with XSWT, when it would need to have significant active behavior, or when the wizard page code already exists in Java form. See below for further discussion about custom pages.
page.<i>.title
Title of the wizard page, displayed in the page’s title area. Defaults to the template name.
page.<i>.description
Description of the wizard page, shown in the dialog’s title area below the title. Defaults to text in the format "Page 1 of 3".
page.<i>.condition
A condition for showing the page. If it evaluates to false, the page will be skipped when it would normally come in the page sequence of the wizard. This makes it possible not only to skip pages, but also to show different pages based on some choice or choices the user made earlier in the wizard (decision tree). The condition will be evaluated by the template engine, so any valid FreeMarker expression that can produce true or "true" as a result will do. The expression must be supplied without the ${ and } marks. The string you enter will be substituted into the "${( <condition> )?string}" string (will replace "<condition>"), and evaluate as such. An example will be provided later.

All property file entries are available as template variables, too. In addition, most property values may refer to other property values or template variables, using the ${name} syntax.

XSWT Forms

An XSWT form is defined in an XML file with the root element <xswt>. Some XSWT specific elements and attributes (import and package declarations, id and class attributes to name a few) are defined in the http://sweet_swt.sf.net/xswt XML namespace (we use the x namespace prefix here).

Controls that can be used in XSWT are instantiated by an element with same name as the control (but starting with lowercase).

Controls and classes used in an XSWT file must be imported before they can be used.

<xswt xmlns:x="http://sweet_swt.sf.net/xswt">
  <x:import>
    <package name="java.lang"/>
    <package name="org.eclipse.swt.widgets" />
    <package name="org.eclipse.swt.custom" />
    <package name="org.eclipse.swt.graphics" />
    <package name="org.eclipse.swt.layout" />
    <package name="org.omnetpp.common.wizard.support" />
    <package name="org.omnetpp.ned.editor.wizards.support" />
    <package name="org.omnetpp.cdt.wizard.support" />
  </x:import>
  <label text="Hello"/>
</xswt>

Entities and attributes in an XSWT file are directly mapped to the corresponding SWT controls and their properties. For example, a <styledText> tag creates an org.eclipse.swt.custom.StyledText control. Similarly, a text attribute causes the setText() method of the control to be called.

<styledText text="Hello world!" />

Alternatively, it is possible to call a public method on the control by embedding a "call" as a child tag and supplying the parameters as p0, p1, etc.:

<styledText>
  <setText x:p0="Hello World"/>
</styledText>

Note

Because of a limitation in XSWT, only methods accepting String parameters can be accessed this way.

Integer constants in controls (public static final int fields) can be used in an XSWT file by appending the Java class name before them:

<gateChooser gateFilter="GateChooser.INOUT|GateChooser.VECTOR"/>

Constants in the SWT class do not need the SWT. prefix. You can write:

<button x:style="RADIO"/>

Children can be added to a compound control inside the <x:children></x:children> tags.

<group text="Hello">
  <x:children>
    <label text="Label 1" />
    <label text="Label 2" />
  </x:children>
</group>

Layout and layout data can also be added as a new tag inside a control element:

<text x:id="numServers" x:style="BORDER">
  <layoutData x:class="GridData" horizontalAlignment="FILL"
              grabExcessHorizontalSpace="true"/>
</text>

Note

Layout is always needed; otherwise, the control will not appear on the page.

Tip

SWT is documented on the Eclipse website. See: http://www.eclipse.org/swt/docs.php for documentation, examples and tutorials.

Binding of Template Variables to Widgets

XSWT allows one to tag widgets with ID attributes. Widget IDs will become the names of template variables with the values being the content of widgets. For example, text widgets (org.eclipse.swt.widgets.Text) provide a string value (Java type "String"), while checkboxes and radio buttons provide a boolean (Java type "Boolean").

XSWT also allows filling up the widgets with default values (e.g. <styledText text="some text"/> ), but this feature should be used with care because the defaults set in XSWT may not make it to the file templates. This occurs because if the user clicks Finish early, the rest of the wizard pages (and their widgets) may not be created at all, so values set in the XSWT will take no effect.

For this reason, defaults should always be set in the property file. To do so, simply use a key with the ID of the widget; those values will be written into the wizard page when the page is created. For example, if you have a text widget with x:id="numNodes" and a checkbox with x:id="generateTraffic", then the following lines

numNodes = 100
generateTraffic = true

will fill in the text widget with "100" and select the checkbox. Widgets that do not have such lines in the property file will be left alone. The property file takes precedence over values specified in the XSWT file.

Compound data structures (arrays, maps, and any combination of them) can be specified in the JSON syntax (http://json.org). They can be iterated over in the templates and can be used as input/output for custom compound widgets. Examples:

apps = ["ftp", "smtp", "news"]
layers = {"datalink":"ieee80211", "network":"ip", "transport":["tcp","udp"]}

Tip

If you get an error about syntax errors in a JSON entry, the http://jsonlint.com website can help you locate the problem.

Conditional Pages

Now that we have covered basic XSWT, we can revisit how one can use page conditions. Consider the following practical example of creating a wizard for wireless networks.

On the first page of the wizard you could have a [] Configure routing checkbox with the ID wantRouting. If this checkbox is selected, you want to display a second page where the user can select a routing protocol, followed by configuration pages determined by the chosen routing protocol.

To achieve this, you would add the following lines to template.properties:

# page with the "wantRouting" checkbox
page.1.title = General
# page with the "protocol" combobox
page.2.title = Choose Routing Protocol
page.3.title = AODV Options
page.4.title = DSDV Options
page.2.condition = wantRouting
page.3.condition = wantRouting && protocol=="AODV"
page.4.condition = wantRouting && protocol=="DSDV"

The .condition keys will make the wizard include only the pages where the condition evaluates to true. Conditions can be arbitrary FreeMarker expressions that evaluate to true (as boolean) or "true" (as string). Conditions are re-evaluated after every page, so you can depend on variables edited on earlier pages.

Conditional Widgets

It is also possible to create controls conditionally. To overcome the limitation that XSWT page descriptions are completely static, XSWT files undergo FreeMarker template processing before giving them to the XSWT engine for instantiation. This template processing occurs right before the page gets displayed, so data entered on previous pages can also be used as input for generating XSWT source. This feature can be useful in making conditional widgets (i.e. using <#if> to make part of the page appear only when a certain option has been activated on earlier pages), to create a previously unknown number of widgets (using a <#list>..</#list> loop), to populate combo boxes, listboxes or other widgets with options, and more.

<!-- Show only if the wizard is run from the New Simulation wizard-->
<#if wizardType=="simulation">
<label text="Description how the wizard works for new simulations."/>
</#if>

If the user navigates in the wizard back and forth several times (using the Next and Back buttons), the contents of wizard pages are always re-created with the current values of template variables just before getting displayed, so they will always be up to date.