Class BinderCustomField<T>
- Type Parameters:
T
- field value type
- All Implemented Interfaces:
AttachNotifier
,BlurNotifier<CustomField<T>>
,DetachNotifier
,Focusable<CustomField<T>>
,FocusNotifier<CustomField<T>>
,HasElement
,HasEnabled
,HasHelper
,HasLabel
,HasSize
,HasStyle
,HasTheme
,HasValidation
,HasValue<AbstractField.ComponentValueChangeEvent<CustomField<T>,
,T>, T> HasValueAndElement<AbstractField.ComponentValueChangeEvent<CustomField<T>,
,T>, T> HasTooltip
,HasValidationProperties
,InputField<AbstractField.ComponentValueChangeEvent<CustomField<T>,
,T>, T> Serializable
,ValidatingField<AbstractField.ComponentValueChangeEvent<CustomField<T>,
T>, T>
- Direct Known Subclasses:
FieldBuilderCustomField
CustomField
s containing sub-fields that are managed by an internal Binder
.
As with many CustomField
's, this class this allows editing a complex value type as a single bound
property using multiple sub-fields. A common example is a date range value, which is a composite of two LocalDate
values representing start and end date.
The purpose of this class is to add an internal Binder
so that the individual sub-fields can be properly
(and separately) validated. This class also includes support for validating the overall value, for example,
requiring the date range start date to be prior to the end date.
Binding
Although a BinderCustomField
may be bound as a field to a property in some larger containing class' Binder
,
each BinderCustomField
also contains its own internal Binder
to which its private sub-fields are bound.
Subclasses can customize this internal Binder
by overriding createBinder()
.
Field Value
The value of a BinderCustomField
is generated by creating a new bean instance and then
applying the values of the internal sub-fields to it.
In order for this class to create new instances, its value type must have a public zero-arg constructor; otherwise,
the subclass must override createNewBean()
.
In any case, the value of a BinderCustomField
remains its empty value
as long as any of its sub-fields remain in an invalid state according to the internal Binder
.
Binders and Validation
Individual sub-fields are validated normally using the internal Binder
; however, this guarantees only that
the sub-fields are valid. It does not validate this BinderCustomField
's value, which is derived from a combination
of the sub-fields; normally, that's the responsibilty of some outer Binder
, not the internal Binder
.
Subclasses can override validate()
to implement "whole bean" validation contraints on
this BinderCustomField
's value. However, for whole bean validation to have any effect, some code must register
the validation provided by validate()
to the outer binding. This happens automatically when this
field is created by a FieldBuilder
, or by any other mechanism which recognizes the ValidatingField
interface
(which this class implements). In particular, it's possible to recursively nest BinderCustomField
's using
FieldBuilder
annotations and have proper validation at each level.
See also WholeBeanValidator
for another way to do "whole bean" validation using JSR 303 validation constraints.
Layout
For layout, BinderCustomField
simply concatenates the sub-fields into a HorizontalLayout
.
Subclasses can customize this behavior by overriding layoutComponents()
.
Example
See FieldBuilderCustomField
for an example.
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from class com.vaadin.flow.component.AbstractField
AbstractField.ComponentValueChangeEvent<C extends Component,
V extends Object> Nested classes/interfaces inherited from interface com.vaadin.flow.component.BlurNotifier
BlurNotifier.BlurEvent<C extends Component>
Nested classes/interfaces inherited from interface com.vaadin.flow.component.FocusNotifier
FocusNotifier.FocusEvent<C extends Component>
Nested classes/interfaces inherited from interface com.vaadin.flow.component.HasValue
HasValue.ValueChangeEvent<V extends Object>, HasValue.ValueChangeListener<E extends HasValue.ValueChangeEvent<?>>
-
Field Summary
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionprotected abstract void
Create this field's sub-fields and bind them tobinder
.Create a newBinder
for the given type.protected T
Create a new instance of the bean model class.protected T
Get the model type.protected void
Initialize this instance.protected void
Layout components required for this field.void
setEnabled
(boolean enabled) void
setErrorMessage
(String errorMessage) Sets an error message to the component.protected void
setPresentationValue
(T value) validate
(T value, ValueContext ctx) Validate this instance.Methods inherited from class com.vaadin.flow.component.customfield.CustomField
add, addThemeVariants, getLabel, onAttach, remove, removeThemeVariants, setLabel, updateValue
Methods inherited from class com.vaadin.flow.component.AbstractField
addValueChangeListener, getEmptyValue, getValue, isEmpty, setModelValue, setValue, valueEquals
Methods inherited from class com.vaadin.flow.component.Component
addListener, findAncestor, fireEvent, from, get, getChildren, getElement, getEventBus, getId, getListeners, getLocale, getParent, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getUI, hasListener, isAttached, isTemplateMapped, isVisible, onDetach, onEnabledStateChanged, removeFromParent, scrollIntoView, scrollIntoView, set, setElement, setId, setVisible
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface com.vaadin.flow.component.AttachNotifier
addAttachListener
Methods inherited from interface com.vaadin.flow.component.BlurNotifier
addBlurListener
Methods inherited from interface com.vaadin.flow.component.DetachNotifier
addDetachListener
Methods inherited from interface com.vaadin.flow.component.Focusable
addFocusShortcut, blur, focus, getTabIndex, setTabIndex
Methods inherited from interface com.vaadin.flow.component.FocusNotifier
addFocusListener
Methods inherited from interface com.vaadin.flow.component.HasElement
getElement
Methods inherited from interface com.vaadin.flow.component.HasEnabled
isEnabled
Methods inherited from interface com.vaadin.flow.component.HasHelper
getHelperComponent, getHelperText, setHelperComponent, setHelperText
Methods inherited from interface com.vaadin.flow.component.HasSize
getHeight, getHeightUnit, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getWidth, getWidthUnit, setHeight, setHeight, setHeightFull, setMaxHeight, setMaxHeight, setMaxWidth, setMaxWidth, setMinHeight, setMinHeight, setMinWidth, setMinWidth, setSizeFull, setSizeUndefined, setWidth, setWidth, setWidthFull
Methods inherited from interface com.vaadin.flow.component.HasStyle
addClassName, addClassNames, getClassName, getClassNames, getStyle, hasClassName, removeClassName, removeClassNames, setClassName, setClassName
Methods inherited from interface com.vaadin.flow.component.HasTheme
addThemeName, addThemeNames, getThemeName, getThemeNames, hasThemeName, removeThemeName, removeThemeNames, setThemeName, setThemeName
Methods inherited from interface com.vaadin.flow.component.shared.HasTooltip
getTooltip, setTooltipText
Methods inherited from interface com.vaadin.flow.component.HasValidation
setManualValidation
Methods inherited from interface com.vaadin.flow.component.shared.HasValidationProperties
getErrorMessage, isInvalid, setInvalid
Methods inherited from interface com.vaadin.flow.component.HasValue
addValueChangeListener, clear, getEmptyValue, getOptionalValue, getValue, isEmpty, setValue
Methods inherited from interface com.vaadin.flow.component.HasValueAndElement
isReadOnly, isRequiredIndicatorVisible, setReadOnly, setRequiredIndicatorVisible
Methods inherited from interface org.dellroad.stuff.vaadin24.field.ValidatingField
addValidationTo
-
Field Details
-
modelType
The field value type. -
binder
The binder that is bound to this instance's sub-fields. -
subfieldValidationErrors
protected boolean subfieldValidationErrorsWhether any sub-fields currently have a validation error.
-
-
Constructor Details
-
BinderCustomField
Constructor.- Parameters:
modelType
- field value type- Throws:
IllegalArgumentException
- ifmodelType
is null
-
-
Method Details
-
getModelType
Get the model type. -
initialize
protected void initialize()Initialize this instance.The implementation in
BinderCustomField
invokescreateAndBindFields()
and thenlayoutComponents()
.Note: this method is invoked from the constructor, so any subclass constructor initialization will not have been done yet. Subclasses can fix this by overriding this method and invoking
VaadinUtil.accessCurrentSession
(() -> super.initialize())
. -
createBinder
Create a newBinder
for the given type.The implementation in
BinderCustomField
delegates toBinder(Class)
. Subclasses can override this method to substituteBeanValidationBinder
, configure additional validators, etc.Note: this method is invoked from the constructor.
- Returns:
- field builder
-
createAndBindFields
protected abstract void createAndBindFields()Create this field's sub-fields and bind them tobinder
. -
layoutComponents
protected void layoutComponents()Layout components required for this field.The implementation in
BinderCustomField
iterates the bound fields inbinder
into a newHorizontalLayout
which is then added to this instance, assuming all fields are also actuallyComponent
's.Subclasses can override this method to add decoration and/or layout differently.
-
createNewBean
Create a new instance of the bean model class.This value is used to create beans to be populated with sub-field values and returned from
generateModelValue()
.The implementation in
BinderCustomField
attempts to invoke a default constructor for the bean class.- Returns:
- new empty bean
-
validate
Validate this instance.The implementation in
BinderCustomField
always returnsValidationResult.ok()
.- Specified by:
validate
in interfaceValidatingField<AbstractField.ComponentValueChangeEvent<CustomField<T>,
T>, T> - Parameters:
value
- field value to validatectx
- the value context for validation- Returns:
- the validation result
-
setEnabled
public void setEnabled(boolean enabled) The implementation in
BinderCustomField
delegates to the superclass and then removes any error message from sub-fields that implementHasValidation
.- Specified by:
setEnabled
in interfaceHasEnabled
-
setErrorMessage
Sets an error message to the component.The implementation in
BinderCustomField
delegates to the overridden superclass method except whenerrorMessage
is not null and any sub-field currently has a validation error. This is to avoid clutter in the display.- Specified by:
setErrorMessage
in interfaceHasValidation
- Specified by:
setErrorMessage
in interfaceHasValidationProperties
-
generateModelValue
The implementation in
BinderCustomField
returns the empty value if the internal binder is invalid, otherwise a newly created bean instance populated with the current sub-fields' values.- Specified by:
generateModelValue
in classCustomField<T>
-
setPresentationValue
The implementation in
BinderCustomField
updates the sub-fields fromvalue
unless it is equal to the empty value, in which case from a newly created bean instance.- Specified by:
setPresentationValue
in classCustomField<T>
-