diff options
author | Artur Signell <artur@vaadin.com> | 2011-12-16 09:27:56 +0200 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2011-12-16 09:27:56 +0200 |
commit | b0398e876695be532d9d0edc8764f622ed56c837 (patch) | |
tree | 9daeec19e5f1773948e151540d09ab3d79b195f6 /src | |
parent | 1c262e237ce53fedb289737ec29946fb18e08249 (diff) | |
download | vaadin-framework-b0398e876695be532d9d0edc8764f622ed56c837.tar.gz vaadin-framework-b0398e876695be532d9d0edc8764f622ed56c837.zip |
#8095 Added field type to field factory to be able to validate that a
field of correct type is created and to be able to create different
fields (e.g. selects) based on what the user wants.
Diffstat (limited to 'src')
3 files changed, 138 insertions, 34 deletions
diff --git a/src/com/vaadin/data/fieldbinder/DefaultFieldBinderFieldFactory.java b/src/com/vaadin/data/fieldbinder/DefaultFieldBinderFieldFactory.java index c2dac85164..18a979cf65 100644 --- a/src/com/vaadin/data/fieldbinder/DefaultFieldBinderFieldFactory.java +++ b/src/com/vaadin/data/fieldbinder/DefaultFieldBinderFieldFactory.java @@ -6,41 +6,118 @@ package com.vaadin.data.fieldbinder; import java.util.EnumSet;
import com.vaadin.data.Item;
+import com.vaadin.ui.AbstractSelect;
+import com.vaadin.ui.AbstractTextField;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Field;
+import com.vaadin.ui.ListSelect;
+import com.vaadin.ui.NativeSelect;
+import com.vaadin.ui.OptionGroup;
+import com.vaadin.ui.PasswordField;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
public class DefaultFieldBinderFieldFactory implements FieldBinderFieldFactory {
public static final Object CAPTION_PROPERTY_ID = "Caption";
- @SuppressWarnings("unchecked")
- public Field createField(Class<?> type) {
+ public Field createField(Class<?> type, Class<? extends Field> fieldType) {
if (Enum.class.isAssignableFrom(type)) {
- return createEnumField((Class<? extends Enum<?>>) type);
- }
- if (Boolean.class.isAssignableFrom(type)
+ return createEnumField(type, fieldType);
+ } else if (Boolean.class.isAssignableFrom(type)
|| boolean.class.isAssignableFrom(type)) {
- return createBooleanField();
+ return createBooleanField(fieldType);
}
- return createDefaultField(type);
+ return createDefaultField(type, fieldType);
}
- private Field createBooleanField() {
- CheckBox cb = new CheckBox(null);
- cb.setImmediate(true);
- return cb;
- }
+ private Field createEnumField(Class<?> type,
+ Class<? extends Field> fieldType) {
+ if (AbstractSelect.class.isAssignableFrom(fieldType)) {
+ AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType);
+ populateWithEnumData(s, (Class<? extends Enum>) type);
+ return s;
+ }
- private Field createDefaultField(Class<?> type) {
- return new TextField();
+ return null;
}
- public Field createEnumField(Class<? extends Enum> enumClass) {
- ComboBox select = new ComboBox(null);
+ protected AbstractSelect createCompatibleSelect(
+ Class<? extends AbstractSelect> fieldType) {
+ AbstractSelect select;
+ if (fieldType.isAssignableFrom(ListSelect.class)) {
+ select = new ListSelect();
+ select.setMultiSelect(false);
+ } else if (fieldType.isAssignableFrom(NativeSelect.class)) {
+ select = new NativeSelect();
+ } else if (fieldType.isAssignableFrom(OptionGroup.class)) {
+ select = new OptionGroup();
+ select.setMultiSelect(false);
+ } else if (fieldType.isAssignableFrom(Table.class)) {
+ Table t = new Table();
+ t.setSelectable(true);
+ select = t;
+ } else {
+ select = new ComboBox(null);
+ }
select.setImmediate(true);
select.setNullSelectionAllowed(false);
+
+ return select;
+ }
+
+ protected Field createBooleanField(Class<? extends Field> fieldType) {
+ if (fieldType.isAssignableFrom(CheckBox.class)) {
+ CheckBox cb = new CheckBox(null);
+ cb.setImmediate(true);
+ return cb;
+ } else if (AbstractTextField.class.isAssignableFrom(fieldType)) {
+ return createAbstractTextField((Class<? extends AbstractTextField>) fieldType);
+ }
+
+ return null;
+ }
+
+ protected AbstractTextField createAbstractTextField(
+ Class<? extends AbstractTextField> fieldType) {
+ if (fieldType.isAssignableFrom(PasswordField.class)) {
+ PasswordField pf = new PasswordField();
+ pf.setImmediate(true);
+ return pf;
+ } else if (fieldType.isAssignableFrom(TextField.class)) {
+ TextField tf = new TextField();
+ tf.setImmediate(true);
+ return tf;
+ } else if (fieldType.isAssignableFrom(TextArea.class)) {
+ TextArea ta = new TextArea();
+ ta.setImmediate(true);
+ return ta;
+ }
+
+ return null;
+ }
+
+ protected Field createDefaultField(Class<?> type,
+ Class<? extends Field> fieldType) {
+ if (AbstractTextField.class.isAssignableFrom(fieldType)) {
+ return createAbstractTextField((Class<? extends AbstractTextField>) fieldType);
+ }
+ return null;
+ }
+
+ /**
+ * @param select
+ * @param enumClass
+ */
+ protected void populateWithEnumData(AbstractSelect select,
+ Class<? extends Enum> enumClass) {
+ // TODO EnumContainer?
+ select.removeAllItems();
+ for (Object p : select.getContainerPropertyIds()) {
+ select.removeContainerProperty(p);
+ }
select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, "");
select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID);
@SuppressWarnings("unchecked")
@@ -49,7 +126,5 @@ public class DefaultFieldBinderFieldFactory implements FieldBinderFieldFactory { Item newItem = select.addItem(r);
newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString());
}
- return select;
}
-
}
diff --git a/src/com/vaadin/data/fieldbinder/FieldBinderFieldFactory.java b/src/com/vaadin/data/fieldbinder/FieldBinderFieldFactory.java index 0d445364d3..3d4b0b49a3 100644 --- a/src/com/vaadin/data/fieldbinder/FieldBinderFieldFactory.java +++ b/src/com/vaadin/data/fieldbinder/FieldBinderFieldFactory.java @@ -21,7 +21,11 @@ public interface FieldBinderFieldFactory extends Serializable { *
* @param dataType
* The type that we want to edit using the field
- * @return A field capable of editing the given type of data
+ * @param fieldType
+ * The type of field we want to create. If set to {@link Field}
+ * then any type of field is accepted
+ * @return A field that can be assigned to the given fieldType and that is
+ * capable of editing the given type of data
*/
- Field<?> createField(Class<?> dataType);
+ Field<?> createField(Class<?> dataType, Class<? extends Field> fieldType);
}
diff --git a/src/com/vaadin/data/fieldbinder/FormBuilder.java b/src/com/vaadin/data/fieldbinder/FormBuilder.java index a623cb1e24..2dc567570e 100644 --- a/src/com/vaadin/data/fieldbinder/FormBuilder.java +++ b/src/com/vaadin/data/fieldbinder/FormBuilder.java @@ -5,21 +5,29 @@ package com.vaadin.data.fieldbinder; import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
+import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.logging.Logger;
+
+import org.apache.tools.ant.BuildException;
import com.vaadin.data.fieldbinder.FieldBinder.BindException;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
/**
- * FIXME Javadoc
+ * Class for constructing form fields based on a data type.
+ * <p>
*
+ * FIXME Javadoc
*/
-public class FormBuilder {
+public class FormBuilder implements Serializable {
private FieldBinderFieldFactory fieldFactory = new com.vaadin.data.fieldbinder.DefaultFieldBinderFieldFactory();
private FieldBinder fieldBinder;
+ private static final Logger logger = Logger.getLogger(FormBuilder.class
+ .getName());
/**
* Constructs a FormBuilder that can be used to build forms automatically.
@@ -77,11 +85,11 @@ public class FormBuilder { * @param propertyId
* The property id to bind to. Must be present in the field
* finder.
- * @return The created and bound field
+ * @return The created and bound field. Can be any type of {@link Field}.
*/
public Field<?> buildAndBind(String caption, Object propertyId) {
Class<?> type = getFieldBinder().getPropertyType(propertyId);
- return buildAndBind(caption, propertyId, type);
+ return buildAndBind(caption, propertyId, type, Field.class);
}
@@ -96,29 +104,44 @@ public class FormBuilder { * binder.
* @param type
* The data model type we want to edit using the field
+ * @param fieldType
+ * The type of field we want to create
* @return The created and bound field
*/
protected Field<?> buildAndBind(String caption, Object propertyId,
- Class<?> type) {
- Field<?> field = build(caption, type);
+ Class<?> type, Class<? extends Field> fieldType) {
+ Field<?> field = build(caption, type, fieldType);
fieldBinder.bind(field, propertyId);
return field;
}
/**
- * Creates a field based on the given type. The type should be the data
- * model type and not a Vaadin Field type.
+ * Creates a field based on the given data type.
+ * <p>
+ * The data type is the type that we want to edit using the field. The field
+ * type is the type of field we want to create, can be {@link Field} if any
+ * Field is good.
+ * </p>
*
* @param caption
* The caption for the new field
- * @param type
+ * @param dataType
* The data model type that we want to edit using the field
+ * @param fieldType
+ * The type of field that we want to create
* @return A Field capable of editing the given type
*/
- protected Field<?> build(String caption, Class<?> type) {
- System.err.println("Building a field with caption " + caption
- + " of type " + type.getName());
- Field<?> field = getFieldFactory().createField(type);
+ protected Field<?> build(String caption, Class<?> dataType,
+ Class<? extends Field> fieldType) {
+ logger.finest("Building a field with caption " + caption + " of type "
+ + dataType.getName());
+ Field<?> field = getFieldFactory().createField(dataType, fieldType);
+ if (field == null) {
+ throw new BuildException("Unable to build a field of type "
+ + fieldType.getName() + " for editing "
+ + dataType.getName());
+ }
+
field.setCaption(caption);
return field;
}
@@ -171,6 +194,8 @@ public class FormBuilder { // Process next field
continue;
}
+ Class<? extends Field> fieldType = (Class<? extends Field>) f
+ .getType();
Object propertyId = null;
if (propertyIdAnnotation != null) {
@@ -210,7 +235,7 @@ public class FormBuilder { .createCaptionByPropertyId(propertyId);
}
// Create the component (Field)
- builtField = build(caption, propertyType);
+ builtField = build(caption, propertyType, fieldType);
// Store it in the field
setJavaFieldValue(object, f, builtField);
}
|