import java.util.EnumSet;\r
\r
import com.vaadin.data.Item;\r
+import com.vaadin.ui.AbstractSelect;\r
+import com.vaadin.ui.AbstractTextField;\r
import com.vaadin.ui.CheckBox;\r
import com.vaadin.ui.ComboBox;\r
import com.vaadin.ui.Field;\r
+import com.vaadin.ui.ListSelect;\r
+import com.vaadin.ui.NativeSelect;\r
+import com.vaadin.ui.OptionGroup;\r
+import com.vaadin.ui.PasswordField;\r
+import com.vaadin.ui.Table;\r
+import com.vaadin.ui.TextArea;\r
import com.vaadin.ui.TextField;\r
\r
public class DefaultFieldBinderFieldFactory implements FieldBinderFieldFactory {\r
\r
public static final Object CAPTION_PROPERTY_ID = "Caption";\r
\r
- @SuppressWarnings("unchecked")\r
- public Field createField(Class<?> type) {\r
+ public Field createField(Class<?> type, Class<? extends Field> fieldType) {\r
if (Enum.class.isAssignableFrom(type)) {\r
- return createEnumField((Class<? extends Enum<?>>) type);\r
- }\r
- if (Boolean.class.isAssignableFrom(type)\r
+ return createEnumField(type, fieldType);\r
+ } else if (Boolean.class.isAssignableFrom(type)\r
|| boolean.class.isAssignableFrom(type)) {\r
- return createBooleanField();\r
+ return createBooleanField(fieldType);\r
}\r
- return createDefaultField(type);\r
+ return createDefaultField(type, fieldType);\r
}\r
\r
- private Field createBooleanField() {\r
- CheckBox cb = new CheckBox(null);\r
- cb.setImmediate(true);\r
- return cb;\r
- }\r
+ private Field createEnumField(Class<?> type,\r
+ Class<? extends Field> fieldType) {\r
+ if (AbstractSelect.class.isAssignableFrom(fieldType)) {\r
+ AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType);\r
+ populateWithEnumData(s, (Class<? extends Enum>) type);\r
+ return s;\r
+ }\r
\r
- private Field createDefaultField(Class<?> type) {\r
- return new TextField();\r
+ return null;\r
}\r
\r
- public Field createEnumField(Class<? extends Enum> enumClass) {\r
- ComboBox select = new ComboBox(null);\r
+ protected AbstractSelect createCompatibleSelect(\r
+ Class<? extends AbstractSelect> fieldType) {\r
+ AbstractSelect select;\r
+ if (fieldType.isAssignableFrom(ListSelect.class)) {\r
+ select = new ListSelect();\r
+ select.setMultiSelect(false);\r
+ } else if (fieldType.isAssignableFrom(NativeSelect.class)) {\r
+ select = new NativeSelect();\r
+ } else if (fieldType.isAssignableFrom(OptionGroup.class)) {\r
+ select = new OptionGroup();\r
+ select.setMultiSelect(false);\r
+ } else if (fieldType.isAssignableFrom(Table.class)) {\r
+ Table t = new Table();\r
+ t.setSelectable(true);\r
+ select = t;\r
+ } else {\r
+ select = new ComboBox(null);\r
+ }\r
select.setImmediate(true);\r
select.setNullSelectionAllowed(false);\r
+\r
+ return select;\r
+ }\r
+\r
+ protected Field createBooleanField(Class<? extends Field> fieldType) {\r
+ if (fieldType.isAssignableFrom(CheckBox.class)) {\r
+ CheckBox cb = new CheckBox(null);\r
+ cb.setImmediate(true);\r
+ return cb;\r
+ } else if (AbstractTextField.class.isAssignableFrom(fieldType)) {\r
+ return createAbstractTextField((Class<? extends AbstractTextField>) fieldType);\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ protected AbstractTextField createAbstractTextField(\r
+ Class<? extends AbstractTextField> fieldType) {\r
+ if (fieldType.isAssignableFrom(PasswordField.class)) {\r
+ PasswordField pf = new PasswordField();\r
+ pf.setImmediate(true);\r
+ return pf;\r
+ } else if (fieldType.isAssignableFrom(TextField.class)) {\r
+ TextField tf = new TextField();\r
+ tf.setImmediate(true);\r
+ return tf;\r
+ } else if (fieldType.isAssignableFrom(TextArea.class)) {\r
+ TextArea ta = new TextArea();\r
+ ta.setImmediate(true);\r
+ return ta;\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ protected Field createDefaultField(Class<?> type,\r
+ Class<? extends Field> fieldType) {\r
+ if (AbstractTextField.class.isAssignableFrom(fieldType)) {\r
+ return createAbstractTextField((Class<? extends AbstractTextField>) fieldType);\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * @param select\r
+ * @param enumClass\r
+ */\r
+ protected void populateWithEnumData(AbstractSelect select,\r
+ Class<? extends Enum> enumClass) {\r
+ // TODO EnumContainer?\r
+ select.removeAllItems();\r
+ for (Object p : select.getContainerPropertyIds()) {\r
+ select.removeContainerProperty(p);\r
+ }\r
select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, "");\r
select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID);\r
@SuppressWarnings("unchecked")\r
Item newItem = select.addItem(r);\r
newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString());\r
}\r
- return select;\r
}\r
-\r
}\r
\r
import java.beans.IntrospectionException;\r
import java.beans.PropertyDescriptor;\r
+import java.io.Serializable;\r
import java.lang.reflect.InvocationTargetException;\r
import java.lang.reflect.Method;\r
+import java.util.logging.Logger;\r
+\r
+import org.apache.tools.ant.BuildException;\r
\r
import com.vaadin.data.fieldbinder.FieldBinder.BindException;\r
import com.vaadin.ui.DefaultFieldFactory;\r
import com.vaadin.ui.Field;\r
\r
/**\r
- * FIXME Javadoc\r
+ * Class for constructing form fields based on a data type.\r
+ * <p>\r
* \r
+ * FIXME Javadoc\r
*/\r
-public class FormBuilder {\r
+public class FormBuilder implements Serializable {\r
\r
private FieldBinderFieldFactory fieldFactory = new com.vaadin.data.fieldbinder.DefaultFieldBinderFieldFactory();\r
private FieldBinder fieldBinder;\r
+ private static final Logger logger = Logger.getLogger(FormBuilder.class\r
+ .getName());\r
\r
/**\r
* Constructs a FormBuilder that can be used to build forms automatically.\r
* @param propertyId\r
* The property id to bind to. Must be present in the field\r
* finder.\r
- * @return The created and bound field\r
+ * @return The created and bound field. Can be any type of {@link Field}.\r
*/\r
public Field<?> buildAndBind(String caption, Object propertyId) {\r
Class<?> type = getFieldBinder().getPropertyType(propertyId);\r
- return buildAndBind(caption, propertyId, type);\r
+ return buildAndBind(caption, propertyId, type, Field.class);\r
\r
}\r
\r
* binder.\r
* @param type\r
* The data model type we want to edit using the field\r
+ * @param fieldType\r
+ * The type of field we want to create\r
* @return The created and bound field\r
*/\r
protected Field<?> buildAndBind(String caption, Object propertyId,\r
- Class<?> type) {\r
- Field<?> field = build(caption, type);\r
+ Class<?> type, Class<? extends Field> fieldType) {\r
+ Field<?> field = build(caption, type, fieldType);\r
fieldBinder.bind(field, propertyId);\r
return field;\r
}\r
\r
/**\r
- * Creates a field based on the given type. The type should be the data\r
- * model type and not a Vaadin Field type.\r
+ * Creates a field based on the given data type.\r
+ * <p>\r
+ * The data type is the type that we want to edit using the field. The field\r
+ * type is the type of field we want to create, can be {@link Field} if any\r
+ * Field is good.\r
+ * </p>\r
* \r
* @param caption\r
* The caption for the new field\r
- * @param type\r
+ * @param dataType\r
* The data model type that we want to edit using the field\r
+ * @param fieldType\r
+ * The type of field that we want to create\r
* @return A Field capable of editing the given type\r
*/\r
- protected Field<?> build(String caption, Class<?> type) {\r
- System.err.println("Building a field with caption " + caption\r
- + " of type " + type.getName());\r
- Field<?> field = getFieldFactory().createField(type);\r
+ protected Field<?> build(String caption, Class<?> dataType,\r
+ Class<? extends Field> fieldType) {\r
+ logger.finest("Building a field with caption " + caption + " of type "\r
+ + dataType.getName());\r
+ Field<?> field = getFieldFactory().createField(dataType, fieldType);\r
+ if (field == null) {\r
+ throw new BuildException("Unable to build a field of type "\r
+ + fieldType.getName() + " for editing "\r
+ + dataType.getName());\r
+ }\r
+\r
field.setCaption(caption);\r
return field;\r
}\r
// Process next field\r
continue;\r
}\r
+ Class<? extends Field> fieldType = (Class<? extends Field>) f\r
+ .getType();\r
\r
Object propertyId = null;\r
if (propertyIdAnnotation != null) {\r
.createCaptionByPropertyId(propertyId);\r
}\r
// Create the component (Field)\r
- builtField = build(caption, propertyType);\r
+ builtField = build(caption, propertyType, fieldType);\r
// Store it in the field\r
setJavaFieldValue(object, f, builtField);\r
}\r