在JavaFX中,我如何确定获得焦点的节点是否是我自己的子节点?

时间:2013-07-18 18:33:37

标签: javafx

我正在使用JavaFX中的TableView。我想做的是跟踪对表格的编辑。当用户离开表格时,我想检查是否有任何编辑,如果是,则提示用户询问他们是否要保存更改。

我有TableView工作,我可以跟踪编辑,我可以确定TableView何时失去焦点(使用focusedProperty更改侦听器)。

然而,问题是当单击一个单元格进行编辑时,表格的focusedProperty更改侦听器将触发(编辑单元格获得焦点,表格本身会丢失它)。我真正想要的是一种方法来判断焦点更改时是否更改为表的子节点(例如列或单元格)或表外的某些内容(在父GUI上选择不同的选项卡)。但我不想将侦听器添加到可以单击的每个其他可能节点。

如果我知道如何获取当前关注的项目(还没有看到如何做到这一点),我可以递归调用getParent()并检查TableView是否在该列表中,如果是,我会知道这是个孩子。但我还没有看到一种通用的方法来获取应用程序中当前关注的节点。

没有好的通用方法来遍历表的子节点,因为getChildrenUnmodifiable()返回我的Node()类型(我想我可以逐个演员来确定他们每个人是否有更多孩子),或者我必须去从TableColumns到那里的单元格(并检查每个单元格的图形)。

我可能会以递归方式迭代子项,根据需要进行转换,并在此时检查isFocused(),除非有更好的解决方案。但是我希望这里的某个人能够更好地解决这个问题,最好是更通用的解决方案。

2 个答案:

答案 0 :(得分:6)

我从节点进行搜索,投射到孩子并检查焦点节点是否是孩子。它不优雅 - 当然感觉应该有更好的方式。但这是我过去常用的方法:

private boolean isChildFocused(javafx.scene.Parent parent)
{
    for (Node node : parent.getChildrenUnmodifiable())
    {
        if (node.isFocused())
        {
            return true;
        }
        else if (node instanceof javafx.scene.Parent)
        {
            if (isChildFocused((javafx.scene.Parent)node))
            {
                return true;
            }
        }
    }
    return false;
}

它似乎工作正常(至少使用TableView作为根级父级),当父级的focusedProperty()更改为false(通过属性更改侦听器)时调用此方法。

答案 1 :(得分:5)

您可以通过场景的getFocusOwner()或focusOwnerProperty()获取当前关注的节点。正如您所说,从焦点节点到TableView的遍历更好。

    public void createTable() {
        TableView tableView = new TableView();
        tableView.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
            if (oldValue && !newValue) {
                if (!isParent(tableView, tableView.getScene().getFocusOwner())) {
                    System.out.println("Saving changes.");
                }
            }
        });
    }

    public boolean isParent(Parent parent, Node child) {
        if (child == null) {
            return false;
        }
        Parent curr = child.getParent();
        while (curr != null) {
            if (curr == parent) {
                return true;
            }
            curr = curr.getParent();
        }
        return false;
    }