1

当 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);
4

1 回答 1

2

为什么我没有看到focusedProperty 发生变化的简短答案是没有变化,因为该属性始终为假。

原因是,树/表/单元格的focusedProperty(可以说是错误的)用于表示树/表视图的FocusModel 的焦点单元格(与“真正的”焦点为focusOwner 相比),但前提是cellSelectionEnabled。

updateFocus 中的相关代码片段(在 TableCell 中)由 InvalidationListener 调用 fi 到 FocusModel 的focusedProperty:

private void updateFocus() {
    final boolean isFocused = isFocused();
    if (! isInCellSelectionMode()) {
        if (isFocused) {
            setFocused(false);
        }
        return;
    }
    ...
}  
于 2015-10-30T11:30:15.307 回答