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
page.<i>.class
page.<i>.title
page.<i>.description
page.<i>.condition
${
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.
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>
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>
Layout is always needed; otherwise, the control will not appear on the page.
SWT is documented on the Eclipse website. See: http://www.eclipse.org/swt/docs.php for documentation, examples and tutorials.
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"]}
If you get an error about syntax errors in a JSON entry, the http://jsonlint.com website can help you locate the problem.
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.
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.