After some digging, turned out that the culprit (aka: the collaborator that cancels the edit before the textField looses focus) is the TableCellBehaviour/Base in its processing of a mousePressed:
- mousePressed calls
simpleSelect(..)
- on detecting a single click it calls
edit(-1, null)
- which calls the same method on TableView
- which sets its editingCell property to null
- a tableCell listens to that property and reacts by canceling its own edit
Unfortunately, a hackaround requires 3 collaborators
- a TableView with additional api to terminate an edit
- a TableCellBehaviour with overridden
simpleSelect(...)
that calls the additional api (instead of edit(-1..)) before calling super - a TableCell that is configured with the extended behaviour and is aware of table’s extended properties
Some code snippets (full code) :
// on XTableView:
public void terminateEdit() {
if (!isEditing()) return;
// terminatingCell is a property that supporting TableCells can listen to
setTerminatingCell(getEditingCell());
if (isEditing()) throw new IllegalStateException(
"expected editing to be terminated but was " + getEditingCell());
setTerminatingCell(null);
}
// on XTableCellBehaviour: override simpleSelect
@Override
protected void simpleSelect(MouseEvent e) {
TableCell<S, T> cell = getControl();
TableView<S> table = cell.getTableColumn().getTableView();
if (table instanceof XTableView) {
((XTableView<S>) table).terminateEdit();
}
super.simpleSelect(e);
}
// on XTextFieldTableCell - this method is called from listener
// to table's terminatingCell property
protected void terminateEdit(TablePosition<S, ?> newPosition) {
if (!isEditing() || !match(newPosition)) return;
commitEdit();
}
protected void commitEdit() {
T edited = getConverter().fromString(myTextField.getText());
commitEdit(edited);
}
/**
* Implemented to create XTableCellSkin which supports terminating edits.
*/
@Override
protected Skin<?> createDefaultSkin() {
return new XTableCellSkin<S, T>(this);
}
Note: the implementation of TableCellBehaviour changed massively between jdk8u5 and jdk8u20 (joys of hacking – not fit for production use 😉 – the method to override in the latter is handleClicks(..)
BTW: massive votingfor JDK-8089514 (was RT-18492 in old jira) might speed up a core fix. Unfortunately, at least the author role is needed to vote/comment bugs in the new tracker.