【问题标题】:JAVAFX 8 TreeTableView: why doesn't this code detect cell losing focus?JAVAFX 8 TreeTableView:为什么这段代码没有检测到单元格失去焦点?
【发布时间】:2016-01-30 02:09:09
【问题描述】:

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

【问题讨论】:

  • 就像我在问题文本中提到的那样,它不是重复的,因为我不一定要问如何启用此类提交,而是要问为什么没有调用特定的事件处理程序。
  • 啊,我明白了 - 没有 SSCCE 很难判断,但我的第一个猜测是 cell 的focusedProperty 总是错误的,它要么是包含的 textField 要么是表它设置为真。只是猜测..
  • 谢谢!我怎样才能访问 textField,你知道吗?没找到。
  • 您确实阅读了其他问题和那里的答案,不是吗;-) focusproperty 的侦听器对根本问题没有帮助,因此您无需访问文本字段.如果您坚持:阅读 TextFieldTreeTableCell 的代码,文本字段不是公开的,但您可以在首次设置后(即在首次开始编辑之后)通过 getGraphic 访问它 - 通过收听图形属性

标签: event-handling javafx-8 eventhandler treetableview


【解决方案1】:

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

原因是,树/表格/单元格的focusedProperty(可以说是错误的)用于表示Tree/TableView的FocusModel的焦点单元格(相对于“真正的”焦点是focusOwner),但前提是启用单元格选择。

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

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

【讨论】:

  • 谢谢。您确定 cellSelectionEnabled 和 isInCellSelectionModel 在 TableCell 中吗?找不到他们。您的回答是否暗示我可以通过将 cellSelectionEnabled 设置为 true 来“解决”问题(一旦我找到它)?
  • 它是表 selectionModel 的一个属性。通常,focusedProperty 的侦听器不起作用,请参阅副本。没有尝试使用 cellSelection (无论如何,这很可能会过多地干扰您的用户界面)。顺便说一句:我回答的是“为什么”,而不是“如何”——这是你问题的重复部分;-)
猜你喜欢
  • 1970-01-01
  • 2011-09-16
  • 2019-07-26
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 2014-07-14
  • 1970-01-01
相关资源
最近更新 更多