Since SWT is a common abstraction layer of UI controls of different operating systems, its design is mainly driven by constraints given on these operation systems, not by usability. And it is difficult and might introduce version incompatibilities to derive classes from SWT controls.
Thus all known UI frameworks in Eclipse wrap SWT widgets to enrich their behaviour. So does rcpforms.
The design of the widget wrapper in the different available UI frameworks varies a lot. RCPForms tries to get the best of all worlds:
The widget wrapper component is the mandatory buy-in if you want to use the framework. If you don’t like it, most of the framework is useless (still you can use the ModelAdapter and the TableSupport if you mainly need powerful tables, no validated forms). Thus this layer is specifically careful designed.
Since existing frameworks take different approaches to this Widget Wrapper layer, a comparison is done in the following section.
Widget Wrappers all start with RCP... and usually one wrapper wraps one specific SWT control, e.g. RCPSimpleTable wraps a Table control, RCPSimpleCombo wraps a CCombo control. Since grouping a label and a control is an extremely common case, for most controls there is a "Simple" form wrapping only the control and a compound form wrapping a label and a control, common base class is RCPLabeledControl<T> where T is the simple control, e.g. RCPText extends RCPLabeledControl<RCPSimpleText>.
All wrappers offer direct access to the swt control via template method getTypedWidget(), but for convenience most controls offer a non-template typed access method getSWT[SwtControlName?] e.g. RCPSimpleText offers getSWTText().
In the constructor you can usually pass a label and an swt style; recommended is to pass only the label or use the SWT.DEFAULT style which lets the widget factory decide which styles to use. For some widgets there are wrapper subclasses to encapsulate often used styles, e.g. there is a RCPRadioButton, RCPCheckbox, RCPPushButton, RCPToggleButton to avoid needing styles for the most commonly used variants of the button.
Wrappers for Controls which maintain more than one value (e.g. Combo, List, Table) automatically create a suitable JFace viewer. It is a fundamental design principle
to use viewers and content/label providers instead of adding/removing stuff from the control directly.
When createUI() is invoked on a wrapper, the swt control is created. All swt control creation is done via an extended FormToolkit (factory), thus all controls are created in a central location if you use wrappers. This guarantees a consistent look of the application.
Widgets can be in different states, e.g. enabled, disabled. RCPForms internally uniformly handles all states using the same mechanisms, but offers some convenience methods for well known states. An enum defines the available states, several custom state placeholders are defined for additional states needed (not yet in V0.7).
Rendering of states is currently done hardcoded, but the design will be in a way that custom renderers can be added in future versions without breaking any interface.
Here is a list of the states and their meaning as well as the default rendering, bold is the term used in the API:
State
Rendering
Description
enabled/disabled
disabled state of swt control + gray background which Formfactory does not render correct.
usually can be edited, but in the current context it is not editable. Different to readonly, in that readonly fields are only for display, not for editing at all. Content cannot be copied since control is not focusable at all
editable/readonly
different only for Combo, Text, Table. Controls without copyable content (buttons, labels) use disabled rendering. Text Fields and Combo: no border, solid line under field, Combo not selectable anymore
field is for display only, can never be edited. Content can be copied since control is focusable.
visible/invisible
visible state of swt control. an invisible widget is excluded from layout, its space is reused. The latter behavior can be changed with the method setKeepSpaceIfInvisible(boolean).
hides a control completely
mandatory
yellow background, ‘*’ decoration
content must be filled before the form is valid.
recommended
yellow background.
content should be filled by user, but is not mandatory.
error/warning
error/warning marker decoration
uses the standard UI Forms IMessageManager interface, widget wrappers still have built-in support for creating decorations explicitly.
custom1,custom2, custom3, custom4
none, can be customized
eserved for application specific state extension, e.g. extremely required fields, change color when value is negative
Widget Wrappers have 3 relevant states:
- created (only wrapper, no swt controls)
- UI created (swt control is created), state transition via createUI()
- destroyed (swt control is destroyed, but widget wrapper still exists), state transition implicitly when swt control is destroyed eg. because parent is destroyed
State manipulation methods may be called at all times.
Value manipulation methods may only be called in UI created state.
Binding is only allowed in UI created state.
All SWT widgets are created using the FormToolkit. Since the standard UI Forms FormToolkit does not offer enough flexibility, it was extended and an additional interface IFormToolkitEx was introduced to define the methods needed by UI forms. By passing a different implementation of the toolkit, you can define a different look, different default font, colors and so on.
If the SWT.DEFAULT style is used, the creation method which only passes a label is called in the RCPFormToolkit. If other styles are used, the creation method passing the style is called. This eases usage and customization of default styles.