gpt4 book ai didi

JavaFX - 为什么将节点多次添加到一个 Pane 或添加到不同的 Pane 会导致错误?

转载 作者:搜寻专家 更新时间:2023-11-01 02:43:40 31 4
gpt4 key购买 nike

我现在正在学习基本的 JavaFX,我不明白我正在阅读的书中的这句话:“不,像文本字段这样的节点只能添加到一个 Pane 中一次。添加一个节点多次或不同的 Pane 将导致运行时错误。”从书上提供的UML图可以看出它是一个组合,但我不明白为什么(库类代码实现)是这样。

例如,为什么会导致编译错误?因为它是一个组合,所以不是在 Pane 中实例化了一个新的文本字段吗?

FlowPane pane = new FlowPane();
StackPane pane2 = new StackPane();
TextField tf = new TextField();
pane.getChildren().add(tf);
pane.getChildren().add(tf);

另外,为什么下面运行但不显示放置在 Pane 中的文本字段?

FlowPane pane = new FlowPane();
StackPane pane2 = new StackPane();
TextField tf = new TextField();
pane.getChildren().add(tf);
pane2.getChildren().add(tf);

primaryStage.setScene(new Scene(pane));
primaryStage.show();

最佳答案

这基本上是 API 设计方式的(故意的)结果。每个 Node 都有一组属性,包括 parent 属性(场景图中节点的唯一父级),以及诸如 layoutXlayoutY 是节点相对于其父节点的坐标。因此,一个节点只能属于一个父节点,并且只能添加到父节点一次(因为它在父节点中只能有一个位置)。以这种方式组织事物可以实现非常高效的布局过程。

另一种思考方式:假设您的第一个代码块完成了您想要的;所以文本字段 tf 在流程 Pane 中出现了两次。您希望从 tf.getBoundsInParent() 获得什么结果?由于 tf 在父级中出现两次,API 将无法为此调用提供合理的值。

您在问题中的陈述有几处不准确:

For instance, why does this result in a compile error? Isn't a new text field instantiated within the pane since it's a composition?

首先,从技术上讲,这是聚合,而不是组合;尽管我不确定理解差异是否有助于您理解此时发生的事情。

其次,这里没有编译错误;您在运行时遇到错误( Pane 检测到相同的节点 已被添加两次;编译器无法检查这一点)。

第三,父级不会实例化您添加到它们的节点的副本。如果是这样,您将无法更改显示的节点的属性。例如,如果您的示例中的 FlowPane 在您调用 pane.getChildren().add(tf); 时实例化了一个新的 TextField,并且然后显示新的文本字段,然后如果您随后调用 tf.setText("new text"),它不会有任何效果,因为它不会更改 Pane 正在显示。

当您调用 pane.getChildren().add(...) 时,您传递了对要添加的节点的引用;正是该节点随后显示为 Pane 的子节点。任何其他实现都会产生非常违反直觉的行为。

在你的第二个代码块中:

pane.getChildren().add(tf);
pane2.getChildren().add(tf);

第二次调用隐式地将tfparent属性设置为pane2;因此 tf 不再是 pane 的子项。所以这段代码具有从第一个父级 pane 中删除 tf 的效果。据我所知,没有记录这种副作用,因此您可能应该避免编写这样的代码。

关于JavaFX - 为什么将节点多次添加到一个 Pane 或添加到不同的 Pane 会导致错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27696414/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com