JavaFX - 为什么多次向窗格添加节点或向不同的窗格添加节点会导致错误? [英] JavaFX - Why does adding a node to a pane multiple times or to different panes result in an error?

查看:177
本文介绍了JavaFX - 为什么多次向窗格添加节点或向不同的窗格添加节点会导致错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm learning basic JavaFX right now, and I don't understand this statement from the book I'm reading: "No, a node such as a text field can be added to only one pane and once. Adding a node to a pane multiple times or to different panes will cause a runtime error." I can see from the UML diagram the book provides that it is a composition, but I don't understand why (library class code implementation) that is.

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

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?

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

此外,为什么以下运行但不显示放置在窗格中的文本字段?

Also, why does the following run but not show the text field placed in 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是专门设计的。每个节点都有一组属性,包括属性( - 一个且只有一个 - 节点的父节点在场景图中),以及 layoutX layoutY 等属性,它们是与之相关的节点坐标它的父母。因此,节点只能属于一个父节点,并且只能添加到父节点一次(因为它只能在父节点中有一个位置)。以这种方式组织事物可以实现非常有效的布局过程。

This is basically a (deliberate) consequence of the way the API is designed. Each Node has a collection of properties, including a parent property (the - one and only one - parent of the node in the scene graph), along with properties such as layoutX and layoutY which are the coordinates of the node in relation to its parent. Consequently, a node can only belong to one parent, and can only be added to a parent once (as it can only have one location in the parent). Organizing things this way enables a very efficient layout process.

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

Another way to think of this: suppose your first code block did what you wanted; so the text field tf appeared twice in the flow pane. What result would you expect to get from tf.getBoundsInParent()? Since tf appears twice in the parent, the API would not be able to give a sensible value for this call.

您在问题中的陈述中有一些不准确之处:

There are a couple of inaccuracies in statements you make in your question:


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

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?

首先,从技术上讲,这是聚合而不是构图;虽然我不确定理解差异会帮助你理解目前发生的事情。

First, technically, this is aggregation, not composition; though I'm not sure understanding the difference will aid your understanding of what is happening at this point.

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

Second, there is no compile error here; you get an error at runtime (the pane detects that the same node has been added twice; the complier has no way to check this).

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

Third, parents do not instantiate copies of the nodes you add to them. If so, you wouldn't be able to change the properties of nodes that were displayed. For example, if the FlowPane in your example instantiated a new TextField when you called pane.getChildren().add(tf);, and then displayed that new text field, then if you subsequently called tf.setText("new text"), it would have no effect, as it would not be changing the text of the text field that pane was displaying.

当你调用 pane.getChildren()。add(...)时,你要传递一个你想要添加的节点的引用;然后,该节点将显示为窗格的子节点。任何其他实现都会产生相当反直觉的行为。

When you call pane.getChildren().add(...) you pass a reference to the node you want to be added; it is that node that is then displayed as a child of the pane. Any other implementation would produce pretty counter-intuitive behavior.

在你的第二个代码块中:

In your second code block:

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

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

the second call implicitly sets the parent property of tf to pane2; consequently tf is no longer a child of pane. So this code has the effect of removing tf from the first parent, pane. As far as I am aware, this side-effect is not documented, so you probably should avoid writing code like this.

这篇关于JavaFX - 为什么多次向窗格添加节点或向不同的窗格添加节点会导致错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆