2014-12-29 50 views
2

我正在学习基本的JavaFX,而且我不明白这本书的读法:“不,可以将节点(如文本字段)仅添加到一个窗格中,也可以添加一次。多次添加到窗格或添加到不同的窗格将导致运行时错误。“我从UML图中可以看出,本书规定它是一个组合,但我不明白为什么(库类代码实现)是。JavaFX - 为什么将节点多次添加到窗格或添加到不同窗格会导致错误?

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

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

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

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(); 
+1

该声明来自哪里?有些上下文会很有用。 –

+0

它来自教科书 – Hyde

+0

您可以查看JavaFX源代码并找出原因。 –

回答

0

试试这个:

TextField tf = new TextField(); 
TextField tf2 = new TextField(); 
pane.getChildren().add(tf); 
pane.getChildren().add(tf2); 

的原因,你不能添加同一节点两次是,只有一个具有相同规格和尺寸节点可以在GUI中查看。这就像将相同的蓝色圆圈复制到原始的蓝色圆圈上。对用户来说,它看起来是一样的,但它占用更多的内存。

2

这是基本的API设计方式的(故意)的后果。每个Node具有属性的集合,包括parent属性(在 - 一个且仅一个 - 在场景图中的节点的父)中,用如layoutXlayoutY性质,这是节点的坐标相对于它的父沿。因此,节点只能属于一个父节点,并且只能添加到父节点(因为它只能在父节点中有一个位置)。以这种方式组织事物可以实现非常有效的布局过程。

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

有陈述了几个不准确的,你做你的问题:

举例来说,为什么会出现这种结果编译错误?是不是一个新的 文本字段在窗格中实例化,因为它是一个组合?

首先,在技术上,这是聚集,不组合物;尽管我不确定理解这些差异会有助于你理解在这一点上发生的事情。

其次,这里没有编译错误;在运行时出现错误(pane检测到相同的node已添加两次;编译器无法检查此问题)。

三,父母不要实例您添加到他们的节点的副本。如果是这样,您将无法更改显示的节点的属性。例如,如果在您的示例FlowPane实例化一个新的TextField当你叫pane.getChildren().add(tf);,然后显示的新文本字段,那么如果随后叫tf.setText("new text"),那就没有任何作用,因为它不会改变文本的文本pane正在显示的字段。

当您致电pane.getChildren().add(...)时,您传递了要添加的节点的引用;它就是那个节点,然后显示为窗格的子节点。任何其他的实现都会产生非常不直观的行为。

在你的第二个代码块:

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

第二个呼叫隐式设置的tfpane2parent财产;因此tf不再是pane的孩子。因此,此代码的作用是从第一个父项pane中删除tf。据我所知,这种副作用没有记录,所以你可能应该避免编写这样的代码。

相关问题