It's not about cancelling the event; it's about *not* routing it to a DefaultSelectionEventManager (which changes selection depending on the event). It also means you shouldn't addCellPreviewHandler, but instead use the
two-argument overload of setSelectionModel.
It's as easy as:
myCellList.setSelectionModel(mySelectionModel, CellPreviewEvent.Handler<MyObject>() {
private final CellPreviewEvent.Handler<MyObject> defaultSelectionManager = DefaultSelectionEventManager.createDefaultManager();
@Override
public void onCellPreview(CellPreviewEvent<MyObject> event) {
if (hasUnsavedChanged() && !Window.prompt("There are unsaved changes, are you sure you want to continue?") {
return;
}
return defaultSelectionManager.onCellPreview(event);
}
});
Beware though, if you have a cell that "handlesSelection()", you'll have to handle the case there (so that it doesn't change selection if there are unsaved changes).
Oh, and it just occurred to me that you could also simply code that within your SelectionModel too:
class PromptingSelectionModel<T> extends SingleSelectionModel<T> {
@Override
public void setSelected(T object, boolean selected) {
if (hasUnsavedChanged() && !Window.prompt("There are unsaved changes, are you sure you want to continue?") {
return;
}
super.setSelected(object, selected);
}
}