【问题标题】:Remove a node without knowing the parent (JavaFX)在不知道父节点的情况下删除节点(JavaFX)
【发布时间】:2016-07-15 10:33:30
【问题描述】:

我可以在不知道其父级的情况下从场景图中删除 Node 吗?

换句话说,我可以这样做吗?

@FXML private ToolBar toolBar;

@FXML
protected void handleCloseButtonAction(ActionEvent actionEvent) {
    toolBar.getParent().getChildrenUnmodifiable().remove(toolBar);

    actionEvent.consume();
}

如果我这样做,它会抛出一个java.lang.UnsupportedOperationException

【问题讨论】:

    标签: java javafx fxml


    【解决方案1】:

    你得到UnsupportedOperationException,因为Parent#getChildrenUnmodifiable返回一个只读列表:

    获取此 Parent 的子列表作为只读列表。

    如果你存储父容器的引用总是更好更安全,但理论上你可以通过(向下)将getParent()方法返回的Parent对象转换为父容器的类型。

    例如,如果将ToolBar 添加到VBox

    ((VBox) toolBar.getParent()).getChildren().remove(toolBar);
    

    或者,如果你想更通用一点,你可以在类型检查之后将返回的父级转换为Pane,因为这个类是 JavaFX 容器的超类,它允许在子级列表上进行修改:

    if (toolBar.getParent() instanceof Pane)   
        ((Pane) toolBar.getParent()).getChildren().remove(toolBar);
    

    不过,我还是建议存储父容器的引用,而不是遵循其中一种(或类似的)方法,因为这不是一个干净的方法,并且因为向下转换不是一个安全的解决方案(没有类型检查)。

    【讨论】:

    • 我从来没有遇到过必须查找 UI 树的特定元素的父级的情况,子组件的设计总是以一种避免这种情况的方式设计的。我希望我们能同意,这样的设计更好:) 我再次更新了第二部分,强调必须对两者进行检查(我很清楚,但答案具有误导性,你是对的)。哪种解决方案“更好”:保留参考或强制转换 - 我无法确定(对我来说,一个对你来说似乎如此)。也许这些 cmets 的答案将在未来帮助其他人解决这个问题(这是 SO 的目标,不是吗?:))
    • argg ...将其子项公开为可修改列表的父项是窗格(不是区域)-我的错,对不起。删除了我的 cmets,因为我同意你的观点,因为这样的要求不应该出现在中途理智的 ui 设计中:) 至少不会出现在 fx 中,因为它没有为节点提供任何通用的公共 api 来将自己从中删除它的父母 - 这是(很可能,不能肯定,显然)一个有意识的决定,所以用户应该一起玩......
    猜你喜欢
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2016-06-12
    • 2011-10-21
    相关资源
    最近更新 更多