UI Components

UI Element

Both fields and buttons are "UI elements". The following types are provided:

Table 1. Fields

UILabel

Displaying of text

UITextField

Field for single line text entry

UITextArea

Area for multiline text entry

UIIntegerField, UIDoubleField

Entry field for numbers

UICheckbox

Control for boolean input

UIDateField

Field for date entry with date picker

UICombobox

Dropdown field with predefined options

UIYesNoCombobox

Dropdown field for boolean choices

Table 2. Buttons

UIButton

A button that triggers an action when clicked

The type of a field can be determined dynamically. This mechanism is called dynamic field.

Annotations for fields and buttons must exist on methods in a PMO class. The main difference between fields and buttons is that fields are used for displaying and editing of values and thus are bound to a value via data binding. Therefore annotations for fields must exist on a getter method of a PMO property. Only if domain model binding is used the method can be named differently.

Buttons are not bound to a value, but to an annotated method. It represents an executable action which is called by the button click.

Properties

All UI elements have the following properties in common:

Fields have additional properties that are required for the domain model binding:

position musst be specified. All other properties have default values.
Position

The "position" property defines the order of elements in the UI. The relative size of the value is deciding. Elements with smaller position are added to the a section first.

Gaps in the position numbering are allowed and common, to allow adding new UI elements at a later moment without needing to renumber all elements.
Label

Usually there is a label text for each UI element, that describes the element. The content of the label is defined by this attribute.

If no label should be shown (as opposed to an empty one), noLabel = true can be used.

An exception to this is the button, for which normally no label is displayed. The controlling property is showLabel, set to false by default. The displaying can be forced by setting it to true.

If an independent label is needed, the UI element UILabel can be used.
Enabled

The property enabled controls whether a component is active/editable. The following configuration options are available:

Table 3. EnabledType

ENABLED

the content of the element is modifiable in the UI (default)

DISABLED

the content of the element is not modifiable in the UI

DYNAMIC

whether the content is modifiable is controlled by the return value of the method boolean is<PropertyName>Enabled()

A UILabel doesn’t offer these options and is always ENABLED.
Visible

The property visible controls whether the component is visible. There are the following configuration options:

Table 4. VisibleType

VISIBLE

the UI element is visible (default)

INVISIBLE

the UI element is invisible

DYNAMIC

whether the UI element is visible is controlled by the return value of thte method boolean is<PropertyName>Visible()

Required

The property required visually highlights required fields. The following configuration options are available:

Table 5. RequiredType

REQUIRED

the UI element requires input (a value musst be entered/selected)

REQUIRED_IF_ENABLED

the UI element requires input if it is enabled

NOT_REQUIRED

input in the UI element is optional (default)

DYNAMIC

whether the element requires input is controlled by the return value of the method boolean is<PropertyName>Required()

UILabels und UIButtons do not offer these options and are always NOT_REQUIRED.
Fields marked as required are only visually highlighted. No validation is performed.
ModelObject and -Attribute

A field can be bound to an attribute of an existing model object using <<domain-model-binding, domain model binding. For this the properties modelAttribute and possibly modelObject are required. The function is described in the section names of model attributes.

UILabel

The annotation @UILabel generates an independent UI element displaying string content. In contrast to a deactivated UITextField its text is not framed by an input field. This annotation is equivalent to a com.vaadin.ui.Label.

The annotated method must return a value of String type. The return value defines what is shown as label.

A UILabel also has the additional property label. If a value is set to it the text would appear beside the UILabel.
HTML Content

The content of the label can be styled with HTML if htmlContent=true is specified.

Example HTML Label Content
    @UILabel(position = 5, label = "", htmlContent = true)
    public String getGender() {
        switch (contact.getGender()) {
            case FEMALE:
                return FontAwesome.FEMALE.getHtml();
            case MALE:
                return FontAwesome.MALE.getHtml();

            default:
                return FontAwesome.GENDERLESS.getHtml();
        }

    }
Styles

To style labels the property styleNames can be used to specify a list (actually a String[]) of CSS class names.

UICheckbox

A com.vaadin.ui.CheckBox, bound to a boolean property. Instead of a label on the left side of the UI element, checkboxes usually have a caption on the right. This caption must be set with the property caption. If no caption is desired, an empty String must be set.

The usual label property is still available if any display text is needed on the left side additionally. However, the label has to be manually activated by setting noLabel to false.

When used in a table, the label is used as the column name while the caption is displayed next to the checkbox in the table cell.

UITextField

A com.vaadin.ui.TextField for text entry. The annotation UITextfield has two additional properties:

  • columns: int

  • maxLength: int

The property columns defines the width of the text field. If no positive value is defined, all available space is used.

maxLength defines the maximum number of characters that can be entered or displayed in the field.

UITextArea

The annotation UITextArea corresponds to a com.vaadin.ui.TextArea. It is used for entering or displaying text that has more than one line.UITextArea has all the properties of the annotation UITextfield. In addition, it also has:

  • rows: int

The property rows defines the height of the UITextArea, not how many rows can be entered. Its default value is 1.

UIIntegerField and UIDoubleField

@UIInterfield and @UIDoubleField are text fields for displaying formatted numbers. Like @UITextField these annotations have the property maxLength.

The format can be defined with the property format: String, using the notation from java.text.NumberFormat.

If no format is specified for a UIIntegerField, linkki uses the default Java Integer NumberFormat (java.text.NumberFormat#getIntegerInstance(java.util.Locale)). In the case of UIDoubleField the format #,##0.00## is used by default. This format means that at least one digit is displayed before the decimal separator and two after, plus thousands separator. The documentation for the format definition can be looked up in the class java.text.DecimalFormat.

UIDateField

The annotation @UIDateField generates a date input field and corresponds to (com.vaadin.ui.DateField). It allows specifying a date format using the property dateFormat: String. If not date format is defined the format matching the Locale setting is used. linkki uses "dd.MM.yyyy" by default for german. For other languages DateFormat.SHORT from the JDK is used.

The property can return both java.time.LocalDate and org.joda.time.LocalDate.

UIComboBox

A @UIComboBox allows selection of a value from a list. It has three additional properties:

    @UIComboBox(position = 20,
            label = "Model",
            modelAttribute = Car.PROPERTY_MODEL,
            required = RequiredType.REQUIRED_IF_ENABLED,
            content = AvailableValuesType.DYNAMIC,
            itemCaptionProvider = ToStringCaptionProvider.class)
    public void model() {
        /* model binding */
    }
Content

The attribute content defines which values are available:

Table 6. AvailableValuesType

ENUM_VALUES_INCL_NULL

the values of the combobox correspond to the values of the enum data type of the property, extended by the value null (default)

ENUM_VALUES_EXCL_NULL

the values of the combobox correspond to the values of the enum data type of the property

DYNAMIC

the values of the combobox are defined dynamically through the method Collection<T> get<PropertyName>AvailableValues()

NO_VALUES

this combobox has no selectable values

Width

The property width can be used to define the width of the combobox using CSS syntax (e.g. "25em" or "100%"). The default value is -1px, corresponding to the standard size given by Vaadin.

ItemCaptionProvider

For displaying the individual values in the combobox a org.linkki.core.ui.components.ItemCaptionProvider<T> is used. By default it is a DefaultCaptionProvider that expects a method getName(). Via the property itemCaptionProvider an alternative implementation class can be specified. linkki offers two additional ones:

  • ToStringCaptionProvider: uses the `toString()`method of the elements

  • IdAndNameCaptionProvider: displays name and ID in the format "name [ID]" using the methods getName() and getId().

UIYesNoComboBox

A @UIYesNoComboBox allows selection of a boolean value from a dropdown list like a UIComboBox. The difference is that the values are not a generic enumeration or list but the well known boolean values true and false (and for Boolean, the option null). It has two properties known from the UIComboBox:

UISubsetChooser

For selection of multiple values from a list, linkki offers the @UISubsetChooser. In this UI control elements are selected by moving them from a list on the left to a list on the right. The display of the individual elements is similar to UIComboBox, but with a default of ToStringCaptionProvider. As with UICombobox the width can be defined via the property width.

The content of a SubsetChooser musst be specified with the method Collection<T> get<PropertyName>AvailableValues(). The bound property must be of type Set<T>.

The caption of both columns can be set through the properties leftColumnCaption: String and rightColumnCaption: String.

UICustomField

Other controls can also easily be generated and bound by linkki. For this the annotation @UICustomField is used.

The control class is specified with the property uiControl: Class<? extends Field<?>>. If the control inherits from com.vaadin.ui.AbstractSelect the values can be defined by content: AvailableValuesType like with UIComboBox.

@UICustomField only supports controls with a parameter-less constructor.
UICustomField Example: PasswordField
	@UICustomField(position = 20, label = "Password", required = RequiredType.REQUIRED, modelAttribute = User.PROPERTY_PASSWORD, uiControl = PasswordField.class)
	public void password() {
		// model binding
	}

Dynamic Field

linkki allows for dynamic typing of an input field. In the following example Selbstbehalt should only be freely writable if Autotyp is set to STANDARD. Otherwise the user can only select values from a list:

    @UIDoubleField(position = 30,
            label = "Retention",
            modelAttribute = Car.PROPERTY_RETENTION,
            required = RequiredType.REQUIRED_IF_ENABLED)
    @UIComboBox(position = 30,
            label = "Retention",
            modelAttribute = Car.PROPERTY_RETENTION,
            required = RequiredType.REQUIRED_IF_ENABLED,
            content = AvailableValuesType.DYNAMIC,
            itemCaptionProvider = RetentionCaptionProvider.class)
    public void retention() {
        /* model binding */
    }

    public List<Double> getRetentionAvailableValues() {
        return Arrays.asList(2_000.0, 5_000.0, 10_000.0);
    }

    public Class<?> getRetentionComponentType() {
        return car.getCarType() == CarType.STANDARD ? UIDoubleField.class : UIComboBox.class;
    }

The selectable UI elements are defined via annotations on the method, as is customary. They must, however, fullfill the following requirements, to allow the type to be determined dynamically:

  1. the position in the UI* annotations must match

  2. the label must have the same value

If the position values are identical but the label values differ, an exception is thrown.

Which UI element is displayed for each PMO instance is determined by the method Class<?> get<PropertyName>ComponentType(). It returns the class of the UI*-Annotation for the UI control to be rendered.

Button

The annotation @UIButton is used to mark the method that should be executed with the click on the button.

Buttons are not bound to values. Since buttons therefore have no corresponding PMO property, the name of the annotated method is used to determine the associated methods. The behavior is similar to the domain model binding, although buttons have no property modelAttribute.

    @UIButton(position = 10, showIcon = true, icon = FontAwesome.SAVE, captionType = CaptionType.NONE, shortcutKeyCode = KeyCode.ENTER, enabled = EnabledType.DYNAMIC)
    public void save() {
        saveAction.apply();
    }

    public boolean isSaveEnabled() {
        return canSaveSupplier.getAsBoolean();
    }

    @UIButton(position = 20, captionType = CaptionType.STATIC, caption = "reset", styleNames = BaseTheme.BUTTON_LINK)
    public void reset() {
        resetAction.apply();
    }

Contrary to other UI elements @UIButton doesn’t have the property noLabel, but showLabel instead. The default value is false. Apart from the common properties, buttons have these additional ones:

Caption

The text shown on a button is called a caption. It is not to be confused with a Label, which usually appears besides the control. A button can have both a caption and a label text.

  • captionType: CaptionType

Table 7. CaptionType

STATIC

the caption of the button is read from the attribute caption (default)

NONE

the button has no caption

DYNAMIC

the caption of the button is determined by the return value of the method String get<PropertyName>Caption(). The value of the attribute caption is ignored.

Icon

Apart from captions buttons can be adorned with icons. For this the constants of the Vaadin class FontAwesome are used. For the icon to be displayed the property showIcon must be set true.

Style Names

Depending on the function buttons must be styled differently. A typical example for this is the link button, a button that looks like a link. For this purpose the annotation @UIButton has the property styleNames. The value of this property are the CSS class names that should apply to the button.

Key Bindings

Some buttons shouldn’t be triggered only by mouse click, but also by key combinations. These can be specified with the properties shortcutModifierKeys and shortcutKeyCode. shortcutModifierKeys defines which keys must be pressed and held before the key in the shortcutKeyCode is pressed. For instance, in many applications saving is triggered with the shortcut combination "Ctrl + s". In this case the "Ctrl" key is the modifier and the "s" key is the ShortcutKey.

In both properties individual keys are identified by integer values. The appropriate value for each key can be found in the Vaadin classes ModifierKey and KeyCode.