Fire value change event in editable table, when value of the field changes

I have a component, that extends table, which should perform an action added as
ValueChangeListener
in all following situations:

  • user selects a row (standard application of
    ValueChangeListener
    )
  • a row is added to a table - following works fine addItemSetChangeListener(event -> fireValueChange(true))
  • user changes a value in one of the fields - following code causes infinitive loop
    @Override public Field<?> createField(Container container, Object itemId, Object propertyId, Component uiContext) { Field<?> field = super.createField(container, itemId, propertyId, uiContext); field.addValueChangeListener(event -> ExtTable.this.fireValueChange(true)); return field; }

Does it exist a way to just notify the listeners, that something has changed?

Looks almost legit to me, except that firing a ValueChange on the ExtTable looks odd. Table’s value is its selection, so firing a value change implies selection change, not a change in the Table’s data content. However, I can’t see how calling that would cause an infinite loop. Does the loop occur when the event is fired or while building the fields?

Why fire an event and not just call a handler method in the ExtTable class from the listener? You could pass the event object or the field to it, or both. Also, instead of creating a separate listener instance (in your case as a lambda) for each field, you could define a listener instance which is shared by all the fields; note that in that case you probably need to remove the listener explicitly when the field is detached (otherwise the listener keeps the field from getting destroyed).

Hello Marko, thanks for answer. You are right, it is strange. I tried to fire
ItemSetChangeEvent
instead of
ValueChangeEvent
, but it goes to infinitive loop, when adding a new row.

The problem with infinitive loop with original code is when building the fields for
BeanItemContainer
. Changing the listener body to if (!((AbstractField) event.getProperty()).isAttached()){ return; } ExtTable.this.fireValueChange(true); works as expected, but, as you said, it is rather
ItemSetChangeEvent
than
ValueChangeEvent
.

What do you mean by “Why fire an event and not just call a handler method in the ExtTable class from the listener?” Could you please explain it with a piece of code?

I mean, why fire an event and not simply do as in the following?[code]
class ExtTable extends Table {

protected fieldValueChange(ValueChangeEvent event) {
    ... whatever you want to do with the value change ...
}

...
class FFactory implements FieldFactory {
    @Override
    public Field<?> createField(Container container, Object itemId, Object propertyId, Component uiContext){
        Field<?> field = super.createField(container, itemId, propertyId, uiContext);
        field.addValueChangeListener(event -> fieldValueChange(event));
        return field;
    }
}

}

[/code]