Editable table and notification

I try to get notified after a cell edit.

I manage to get a ValueChangeEvent by overriding BaseFieldFactory, but it does not tell me what item was modified and I feel that is not a good way to do that…

Just to clarify - you are creating textfields in fieldfactory and adding valuechange listeners to created textfields? You should get valuechangeevents when textfields are modifies and then use event -object getProperty() to get reference to the textfield. Are you setting textfields to be immediate?

Yes. When an item change, I have :

  • a generated column that is not refreshed (Maybe it is a pure IT Mill issue…).
  • to call a “save” method.

Could you give a code snippet so that we could try to replicate the problem?

Did I read the OP right: the ValueChangeEvent is happening as it should, but you need to find out which Item was modified?

It would be helpful if you could explain just a little bit more about what you are trying to achieve - there could be several ways to do this, depending on what you’re after…

Best Regards,
Marc

Pseudo code :

Item.

class MyItem {

int getId();
Date getStart();
Date getEnd();

}

Container.


public class MyContainer implements Container.Indexed {
public Item getItem(Object itemId) {

   MyItem item = ...;

   return new BeanItem(item);
}

}

Field factory.


public class MyFactory extends BaseFieldFactory implements ValueChangeNotifier {

    final HashSet<ValueChangeListener> valueChangeListeners = new HashSet<ValueChangeListener>();
    
    @Override
    public Field createField(Class type, Component uiContext) {
        Field f;
        // Date field
        if (Date.class.isAssignableFrom(type)) {
            final DateField df = new DateField();
            df.setResolution(DateField.RESOLUTION_MSEC);
            df.setImmediate(true);
            f = df;
        }
        else
            f = super.createField(type, uiContext);
        
        for( ValueChangeListener l : valueChangeListeners )
            f.addListener(l);
        
        return f;
    }

    @Override
    public void addListener(ValueChangeListener listener) {
        valueChangeListeners.add(listener);
    }

    @Override
    public void removeListener(ValueChangeListener listener) {
        valueChangeListeners.remove(listener);
    }

}

Table setup.

final Table table = ...;
final MyContainer mycontainer = ...;
MyFactory myfactory = ...;

table.setContainerDataSource(mycontainer);
table.setImmediate(true);
table.setEditable(true);
table.setFieldFactory(myfactory);

table.addGeneratedColumn("duration", new ColumnGenerator() {

    @Override
    public Component generateCell(Table source, Object itemId,
            Object columnId) {
        MyItem item = mycontainer.getItem(itemId).getBean();
        Date start = step.getStart();
        Date end = step.getEnd();

        if (null != start && null != end) {
            return new Label(DurationFormatUtils.formatDurationHMS(end.getTime() - start.getTime()));
        } else {
            return null;
        }
    }
});

Problematic code.



myfactory.addListener(new ValueChangeListener() {

            @Override
            public void valueChange(Property.ValueChangeEvent event) {

                    //What item has been changed?
                    //How can I tell table to regenerate "duration" column?
                
            }
        });

Ok, I have not looked very closely at the code yet, but I immediatly noticed one thing, so first things first:

Which version are you using?

The reason I ask:
BeanItem uses MethodProperty, which previously did not implement Property.ValueChangeNotifier. In practice this means that Table will not notice when the value changes, so the columns will not be generated again.
This is fixed in trunk.

Ticket:
http://dev.itmill.com/ticket/1978
Changeset:
http://dev.itmill.com/changeset/5221

Hope this helps!

Best Regards,
Marc

I’m working with 5.3.0.