JAVAFX 8 TreeTableView:为什么这段代码没有检测到失去焦点的单元格?

JAVAFX 8 TreeTableView: why doesn't this code detect cell losing focus?

我正尝试在 JavaFX 8 TreeTableView 单元格失去焦点时提交编辑。我看到这个问题已经被问到,但我想了解为什么我在下面的尝试不起作用。更具体地说,为什么不调用单元格的 focusedProperty 的侦听器。

Item<String, Object> 是我的数据表示,是 Map<String, Object>.

的扩展

基本上,我将标准文本单元格工厂包装在一个使用标准单元格工厂创建单元格的新单元格工厂中,并向其 focusedProperty 添加了一个侦听器。当失去焦点时,我将单元格文本存储在其上。

但是,打印输出表明事件侦听器从未被调用。

我将侦听器添加到单元格的 focusedProperty,因为我无法识别直接给我文本控件的方法。 getGraphic() 方法(我在某处读到的用词不当,因为它指向单元格中的任何节点)returns 一个空指针。

知道为什么永远不会调用侦听器吗?谢谢

// 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 的聚焦单元格(相对于 "real" 焦点作为 focusOwner),但前提是 cellSelectionEnabled。

updateFocus(在 TableCell 中)中的相关代码片段称为 f.i。通过 InvalidationListener 到 FocusModel 的 focusedProperty:

private void updateFocus() {
    final boolean isFocused = isFocused();
    if (! isInCellSelectionMode()) {
        if (isFocused) {
            setFocused(false);
        }
        return;
    }
    ...
}