New & Noteworthy

1.2.2

ID Collision in Table Sections

When creating a table section from a PMO, the HTML elements of the table, as well as the section surrounding it, were both assigned the name of the PMO class as ID. This leads to ID collision. To avoid this, the ID of the table now has the suffix "_table".

1.2.1

Bugfixes

  • Adding the first child to a row in a HierarchicalTable does not create a triangle to open the row

1.2.0

Buttons and Arbitrary UI Elements in Section Headers

Using the annotation @SectionHeader, any UI element can now be added to a section’s header instead of its content area. This should be used instead of a button PMO returned from PresentationModelObject#getEditButtonPmo().

Radio Buttons

Vaadin’s radio button group, previously only used as an example how to create a custom UI element, is now also a part of linkki for Vaadin 8 with the @UIRadioButtons annotation.

SidebarLayout/SidebarSheet

The SidebarLayout got a SelectionListener to get an event when the selected sidebar sheet changes. To identify the selected sidebar sheet for example when the selected sheet is referenced by a URL parameter, the sidebar sheets now have an optional ID. The ID is derived from name if it was not specified explicitly but it is recommended to make it explicit.

The UiUpdateObserver in SidebarSheet is still the recommended way to trigger an update when the sheet gets selected. This way it remains self-contained (the layout does not need to know how to update the sheet). To make the instantiation more flexible, the UiUpdateObserver could now be specified after constructor using a setter.

Bindings are held in WeakReferences

Bindings used to be removed only when explicitly calling BindingContext#removeBindings…​, or in case of tables, when a DetachEvent was received. The downside was that bindings were either not removed properly which led to a potential memory leak, or in case of tables they might get removed but added again when vaadin recycled a component and re-attached a previously detached one. This was causing duplicated listeners.

With linkki 1.2 the BindingContext only holds weak references to Bindings while there is only one hard reference from the Component to the Binding. This allows the GC to effectively clean up any unused Components together with their `Bindings`.

The new method ComponentWrapper#registerBinding(Binding) creates the hard reference from a component to their Binding. The method BindingContext#add(Binding) has therefore been deprecated and replaced with the new signature BindingContext#add(Binding, ComponentWrapper).

The new behavior also has a critical disadvantage: In tables, the binding was removed immediately with the component’s detach event. Accordingly, there was no call of a RowPmo after a row was removed in a table. The weak reference on the other hand may be removed later by the garbage collector. This might be problematic in cases where the RowPmo relies on a model object, which is part of a composition and was removed from the table by removing the model object from its composition. After removing, the model object might have no parent object any more, which causes a NullPointerException in case the parent object is accessed without null checks.

New Widgetset Allows Flexible Date Entry

linkki now includes its own widgetset that offers a more flexible date entry field. You can switch to it with

@Widgetset(LinkkiWidgetset.NAME)

Empty Selection for Empty Combo Box

If the getAllowedValues() method of a dynamic @UiComboBox returns an empty list, an empty selection is now automatically allowed on the resulting Vaadin component, even if null wouldn’t normally be allowed. Otherwise it would not be possible to clear the currently selected value when all previously available values are removed.

ExceptionPropertyDispatcher Throws IllegalStateException if Model Object Is null

If the model object is null and no getter method is provided in the PMO to handle a null model object, the caller previously received an IllegalArgumentException stating "Cannot convert presentation type class …​ to model type void". This message is now improved, because the ExceptionPropertyDispatcher now throws an IllegalStateException instead of returning void when there is no model object, so that the resulting error is easier to track.

Incubator Project & Nested PMOs

The new incubator module offers access to features in development, such as nested PMOs.

APT Exception Handling for Aspect Definitions

Exceptions thrown when APT calls the createAspect method of aspect definition no longer abort the build. Instead, an ASPECT_CREATION_FAILED warning is now emitted.

Update Vaadin to 8.10.4

linkki now uses Vaadin version 8.10.4 to include the latest bug fixes and patches.

Bugfixes

  • Error markers in table cells are now kept when switching tabs

  • Selection of SidebarSheet showed old content before updating it

  • Datepicker in tables was too wide for the cell