-
Create a new static class in the annotation class that implements the interface
ComponentDefinitionCreator
.-
Use your annotation type as generic type.
-
Implement the
create
method. You can use a lambda directly and then reuse the implemention ofnewComponent()
of yourBindingDefinition
.
-
-
In the annotation class, replace
BindingDefinitonComponentDefinition.Creator.Class
with the new implementation ofComponentDefinitionCreator
.
Release Notes
Version 1.4.0
New features and improvements
New aspect annotation: @BindVisible
For the annotation @BindVisible, the VisibleType
is set to DYNAMIC
, determining the visible state from the PMO by invoking a method named is[PropertyName]Visible()
. Using this annotation, it is no longer necessary to specify the visible
property with VisibleType.DYNAMIC
in components, e.g. @UILabel
. The @BindVisible can be used on any PMO, including any PMO classes that implement the ContainerPmo
interface (i.e. TableSections
). Using @BindVisible will overrule the existing visible
property.
New BoundPropertyCreator
: ModelBindingBoundPropertyCreator
The annotation @LinkkiBoundProperty
now has a default value of the type ModelBindingBoundPropertyCreator
. Using this BoundPropertyCreator
it is very simple to create a new @UI-Field Annotation with model binding support. For more information read the corresponding documentation about BoundProperty.
Concept of BindingDefinition
is deprecated
The concept of BindingDefinition
is deprecated as it has already been replaced by new machenisms described in Creating a custom UI element. Therefore, the following classes and interfaces are deprecated and should not be used anymore.
-
org.linkki.core.binding.descriptor.bindingdefinition.BindingDefinition
and all extending classes -
org.linkki.core.binding.descriptor.bindingdefinition.annotation.LinkkiBindingDefinition
-
org.linkki.core.uicreation.BindingDefinitionComponentDefinition
-
org.linkki.core.ui.element.annotation.FieldAspectDefinitionCreator
Migration of custom annotations based on BindingDefinition
At the end of the migration, your custom UI annotation should not use LinkkiBindingDefinition
anymore. In addition, all of the logic in the impelementation of BindingDefinition
should have been moved to other classes so that the class can be removed.
The BindingDefinition
interface consists of the following methods whose content have to be moved to new classes:
- Component creation method
Object newComponent()
-
This method defines how a UI component should be created. To migrate its content:
Table 1. Example Before After ... @LinkkiComponent(BindingDefinitionComponentDefinition.Creator.class) //2 public @interface UIFancy { ... }
... @LinkkiComponent(FancyComponentCreator.class) //2 public @interface UIFancy { ... static class FancyComponentCreator implements ComponentDefinitionCreator<UIFancy> { //1 public LinkkiComponentDefinition create(UIFancy annotation, AnnotatedElement annotatedElement) { return pmo -> { // Creates new component from annotation }; } } }
public class FancyBindingDefinition implements BindingDefinition { private UIFancy annotation; public Object newComponent() { // Creates new component from annotation } ... }
- Model binding methods
String modelObject()
andString modelAttribute()
-
These methods define how the model object and model attribute names should be derived from the annotation. To support model binding without
BindingDefinition
:-
In the annotation class, remove the argument
BindingDefinitionBoundPropertyCreator
-
Annotate the annotation attribute that defines the model object name with
LinkkiBoundProperty.ModelObject
-
Annotate the annotation attribute that defines the model attribute name with
LinkkiBoundProperty.ModelAttribute
Table 2. Example Before After ... @LinkkiBoundProperty(BindingDefinitionBoundPropertyCreator.class) //1 public @interface UIFancy { String modelObject() ... ; String modelAttribute() ... ; ... }
... @LinkkiBoundProperty //1 public @interface UIFancy { @LinkkiBoundProperty.ModelObject //2 String modelObject() ... ; @LinkkiBoundProperty.ModelAttribute //3 String modelAttribute() ... ; ... }
If your annotation doesn’t support model binding, you should use
SimpleMemberNameBoundPropertyCreator
instead. -
- Aspect methods
String label()
,EnabledType enabled()
,VisibleType visible()
,RequiredType required
-
These methods define values that are necessary for the aspects. The aspects that were supported by default are:
-
label
-
enabled
-
visible
-
required
-
value
-
derived read-only (readonly if setter method is missing)
To support these aspects without
BindingDefinition
:-
Create a new implementation of
ApsectDefinitionCreator
-
Use the annotation type as generic type
-
In the create method, create a new
CompositeAspectDefinition
that contains the apsects above (see example below).
-
-
Replace
FieldAspectDefinitionCreator
with the new customAspectDefinitionCreator
Table 3. Example Before After ... @LinkkiAspect(FieldAspectDefinitionCreator.class) //2 public @interface UIFancy { String label() ... ; EnabledType enabled() ... ; VisibleType visible() ... ; RequiredType required() ... ; ... }
... @LinkkiAspect(FancyAspectDefinitionCreator.class) //2 public @interface UIFancy { ... static class FancyAspectDefinitionCreator implements AspectDefinitionCreator<UIFancy> { //1 @Override public LinkkiAspectDefinition create(UIFancy annotation) { EnabledAspectDefinition enabledAspectDefinition = new EnabledAspectDefinition(annotation.enabled()); RequiredAspectDefinition requiredAspectDefinition = new RequiredAspectDefinition( annotation.required(), enabledAspectDefinition); return new CompositeAspectDefinition(new LabelAspectDefinition( annotation.label()), enabledAspectDefinition, requiredAspectDefinition, new VisibleAspectDefinition(annotation.visible()), new DerivedReadOnlyAspectDefinition()); } }
-
Faktor-IPS Property Dispatcher uses the value set information to set field properties in the UI
The IpsPropertyDispatcher
can now derive the required
, visible
and enabled
state of a field based on the value set of its model attribute. This functionality is described in the section about IpsPropertyDispatcher. If the IpsPropertyDispatcher
is already in use, this new feature will automatically come into effect with the new version.
Update all binding contexts in BindingManager
BindingManager
now has a new method updateAll
which updates all BindingContexts
that are managed by the BindingManager
. This is a costly operation that should be used with caution.
Dependencies updated
Dependencies used by linkki have been updated.
Different date format for English locale
The short date format (1/1/21) in DateFormats
has been replaced with a date format displaying the full year and leading zeroes (01/01/2021).
linkki for Vaadin 14
linkki now includes modules using Vaadin version 14 for a first developer preview.
Bugfixes
-
Fixed typo in ReadOnlyBehaviorType#INVISIBLE
-
Fixed log warnings due to depreacted method call in
SidebarLayout
. SidebarLayout.SelectionListener is now serializable, consider adding a serialVersionUID.
-
Fixed tooltip on labels not showing HTML content
-
Fixed an error when entering a year with five or more digits
-
Fixed UIDateField always showing english error message