Updating generated columns

Hi,

We have an editable table that uses a field factory. We also have a calculated column in this table that should be generated by multiplying 3 other values (in the same row) together. We would like this value to be updated any time any of the three values is changed.

I’ve browsed the forums and seen https://vaadin.com/forum/#!/thread/48512/49275 and https://dev.vaadin.com/ticket/2823. That thread offers the following solution:

public Component generateCell(Table source, Object itemId,
        Object columnId) {
    final Label l = new Label();
    final Property integer = source.getContainerProperty(itemId,
            "integer");
    l.setValue(getMultipliedValue(integer));
    // we must hook value change listener to ensure updates in all use
    // cases (eg. edit mode)
    if (integer instanceof Property.ValueChangeNotifier) {
        Property.ValueChangeNotifier notifier = (Property.ValueChangeNotifier) integer;
        notifier.addListener(new ValueChangeListener() {
            public void valueChange(ValueChangeEvent event) {
                l.setValue(getMultipliedValue(integer));
            }
        });
    }
   return l;

The issue for us, however, is we are not using a BeanContainer, we are using a ListContainer from the Viritin plugin. Properties from this container do not implement Property.ValueChangeNotifier, they are internal dynabean properties and, as such, cannot have listeners added to them. I also don’t really like the idea of adding an extra listener to the property every single time this cell is generated.

That thread seems to be from ~5 years ago. Is there an alternate approach that could be taken?

The same is also true of the footer (summary) on the table. We have the footer re-generate when the item data set is changed, but is there a preferred way to have it dynamically update when fields inside a table are edited?

Hi,

One way to solve this would be to customize the fieldFactory (setTableFieldFactory(TableFieldFactory)) with an implementation that caches, potentially with weak references the created field. Then you could bind the value change listener into the field instead of the property.

Another solution would be to use some other event mechanism like to make your bean extend the good old
Observable
or make a wrapped version that extends Observable. This might actually be simpler in your case as your calculated value depends on more than one properties.

cheers,
matti