Hyd*_*yde 5 java javafx javafx-2
我现在正在学习基本的 JavaFX,但我不明白我正在阅读的书中的这句话:“不,像文本字段这样的节点只能添加到一个窗格中一次。将节点添加到窗格多次或不同的窗格将导致运行时错误。” 我可以从书中提供的 UML 图中看到它是一个组合,但我不明白为什么(库类代码实现)是这样。
例如,为什么这会导致编译错误?不是在窗格中实例化了一个新的文本字段,因为它是一个组合吗?
FlowPane pane = new FlowPane();
StackPane pane2 = new StackPane();
TextField tf = new TextField();
pane.getChildren().add(tf);
pane.getChildren().add(tf);
Run Code Online (Sandbox Code Playgroud)
另外,为什么以下运行但不显示放置在窗格中的文本字段?
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();
Run Code Online (Sandbox Code Playgroud)
这基本上是 API 设计方式的(故意)结果。每个Node都有一组属性,包括一个parent属性(场景图中节点的唯一一个父节点),以及诸如layoutX和 之类的属性,layoutY它们是节点相对于其父节点的坐标。因此,一个节点只能属于一个父节点,并且只能添加到父节点一次(因为它在父节点中只能有一个位置)。以这种方式组织事物可以实现非常有效的布局过程。
另一种思考方式:假设你的第一个代码块做了你想要的;所以文本字段tf在流窗格中出现了两次。你希望得到什么结果tf.getBoundsInParent()?由于tf在父级中出现两次,API 将无法为此调用提供合理的值。
您在问题中的陈述有几个不准确之处:
例如,为什么这会导致编译错误?不是在窗格中实例化了一个新的文本字段,因为它是一个组合吗?
首先,从技术上讲,这是聚合,而不是组合;尽管我不确定理解差异是否有助于您了解此时正在发生的事情。
其次,这里没有编译错误;您在运行时收到错误(pane检测到相同的node已添加两次;编译器无法检查)。
第三,父节点不会实例化您添加到它们的节点的副本。如果是这样,您将无法更改显示的节点的属性。例如,如果FlowPane在您的示例中,TextField当您调用 时实例化了一个 new pane.getChildren().add(tf);,然后显示该新文本字段,那么如果您随后调用tf.setText("new text"),它将没有效果,因为它不会更改pane正在显示的文本字段的文本.
当您调用时,pane.getChildren().add(...)您会传递一个对要添加的节点的引用;该节点随后显示为窗格的子节点。任何其他实现都会产生非常违反直觉的行为。
在您的第二个代码块中:
pane.getChildren().add(tf);
pane2.getChildren().add(tf);
Run Code Online (Sandbox Code Playgroud)
第二个调用隐式地设置了to的parent属性;因此不再是 的孩子。所以这段代码具有从第一个父级中删除的效果,. 据我所知,这种副作用没有记录在案,因此您可能应该避免编写这样的代码。tfpane2tfpanetfpane
尝试这个:
TextField tf = new TextField();
TextField tf2 = new TextField();
pane.getChildren().add(tf);
pane.getChildren().add(tf2);
Run Code Online (Sandbox Code Playgroud)
同一节点不能添加两次的原因是,GUI 中只能看到一个具有相同规格和尺寸的节点。这就像将相同的蓝色圆圈复制到原始蓝色圆圈上。对于用户来说,它看起来是一样的,但它占用更多的内存。
| 归档时间: |
|
| 查看次数: |
6554 次 |
| 最近记录: |