当JavaFX 8 TreeTableView单元格失去焦点时,我正试图提交编辑。我知道这个问题已经被问过了,但我想理解为什么我下面的尝试不起作用。更具体地说,为什么没有调用单元格的focusedProperty的侦听器。
Item<String, Object>
是我的数据表示,是Map<String, Object>
的扩展。
从本质上讲,我将标准文本单元格工厂包装在一个新的单元格工厂中,该工厂使用标准单元格创建一个单元格,并在其focusedProperty中添加一个监听器。当焦点丢失时,我将单元格文本存储在上面。
但是,打印输出表明从未调用过事件侦听器。
我将侦听器添加到单元格的focusedProperty中,因为我无法识别直接为我提供文本控件的方法。getGraphic()方法(我在某个地方读到它用词不当,因为它指向单元格中的任何节点)返回一个空指针。
知道为什么听众从来没有被调用过吗?谢谢
// 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);
为什么我没有在focusedProperty中看到更改的简短答案是没有更改,因为该属性总是false。
原因是,Tree/Table/Cell的focusedProperty被(可以说是错误的)用于表示Tree/TableView的FocusModel的焦点单元格(而"真正的"焦点是focusOwner),但前提是cellSelectionEnabled。
updateFocus(在TableCell中)中的相关代码片段,由InvalidationListener对FocusModel:的focusedProperty进行f.i.调用
private void updateFocus() {
final boolean isFocused = isFocused();
if (! isInCellSelectionMode()) {
if (isFocused) {
setFocused(false);
}
return;
}
...
}