Thanks Colin for your detailed answer. I tried implementing your idea using the command pattern.
Here is my Code of the Command:
Code:
public class GridCellChangeCommand<M,V> implements Command {
private Store<M>.Record record;
private ValueProvider<? super M, V> provider;
private Change<M, ?> change;
public GridCellChangeCommand (Store<M>.Record record, ValueProvider<? super M, V> provider) {
this.record = record;
this.provider = provider;
for(Change<M, ?> change : record.getChanges()) {
this.change = change;
}
}
@Override
public void execute() {
}
@Override
public void undo() {
record.revert(provider);
}
@Override
public void redo() {
record.addChange(provider, (V) change.getValue());
}
}
And here is the code, that generates the command and put it to the undo stack:
Code:
protected <M> void register(Grid<M> grid) {
grid.getStore().addStoreRecordChangeHandler(new StoreRecordChangeHandler<M>() {
@Override
public void onRecordChange(StoreRecordChangeEvent<M> event) {
Store<M>.Record rec = event.getRecord();
ValueProvider<? super M, ?> prop = event.getProperty();
GridCellChangeCommand<M, ?> c = new GridCellChangeCommand((Record) rec, prop);
undoStack.push(c);
eventBus.fireEvent(new UndoableEvent());
}
});
}
The first problem is, that record.getChanges() in my command class always returns one change, I would have expected, that it returns all changes that was made to the record. A closer look at the source of method Record#addChange shows that
Code:
changes.put(c.getChangeTag(), c);
is responsibly for that, because c#getChangeTag() always returns the same valueProvider and so the new change always replaces the old change (same key). Can you tell me the reason for that?
The second problem is, that my redo-method adds a change to the record what ends up in firing a new StoreUpdateEvent, so my listener generates a new undo-command.
I'm not sure if it would be easier to set the auto-commit in store to false and implementing the changes by myself...Any ideas for solving my problems?