Class FieldBuilder
- java.lang.Object
-
- org.dellroad.stuff.vaadin7.FieldBuilder
-
public class FieldBuilder extends Object
Automatically builds and binds fields for a Java bean annotated withFieldBuilderannotations. The various nestedFieldBuilderannotation types annotate Java bean property "getter" methods and specify how the the bean properties of that class should be edited usingFieldBuilder.AbstractFields. This allows all information about how to edit a Java model class to stay contained within that class.This class supports two types of annotations: first, the
@ProvidesFieldannotation annotates a method that knows how to build anFieldBuilder.AbstractFieldsuitable for editing the bean property specified by itsvalue(). So@ProvidesFieldis analgous to@ProvidesProperty, except that it defines an editing field rather than a container property.The
@FieldBuilder.AbstractFieldhierarchy annotations are the other type of annotation. These annotations annotate a Java bean property getter method and specify how to configure anFieldBuilder.AbstractFieldsubclass instance to edit the bean property corresponding to the getter method.@FieldBuilder.AbstractFieldis the top level annotation in a hierarchy of annotations that correspond to theFieldBuilder.AbstractFieldclass hierarchy.@FieldBuilder.AbstractFieldcorresponds toFieldBuilder.AbstractField, and its properties configure correspondingFieldBuilder.AbstractFieldproperties. More specific annotations correspond to the variousFieldBuilder.AbstractFieldsubclasses, for example@FieldBuilder.ComboBoxcorresponds toFieldBuilder.ComboBox. When using more specific annotations, the "superclass" annotations configure the corresponding superclass' properties.A simple example shows how these annotations are used:
// Use a 10x40 TextArea to edit the "description" property @FieldBuilder.AbstractField(caption = "Description:") @FieldBuilder.TextArea(columns = 40, rows = 10) public String getDescription() { return this.description; } // Use my own custom field to edit the "foobar" property @FieldBuilder.ProvidesField("foobar") private MyCustomField createFoobarField() { ... }A
FieldBuilderinstance will read these annotations and build the fields automatically. For example:// Create fields based on FieldGroup.* annotations Person person = new Person("Joe Smith", 100); BeanFieldGroup<Person> fieldGroup = FieldBuilder.buildFieldGroup(person); // Layout the fields in a form FormLayout layout = new FormLayout(); for (Field<?> field : fieldGroup.getFields()) layout.addComponent(field);For all annotations in the
@FieldBuilder.AbstractFieldhierarchy, leaving properties set to their default values results in the default behavior.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceFieldBuilder.AbstractFieldSpecifies how a Java property should be edited in Vaadin using anAbstractField.static interfaceFieldBuilder.AbstractSelectSpecifies how a Java property should be edited in Vaadin using anAbstractSelect.static interfaceFieldBuilder.AbstractTextFieldSpecifies how a Java property should be edited in Vaadin using aAbstractTextField.protected static classFieldBuilder.AnnotationApplier<A extends Annotation,F extends AbstractField<?>>Class that knows how to apply annotation properties to a corresponding field.static interfaceFieldBuilder.CheckBoxSpecifies how a Java property should be edited in Vaadin using anCheckBox.static interfaceFieldBuilder.ComboBoxSpecifies how a Java property should be edited in Vaadin using anComboBox.static interfaceFieldBuilder.DateFieldSpecifies how a Java property should be edited in Vaadin using anDateField.static interfaceFieldBuilder.EnumComboBoxSpecifies how a Java property should be edited in Vaadin using anEnumComboBox.static interfaceFieldBuilder.ListSelectSpecifies how a Java property should be edited in Vaadin using anListSelect.static interfaceFieldBuilder.PasswordFieldSpecifies how a Java property should be edited in Vaadin using aPasswordField.static interfaceFieldBuilder.ProvidesFieldSpecifies that the annotated method will return anAbstractFieldsuitable for editing the specified property.static interfaceFieldBuilder.TextAreaSpecifies how a Java property should be edited in Vaadin using aTextArea.static interfaceFieldBuilder.TextFieldSpecifies how a Java property should be edited in Vaadin using aTextField.
-
Constructor Summary
Constructors Constructor Description FieldBuilder()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidbuildAndBind(BeanFieldGroup<?> fieldGroup)Introspect forFieldBuilderannotations on property getter methods of theBeanFieldGroup's data source, and then build and bind the corresponding fields.protected List<FieldBuilder.AnnotationApplier<?,?>>buildApplierList(Method method)Find all relevant annotations on the given method as well as on any supertype methods it overrides.Map<String,Field<?>>buildBeanPropertyFields(Object bean)Introspect forFieldBuilderannotations on property getter methods and build a mapping from Java bean property name to a field that may be used to edit that property.protected List<FieldBuilder.AnnotationApplier<?,?>>buildDirectApplierList(Method method)Find all relevant annotations declared directly on the givenMethod.protected AbstractField<?>buildField(Collection<FieldBuilder.AnnotationApplier<?,?>> appliers, String description)Instantiate and configure anFieldBuilder.AbstractFieldaccording to the given scanned annotations.static <T> BeanFieldGroup<T>buildFieldGroup(T bean)Create aBeanFieldGroupusing the given instance, introspect forFieldBuilderannotations on property getter methods of the given bean's class, and build and bind the corresponding fields, and return the result.protected FieldBuilder.AnnotationApplier<?,?>getAnnotationApplier(Method method, Annotation annotation)Get theFieldBuilder.AnnotationApplierthat applies the given annotation.
-
-
-
Method Detail
-
buildAndBind
public void buildAndBind(BeanFieldGroup<?> fieldGroup)
Introspect forFieldBuilderannotations on property getter methods of theBeanFieldGroup's data source, and then build and bind the corresponding fields.- Parameters:
fieldGroup- field group to configure- Throws:
IllegalArgumentException- iffieldGroupis nullIllegalArgumentException- iffieldGroupdoes not yet have a data source
-
buildBeanPropertyFields
public Map<String,Field<?>> buildBeanPropertyFields(Object bean)
Introspect forFieldBuilderannotations on property getter methods and build a mapping from Java bean property name to a field that may be used to edit that property. Only bean properties that haveFieldBuilderannotations are detected.- Parameters:
bean- Java bean- Returns:
- mapping from bean property name to field
- Throws:
IllegalArgumentException- ifbeanis nullIllegalArgumentException- if invalid or conflicting annotations are encountered
-
buildFieldGroup
public static <T> BeanFieldGroup<T> buildFieldGroup(T bean)
Create aBeanFieldGroupusing the given instance, introspect forFieldBuilderannotations on property getter methods of the given bean's class, and build and bind the corresponding fields, and return the result.- Type Parameters:
T- bean type- Parameters:
bean- model bean annotated withFieldBuilderannotations- Returns:
- new
BeanFieldGroup - Throws:
IllegalArgumentException- ifbeanis null
-
buildField
protected AbstractField<?> buildField(Collection<FieldBuilder.AnnotationApplier<?,?>> appliers, String description)
Instantiate and configure anFieldBuilder.AbstractFieldaccording to the given scanned annotations.- Parameters:
appliers- annotation appliersdescription- description of the field (used for exception messages)- Returns:
- new field
-
buildApplierList
protected List<FieldBuilder.AnnotationApplier<?,?>> buildApplierList(Method method)
Find all relevant annotations on the given method as well as on any supertype methods it overrides. The method must be a getter method taking no arguments. Annotations are ordered so that annotations on a method in type X appear before annotations on an overridden method in type Y, a supertype of X.- Parameters:
method- annotated getter method- Returns:
- appliers for annotations found
- Throws:
IllegalArgumentException- ifmethodis nullIllegalArgumentException- ifmethodhas parameters
-
buildDirectApplierList
protected List<FieldBuilder.AnnotationApplier<?,?>> buildDirectApplierList(Method method)
Find all relevant annotations declared directly on the givenMethod.- Parameters:
method- method to inspect- Returns:
- annotations found
- Throws:
IllegalArgumentException- ifmethodis null
-
getAnnotationApplier
protected FieldBuilder.AnnotationApplier<?,?> getAnnotationApplier(Method method, Annotation annotation)
Get theFieldBuilder.AnnotationApplierthat applies the given annotation. Subclasses can add support for additional annotation types by overriding this method.- Parameters:
method- method to inspectannotation- method annotation to inspect- Returns:
- corresponding
FieldBuilder.AnnotationApplier, or null if annotation is unknown
-
-