Preface

Writing User interfaces is a time consuming and repeating task. Most input masks for a model have the same layout which consists of a label, which indicates the editable property and a widget to edit the value of the property.

Most properties use a text field for editing. If the property of any type of number, the input mask might only accept digits. This behaviour has to be added to any text field of property.

Another feature of input masks is the validation of the data. Even simple validation like checking if a value was entered needs additional code, which repeats for every widget which is used.

Kuria provides an automatic way of creating UI widgets based on a given domain model.

The Kuria project is split in three parts:

Using Kuria

1. Maven

Kuria consists of three modules which can be found in our maven repository. At the moment there is only one generator module using SWT.

To use Kuria add the following lines to you pom.xml to add the Topic maps Lab repository:

<repository>
        <id>tmlab</id>
        <url>http://maven.topicmapslab.de/public</url>
</repository>

After that add the Kuria SWTGenerator to you dependencies like:

<dependency>
        <groupId>de.topicmapslab.kuria</groupId>
        <artifactId>kuria-swtgenerator</artifactId>
        <version>1.0.0</version>
        <scope>compile</scope>
</dependency>

The other modules are dependencies of the SWTgenerator and will be added automatically.

SWT is a platform dependent library which needs implementations for a specific platform. To set the platform you develop, the SWT generator project provides profile specific dependencies. The following profiles are supported:

2. Eclipse

It is possible to install Kuria into an eclipse installation. Add the following url into the update manager:

http://kuria.googlecode.com/hg/update/

After installing the feature you can use Kuria in your Eclipse plug-in.

Kuria does not use a FormToolkit. If you want to adapt an InputMask use the following code:

private void adapt(FormToolkit toolkit, Control control) {
        toolkit.adapt(control, true, true);
        if (control instanceof Composite) {
                for (Control c : ((Composite) control).getChildren()) {
                        adapt(toolkit, c);
                }
        }
}

3. Kuria Runtime

The runtime library specifies the classes which are used to bind the widget with the edited model, hence these classes are called bindings.

Bindings have two tasks:

Bindings are generated by implementation of IBindingFactory. The factory generates an instance of IBindungContainer which contains bindings for a set of classes. Some factories, like the AnnotationBindingFactory need some configuration, like the classes to parse.

The following chapters will explain the different bindings and their properties. For every binding an interface and an example implementations for java beans exists.

3.1. General BInginds

ITextBinding

The ITextBinding specifies which value of a method or field will be used when a String representation is needed. THis may be the case for columns in table, nodes in trees or values in comboboxes. If none is specified, the value of toString is uesed.

3.2. Tablebindings

Tablebindings can be found in the package: de.topicmapslab.kuria.runtime.table.

ITableBinding

The ITableBinding interface specifies a container which contains a list of IColumnBinding . The binding also contains the class which is bound.

IColumnBinding

The IColumnBinding interface connects the property of the class with a column of a table. The column binding provides a title of the column, which can be used as column header. It also provides a path to an image, which will be shown left to the value of the property. In addition it provides access to the value of the property.

3.3. Treebindings

Treebindings can be found in the package: de.topicmapslab.kuria.runtime.tree.

ITreeNodeBinding

The ITreeNodeBinding interface indicates that the represented object may be used as node in a tree. The list of IChildrenBinding it provides contains bindings for the children of the node.

IChildrenBinding

The IChildrenBinding interface is used to indicate which properties of an element which may be used as child nodes. Every type of child has to have an ITreeNodeBinding.

3.4. InputMask

For every type of widget exists a corresponding binding. Every binding is inherits from de.topicmapslab.kuria.runtime.IPropertyBinding.

IEditableBinding

The IEditableBinding interface is used to bind a property container, usually a class with the Kuria widget generators. It contains the bindings for every property of the container.

IPropertyBinding

The IPropertyBinding interface provides access to the bound property. In addition it provides a label for the widget and the following flags:

The IPropertyBinding provides methods to access and modify the value of the property for a specific property container.

The following bindings inherit from IPropertyBinding and therefore get its properties.

ICheckBinding

The ICheckBinding interface indicates the use of a check box for the property. Usually these properties have boolean values.

IComboBinding

The ICheckBinding interface is used to set a property based on given choice options. This is commonly used for non primitive types. How the choices are provided is left to the widget implementation.

IDateBinding

The IDateBinding interface is used to specify the use of a widget for Dates. It is used for the data type Date.

IGroupBinding

The IGroupBinding interface is used to embed another InputMask into the current one. This can be used if a property’s type is another property container of the domain model.

IListBinding

The IListBinding interface is used to specify the widget for a collection of attributes. This collection may be shown inside a table or rendered comma separated in a text field. The style is asked with the accessor getListStyle which returns a value of the enumeration ListStyle:

ITextFieldBinding

The ITextFieldBinding interface indicates that the properties value is shown in a text field. It has the following properties:

4. Kuria Annotations

4.1. Introduction

The Kuria annotation module provides a set of Java 5 annotations for domain models. In addition the module contains a binding factory which creates bindings for every class which is annotated. Most of the annotations are similar to the bindings.

4.2. General

@Text

The text annotation indicates that the field or method should be called when a String representation is needed.

public String name(String val);

4.3. Tables

Kuria has two annotations for the table bindings. The first one is @TableElement which is used at types. The binding factory creates a table binding for the type.

The other annotation is @Column. Every property of the annotated type which should be rendered inside a table column must have this annotation. Other properties are ignored.

@Column has the following parameter:

4.4. Tree

To generate a TreeNodeBinding a class must be annotated with @TreeNode. This annotation has the following parameters:

To specify the attributes representing the children, the annotation @Children is used. The annotation may be used on attributes or accessor methods. The properties of this annotation are used to specify a mediator node, which may used to categorize multiple children. The properties are:

If the parameters are not set no mediator node is created.

Note
If a mediator node is needed the text is mandatory, the image optional.

4.5. InputMask

To create an input mask for a model, it is necessary to create an EditableBinding. The AnnotationBindingFactory creates this binding based on the @Editable annotation. If the model has an annotation, for every attribute a default property binding is generated. If an attribute should not be shown in the input mask it must be annotated with @Hidden.

The following annotations provide more configurations:

@TextField

Indicates that a property is modifiable in a text field. Only attributes of primitive data types and String should be annotated with @TextField.

The Parameters are:

@Check

This annotation indicates that a boolean property should be modified using a check box.

The Parameters are:

@Combo

This annotation indicates hat the property is set via a combo box. The combo box must be filled with an array of objects of the property’s type.

The Parameters are:

@Date

The date annotation indicates, that the property should be edited by an calender.

The Parameters are:

@Directory

This annotation indicates that the field is a absolute path to a directory.

The Parameters are:

@File

This annotation indicates that the field is a absolute path to a file.

The Parameters are:

@Group

This annotation is used to embed an input mask for the property. This is used if the type of the property is another complex type. A EditableBinding for the type must exists.

The Parameters are:

@List

This annotation indicates hat the property is set via a list. The list can be a compact one, which means the whole widget is one row in the input mask, or a table with buttons to remove or add new elements. Like @Combo the list provides a createNew parameter which allows the new creation of selections. Is this flag false only a set of selection options provided by the application is selectable.

The Parameters are:

5. SWT Generator

5.1. Introduction

The SWT Generator is used to generate widgets based in the bindings. These widgets are generated with the Standard Widget Toolkit (SWT) and a wrapper library called JFace. Both libraries are part of the Eclipse Project. See http://eclipse.org/swt/ for more information.

To use the generated widgets a parent widget is needed. This could be a Shell, which is the class representing a window or a Composite.

To generate one of the three main widgets instantiate the class WidgetGenerator and call the generation methods.

5.2. Tables

A TableBinding is realized using the class TableViewer. See http://www.jdocs.com/eclipse/3.2/org/eclipse/jface/viewers/TableViewer.html for more information. The table viewer uses the ColumnBinding and generates the needed content providers.

The input of the TableViewer, set with the method setInput must be a Collection of the annotated model class.

To generate a TableViewer call the method generateTable. The method exists with two, three or four parameters:

5.3. Tree

The TreeBinding is used to generate an instance of TreeViewer. Similar to the TableViewer the TreeViewer uses a ContentProvider and a LabelProvider which use the binding information.

The input of the TreeViewer is the root node of the tree.

To generate a TreeViewer call the method generateTree. Again the method exists with two or three parameters: * Composite parent the parent widget, which should be a composite or shell * boolean showRoot indicates if the root node should be visible or not * IContextMenuListener contextMenuListener a listener which generates actions for a context menu for the selected tree nodes.

Note
If you want to set another layout data to the widget you need to set it to the parent of the table widget. This is necessary, because the table is layouted using a TableColumnLayout which needs to be set into a parent of the table.

5.4. InputMask

The class InputMask represents a form for a specific class with an EditableBinding. The InputMask is a container which contains the specific widgets for the bindings. In addition the InputMask validates the input and persist the data into the given model instance.

To generate an input mask for a model type, use the method generateEditable. The method has the following parameters: * Class<?> clazz the class object which binding is used * Composite parent the parent widget, which should be a composite or shell

5.5. Complex Widgets

In addition to the input mask and viewers, Kuria provides some complex widge6ts based on the basic ones. These widgets and their use are explained in the following sections.

5.5.1. Master Detail Widget

The MastetDetailWidget combines a TableViewer for an object with an InputMask. The table is used to display a list of model instances. By selecting one instance the input mask is filled with the instances values. The modification can be canceled or persisted in the widget.

Additionally the widget provides buttons to create new model instances or remove existing ones.

The input of the widget is a list of instances which can be modified.

The MasterDetailsWidget uses its own widget generator, so you just instantiate it. The constructor has the following parameters:

5.6. Listeners used by the generator

Kuria provides a few new listener interfaces, which can be used to react on changes.

5.6.1. IModelListener

Some applications need to persist their model on their own, for instance when using a undo/redo history. Kuria provides a listener interface which is called when model changes happen. The IModelListener uses PerstenzEvent*s which have a flag (*commit) to indicate whether Kuria should persist the new values into the model or not. The latter is should be used if the values are set in another part of the application.

See the javadoc for more information.

5.6.2. IContextMenuListener

An instance of a listener is invoked if a context menu is created for a {@link TableViewer} or {@link TreeViewer}. The listener has one method: createMenu(IMenuManager manager).

The implementation of the should get the selection of the viewer and add the provided actions to the manager.

5.6.3. IInputMaskListener

With the IInputMaskListener it is possible to react on changes in the input mask. The methods are:

5.6.4. IContentProvider

Every input mask may have a selection list or combo box. These widgets need a list of values to choose from, which Kuria cannot know. To set these selectable values, the input masks uses implementations of IContentProvider. Every input masks has one provider, so if more than one field needs provided elements, the provider must choose which elements to return based on the field name and the model instance.

The methods are:

5.6.5. IImageCallback

Kuria tries to load images from the classpath using the path of the binding. It may happen that the image is an external image and Kuria cannot find it. Is this the case the application may register an implementation of this interface and load the image on its own.

A callback implementation can be registered in an instance of WidgetGenerator.

Note
The callback is added to an internal image registry. The image registry is a singleton and every callback must be removed explicitly when it should not be used anymore.

5.6.6. ILabelProvider

Labels for Columns or widgets in input masks will be derived by:

To provide a way of internalization a ILabelProvider implementation can be added to a IBindingContainer. The method getLabel retrieves a String which is the label retrieved by annotation or fieldname and returns either the same string or a translation of the String.

Glossary

Binding

A binding connects the ediablt property of the domain model with the UI element. It provides access to the properties and the configuration for the UI element.

Node

A node is an element of a tree. Every node may have children which are nodes itself. A tree starts with a root node, which is a node without a parent node.

Widget

A widget is visual element in user interfaces. Widgets are e.g. Buttons, Labels and text field .

Changelog

1. Version 1.0.0

1.1. Runtime

1.2. Annotation

1.3. SWT Generator