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
CustomFields 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 AbstractField
AbstractField.ComponentValueChangeEvent<C,V> Nested classes/interfaces inherited from interface BlurNotifier
BlurNotifier.BlurEvent<C>Nested classes/interfaces inherited from interface FocusNotifier
FocusNotifier.FocusEvent<C>Nested classes/interfaces inherited from interface HasValue
HasValue.ValueChangeEvent<V>, HasValue.ValueChangeListener<E> -
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected abstract voidCreate this field's sub-fields and bind them tobinder.Create a newBinderfor the given type.protected TCreate a new instance of the bean model class.protected TGet the model type.protected voidInitialize this instance.protected voidLayout components required for this field.voidsetEnabled(boolean enabled) Set whether this component is enabled.voidsetErrorMessage(String errorMessage) Sets an error message to the component.protected voidsetPresentationValue(T value) validate(T value, ValueContext ctx) Validate this instance.Methods inherited from class CustomField
add, addThemeVariants, getLabel, remove, removeThemeVariants, setLabel, updateValueMethods inherited from class AbstractField
addValueChangeListener, bindValue, getEmptyValue, getValue, isEmpty, setModelValue, setValue, valueEqualsMethods inherited from class Component
addListener, bindVisible, findAncestor, fireEvent, from, get, getChildren, getElement, getEventBus, getId, getListeners, getLocale, getParent, getTestId, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getUI, hasListener, isAttached, isTemplateMapped, isVisible, onAttach, onDetach, onEnabledStateChanged, removeFromParent, scrollIntoView, scrollIntoView, set, setElement, setId, setTestId, setVisibleMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface AttachNotifier
addAttachListenerMethods inherited from interface BlurNotifier
addBlurListenerMethods inherited from interface DetachNotifier
addDetachListenerMethods inherited from interface Focusable
addFocusShortcut, blur, focus, focus, getTabIndex, setTabIndexMethods inherited from interface FocusNotifier
addFocusListenerMethods inherited from interface HasElement
getElementMethods inherited from interface HasEnabled
bindEnabled, isEnabledMethods inherited from interface HasHelper
bindHelperText, getHelperComponent, getHelperText, setHelperComponent, setHelperTextMethods inherited from interface HasSize
bindHeight, bindWidth, getHeight, getHeightUnit, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getWidth, getWidthUnit, setHeight, setHeight, setHeightFull, setMaxHeight, setMaxHeight, setMaxWidth, setMaxWidth, setMinHeight, setMinHeight, setMinWidth, setMinWidth, setSizeFull, setSizeUndefined, setWidth, setWidth, setWidthFullMethods inherited from interface HasStyle
addClassName, addClassNames, bindClassName, bindClassNames, getClassName, getClassNames, getStyle, hasClassName, removeClassName, removeClassNames, setClassName, setClassNameMethods inherited from interface HasTheme
addThemeName, addThemeNames, bindThemeName, bindThemeNames, getThemeName, getThemeNames, hasThemeName, removeThemeName, removeThemeNames, setThemeName, setThemeNameMethods inherited from interface HasTooltip
getTooltip, setTooltipMarkdown, setTooltipTextMethods inherited from interface HasValidation
setManualValidationMethods inherited from interface HasValidationProperties
getErrorMessage, isInvalid, setInvalidMethods inherited from interface HasValue
addValueChangeListener, bindValue, clear, getEmptyValue, getOptionalValue, getValue, isEmpty, setValueMethods inherited from interface HasValueAndElement
bindReadOnly, bindRequiredIndicatorVisible, isReadOnly, isRequiredIndicatorVisible, setReadOnly, setRequiredIndicatorVisibleMethods inherited from interface ValidatingField
addValidationTo
-
Field Details
-
modelType
-
binder
-
subfieldValidationErrors
protected boolean subfieldValidationErrorsWhether any sub-fields currently have a validation error.
-
-
Constructor Details
-
BinderCustomField
Constructor.- Parameters:
modelType- field value type- Throws:
IllegalArgumentException- ifmodelTypeis null
-
-
Method Details
-
getModelType
-
initialize
protected void initialize()Initialize this instance.The implementation in
BinderCustomFieldinvokescreateAndBindFields()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 newBinderfor the given type.The implementation in
BinderCustomFielddelegates 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
BinderCustomFielditerates the bound fields inbinderinto a newHorizontalLayoutwhich 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
BinderCustomFieldattempts to invoke a default constructor for the bean class.- Returns:
- new empty bean
-
validate
Validate this instance.The implementation in
BinderCustomFieldalways returnsValidationResult.ok().- Specified by:
validatein 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) Set whether this component is enabled.The implementation in
BinderCustomFielddelegates to the superclass and then removes any error message from sub-fields that implementHasValidation.- Specified by:
setEnabledin interfaceHasEnabled
-
setErrorMessage
Sets an error message to the component.The implementation in
BinderCustomFielddelegates to the overridden superclass method except whenerrorMessageis not null and any sub-field currently has a validation error. This is to avoid clutter in the display.- Specified by:
setErrorMessagein interfaceHasValidation- Specified by:
setErrorMessagein interfaceHasValidationProperties
-
generateModelValue
The implementation in
BinderCustomFieldreturns the empty value if the internal binder is invalid, otherwise a newly created bean instance populated with the current sub-fields' values.- Specified by:
generateModelValuein classCustomField<T>
-
setPresentationValue
The implementation in
BinderCustomFieldupdates the sub-fields fromvalueunless it is equal to the empty value, in which case from a newly created bean instance.- Specified by:
setPresentationValuein classCustomField<T>
-