Reputation: 5722
I am trying to commit an edit when a JavaFX 8 TreeTableView cell loses focus. I see the question has already been asked, but I would like to understand why my attempt below does not work. More specifically, why a listener to the focusedProperty of the cell does not get invoked.
Item<String, Object>
is my data representation, and is an extension of Map<String, Object>
.
Essentially, I wrap the standard text cell factory within a new cell factory that uses the standard one to create a cell, and adds a listener to its focusedProperty. When focus is lost, I store the cell text on it.
However, printouts indicate the event listener is never invoked.
I added the listener to the cell's focusedProperty because I could not identity a method that gives me the text control directly. The getGraphic() method (which I read somewhere is a misnomer because it points to whatever node is in the cell) returns a null pointer.
Any idea why the listener is never invoked? Thanks.
// obtain usual cell factory for text editing
Callback<TreeTableColumn<Item<String, Object>, String>, TreeTableCell<Item<String, Object>, String>>
callBackForTreeTableColumn = TextFieldTreeTableCell.forTreeTableColumn();
// create a new cell factory that delegates the cell creation to the standard factory
// and then adds a listener to cell's focusedProperty:
Callback<TreeTableColumn<Item<String, Object>, String>, TreeTableCell<Item<String, Object>, String>>
callBackWithOnFocusedListener = new Callback<TreeTableColumn<Item<String, Object>, String>, TreeTableCell<Item<String, Object>, String>> () {
@Override
public TreeTableCell<Item<String, Object>, String> call(TreeTableColumn<Item<String, Object>, String> column) {
TreeTableCell<Item<String, Object>, String> cell = callBackForTreeTableColumn.call(column);
System.out.println(System.currentTimeMillis() + ": cell created!");
cell.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
System.out.println(System.currentTimeMillis() + ": Focus changed!");
if (! isNowFocused) {
System.out.println(System.currentTimeMillis() + ": Lost focus, going to commit!");
Item<String, Object> item = cell.getTreeTableRow().getTreeItem().getValue();
item.put(header, cell.getText());
}
});
return cell;
};
column.setCellFactory(callBackWithOnFocusedListener);
Upvotes: 1
Views: 747
Reputation: 51525
The short answer to why don't I see a change in the focusedProperty is that there is no change because the property is always false.
Reason being, that the focusedProperty of a Tree/Table/Cell is (arguably mis-) used to represent the focused cell of the Tree/TableView's FocusModel (vs. the "real" focus as being focusOwner), but only if cellSelectionEnabled.
The relevant code snippet in updateFocus (in TableCell) which is called f.i. by an InvalidationListener to the focusedProperty of the FocusModel:
private void updateFocus() {
final boolean isFocused = isFocused();
if (! isInCellSelectionMode()) {
if (isFocused) {
setFocused(false);
}
return;
}
...
}
Upvotes: 2