作者:广东暖暖_小乖 | 来源:互联网 | 2024-11-02 14:33
在Vbox和Hbox布局中,当用户点击容器添加一个矩形时,系统会自动为该矩形分配坐标并打印其位置信息。此外,在按键事件触发时,系统仅打印当前矩形的坐标值。这两种布局在特定的交互场景下,能够动态地管理和更新子组件的位置。
I put rectangle on a vbox on click and I print coordinate of the rectangle. On key pressed I only print the coordinate. Look at this sample code example :
我点击vbox上的矩形,我打印矩形的坐标。按下键时我只打印坐标。看看这个示例代码示例:
@FXML
private VBox vbox;
@FXML
private AnchorPane anchorpane;
private List rectangles = new ArrayList<>();
@Override
public void initialize(URL location, ResourceBundle resources) {
System.out.println("init");
}
@FXML
private void onMouseClick(MouseEvent e) {
System.out.println("click");
vbox.getChildren().clear();
for(int i = 0; i <3 ; i++){
Rectangle r = new Rectangle(100.0, 10.0, Color.BLACK);
r.addEventHandler(KeyEvent.ANY, this::onKeyTyped);
rectangles.add(r);
vbox.getChildren().add(r);
System.out.println(" r Yposition :" + r.getLayoutY() + " or " + r.getBoundsInParent().getMinY() + " or " + r.getBoundsInLocal().getMinY());
System.out.println("Vbox height : " + vbox.getBoundsInLocal().getHeight());
}
}
@FXML
private void onKeyTyped(KeyEvent e) {
System.out.println("Key pressed");
for (Rectangle r : rectangles){
System.out.println(" r Yposition :" + r.getLayoutY() + " or " + r.getBoundsInParent().getMinY() + " or " + r.getBoundsInLocal().getMinY());
}
System.out.println("Vbox height : " + vbox.getBoundsInLocal().getHeight());
}
This give me the following output :
这给了我以下输出:
click
r Yposition :0.0 or 0.0 or 0.0
Vbox height : 10.0
r Yposition :0.0 or 0.0 or 0.0
Vbox height : 10.0
r Yposition :0.0 or 0.0 or 0.0
Vbox height : 10.0
Key pressed
r Yposition :0.0 or 0.0 or 0.0
r Yposition :10.0 or 10.0 or 0.0
r Yposition :20.0 or 20.0 or 0.0
Vbox height : 30.0
So I suppose JavaFX assign coordinate of the shape when it prints it on the screen. But how can I have the coordinate of the shape in the Vbox when I refresh it ?
所以我想JavaFX在屏幕上打印时会分配形状的坐标。但是当我刷新它时,如何在Vbox中获得形状的坐标?
1 个解决方案
After you add the rectangles to the VBox
, if you call inmediately to getBoundsInParent()
you get no results.
将矩形添加到VBox后,如果您立即调用getBoundsInParent(),则不会得到任何结果。
The reason for this can be found here:
原因可以在这里找到:
Layout and CSS are also tied to pulse events. Numerous changes in the scene graph could lead to multiple layout or CSS updates, which could seriously degrade performance. The system automatically performs a CSS and layout pass once per pulse to avoid performance degradation. Application developers can also manually trigger layout passes as needed to take measurements prior to a pulse.
布局和CSS也与脉冲事件有关。场景图中的大量更改可能导致多个布局或CSS更新,这可能会严重降低性能。系统每个脉冲自动执行一次CSS和布局传递,以避免性能下降。应用程序开发人员还可以根据需要手动触发布局过程,以便在脉冲之前进行测量。
So if you really need the bounds of those rectangles in the same pass, you can call:
因此,如果你真的需要在同一个传递中的那些矩形的边界,你可以调用:
vbox.layout();
right after adding each rectangle to the box to get its final position.
在将每个矩形添加到框中以获得其最终位置之后。
According to Javadoc, layout()
:
根据Javadoc,layout():
Executes a top-down layout pass on the scene graph under this parent. Calling this method while the Parent is doing layout is a no-op
在此父级下的场景图上执行自上而下的布局传递。在Parent进行布局时调用此方法是一种无操作
And now this will work as you would expected:
现在,这将按照您的预期运作:
for(int i = 0; i <3 ; i++){
Rectangle r = new Rectangle(100.0, 10.0, Color.BLACK);
rectangles.add(r);
vbox.getChildren().add(r);
vbox.layout();
System.out.println(" r Yposition :" + r.getLayoutY() + " or " + r.getBoundsInParent().getMinY() + " or " + r.getBoundsInLocal().getMinY());
System.out.println("Vbox height : " + vbox.getBoundsInLocal().getHeight());
}
Alternatively, you could override the layoutChildren()
method of vbox
, as it is invoked during the layout pass to layout the children in this parent:
或者,您可以覆盖vbox的layoutChildren()方法,因为在布局传递期间调用它来布局此父级中的子级:
private VBox vbox=new VBox(){
@Override
protected void layoutChildren() {
super.layoutChildren();
for (Rectangle r : rectangles){
System.out.println(" r Yposition :" + r.getLayoutY() + " or " + r.getBoundsInParent().getMinY() + " or " + r.getBoundsInLocal().getMinY());
}
}
};
It will give you the same result. Note that this won't work with vbox
added to the FXML file, since you need to create a new instance of it.
它会给你相同的结果。请注意,这不适用于添加到FXML文件的vbox,因为您需要创建它的新实例。