FieldFactory enum & Table field customization

Hi !

I’ve recently began with Vaadin and JPAContainer as a big helper but I do have some glitches to report and since it seems that I’m the only one having those, I must have done something wrong.


The first question is why I can’t get an enum field correctly with FieldFactory?

Here is my enum field definition in an entity:

@NotNull
@Enumerated(EnumType.STRING)
private Gender gender;

Here is my enum definition:

public enum Gender {
	MISS ("Miss"), 
	MRS ("Mrs"), 
	MS ("Ms"), 
	MR ("Mr"), 
	SUPPORT ("Support");
	
	private final String caption;
	
	private Gender(String caption) {
		this.caption = caption;
	}
	
	public String getCaption() {
		return caption;
	}

	@Override
	public String toString() {
		return caption;
	}
}

The classic code to make the Form:

fieldFactory = new FieldFactory();
		form = new BeanValidationForm<T>(clazz);
		form.setFormFieldFactory(fieldFactory);
		form.setWriteThrough(false);
		form.setImmediate(true);
		form.setWidth("100%");
		form.setHeight("100%");
		form.setItemDataSource(jpaContainer.createEntityItem(createEntity()));

I’m using FieldFactory in a Form and with the enum field
I get an empty Table
. It’s like the FieldFactory doesn’t get it that I do have an enum and not a ManyToMany field or something like that.

As you can see, the generated field is an empty Table. I don’t quite get it why.

I’m using:
JPA 2.1.0
beanvalidation-addon 1.0.0
Vaadin: 6.7.6

The second question is a bit stupid:

I wanted to change the Table columns used for ManyToMany Form Field (with FieldFactory). As for now, I’m extending a FieldFactory and overriding the createManyToManyField. Is this the best practice method?

Thanks in advance for your answers !

Hi,

I have the same/ a similar issue. When I use the JPAContainer Field Factory to create a field for an enum, I also get an empty table. My expectation would be to have a combobox with all enum types.

Is there any quick solution to this?

Thanks a lot!

If you have a look at the JPAContainers FieldFactory it actually do try to generate a collection editor for the enum in createField(…) , it calls createEnumSelect(item.getItemProperty(propertyId).getType(), propertyId); this in turn calls constructCollectionSelect() this is where the default behavior needs a bit of work.

NOTE the default JPAContainer FieldFactory DO allow you to customise the component to generate for your enum…
You can override this by [code]

fieldFactory.setMultiSelectType(Gender.class,ComboBox.class);

[/code]

Or overriding constructCollectionSelect with something like


 protected AbstractSelect constructCollectionSelect(EntityContainer<?> containerForProperty, Object itemId, Object propertyId, Component uiContext, Class<?> type) {
        if (multiselectTypes != null) {
            Class<? extends AbstractSelect> class1 = multiselectTypes.get(type);
            if (class1 != null) {
                try {
                    return class1.newInstance();
                } catch (Exception e) {
                    Logger.getLogger(getClass().getName()).log(Level.WARNING, "Could not create select of type {0}", class1.getName());
                }
            }
        }

        // Enum Magic starts here..
        if (type.isEnum()) {
            final NativeSelect select = new NativeSelect();
            select.setMultiSelect(false);
            return select;
        }
        // Enum Magic ends here..
        final Table table = new Table();
        table.setPageLength(5);
        return table;
    }

########

extract of original source listing of JPAContainer FieldFactory.


  
    /**
     * @param type
     * @param propertyId
     * @return
     */
    protected Field createEnumSelect(Class<?> type, Object propertyId) {
        if (type.isEnum()) {
            AbstractSelect select = constructCollectionSelect(null, null,
                    propertyId, null, type);
            populateEnums(type, select);
            select.setCaption(DefaultFieldFactory
                    .createCaptionByPropertyId(propertyId));
            return select;
        }
        return null;
    }



    protected AbstractSelect constructCollectionSelect(
            EntityContainer containerForProperty, Object itemId,
            Object propertyId, Component uiContext, Class<?> type) {
        if (multiselectTypes != null) {
            Class<? extends AbstractSelect> class1 = multiselectTypes.get(type);
            try {
                return class1.newInstance();
            } catch (Exception e) {
                Logger.getLogger(getClass().getName()).warning(
                        "Could not create select of type " + class1.getName());
            }
        }
        Table table = new Table();
        table.setPageLength(5);
        return table;
    }