Custom field value is not saved

Hi All,
I developed a simple abstract field that contains a textfield and a button on the right.
the problem is that the value is not saved in the pojo. all other fields (not custom) are saved correctly.

Thanks for any help
Dekel

​public class URLPanel extends CustomField<String> {

    private static final long serialVersionUID = 1L;
    private TextField txtUrl = new TextField();

    @Override
    protected void setInternalValue(String newValue) {
        super.setInternalValue(newValue);
        txtUrl.setValue(newValue);
        txtUrl.setDescription(newValue);
    }
    
    @Override
    protected Component initContent() {
        txtUrl.setWidth("100%");
        ValueChangeListener listener =  new ValueChangeListener() {
                    private static final long serialVersionUID = 1L;

            @Override
            public void valueChange(
                Property.ValueChangeEvent event) {
                setInternalValue(txtUrl.getValue());
            }
        };
        txtUrl.addValueChangeListener(listener);
        Button btnDashboards = new Button("...");
        
        HorizontalLayout layout = new HorizontalLayout(txtUrl, btnDashboards);
        layout.setWidth("100%");
        layout.setExpandRatio(txtUrl, 1.0f);
        return layout;
    }

    @Override
    public Class<? extends String> getType() {
        return String.class;
    }
}

I have a nearly the same component, but I have ovveridden
setPropertyDatasource
and
setValue
methods:

    @Override
    public void setPropertyDataSource(Property property) {
        super.setPropertyDataSource(property);
        textField.setPropertyDataSource(property);
    }

    @Override
    public void setValue(String value) {
        super.setValue(value);
        textField.setValue(value);
    }
    

Yes!
It works when I override setPropertyDataSource

Thanks!

I think overriding setPropertyDataSource is still not the perfect solution. If you bind your CustomField to a FieldGroup, you cannot use transactions, because your changes are immediatelly propagated to the Property without waiting for commit/discard. To be able to commit/discard your CustomField changes when bound to a FieldGroup, you probably need to override method setBuffered() instead of setPropertyDataSource().

@Override
public void setBuffered(boolean buffered) {
    super.setBuffered(buffered);
    if (buffered) {
        textField.setPropertyDataSource(null);
    } else {
        textField.setPropertyDataSource(getPropertyDataSource());
    }
}

This connects property data source with internal field only in non-buffered (non-transactional mode). However this does not work if CustomField is placed in a Layout without binding to a FieldGroup. A bit inconsistent behaviour.

CustomField is terrible undocumented. In official Vaadin7 Book you find only 10 (!) rows about CustomField. Other books like Vaadin 7 Cookbook, Learning Vaadin 7 or Vaadin 7 UI Design By Example do not mention CustomField at all. Looks like even Vaadin developers do not use it.

I have a custom editor field for a date object and also noticed that setInternalValue(Date d) does not work when field is not in buffered mode. So I created a method to call instead when editor has a new value:

protected void mySetEditedValue(Date d) {
        if (isBuffered()) {
            setInternalValue(d);
        } else {
            @SuppressWarnings("unchecked")
            Property<Date> p = getPropertyDataSource();
            if (p != null) {
                p.setValue(d);
            } else {
                logger.warn("buffered but no datasource");
                setInternalValue(d);
            }
        }
 

So is this enough to get it working in both buffered and unbuffered mode? It seems to work ok, but I’m quite uncertain about it.