在 JavaFX 中显式定位节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21118394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Explicitly positioning nodes in JavaFX
提问by oskarko
When I have clicked a button, it changes its position.
当我点击一个按钮时,它会改变它的位置。
But when I move the mouse, the button comes back to the center of the scene, why?
但是当我移动鼠标时,按钮又回到了场景的中心,为什么?
I have the following code:
我有以下代码:
public class HolaMundo extends Application {
Button btn;
Scene scene;
@Override
public void start(Stage primaryStage) {
btn = new Button();
btn.setText("Hola Mundo");
StackPane root = new StackPane();
root.getChildren().add(btn);
scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
scene.setOnMouseMoved(new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent t) {
btn.setText(String.valueOf(t.getX() ));
}
});
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
btn.setLayoutX(Math.random() * (300 - btn.getWidth()));
btn.setLayoutY(Math.random() * (250 - btn.getHeight()));
}
});
}
public static void main(String[] args) {
launch(args);
}
}
采纳答案by jewelsea
Suggested approach
建议的方法
For your particular code snippet, perhaps using a Paneinstead of a StackPaneis the best approach.
对于您的特定代码片段,也许使用Pane而不是StackPane是最好的方法。
Why your code doesn't do what you want
为什么你的代码没有做你想要的
If you are going to manually set layout values, don't use a layout pane (such as a StackPane) which automatically sets layout values for you. If you use a layout pane, then the layout values you explicitly set will be overridden automatically the next time layout pane performs a layout pass (e.g. it is resized or some its content or location in the scene graph becomes dirty).
如果您要手动设置布局值,请不要使用自动为您设置布局值的布局窗格(例如 StackPane)。如果您使用布局窗格,那么您明确设置的布局值将在下次布局窗格执行布局过程时自动覆盖(例如,调整大小或场景图中的某些内容或位置变脏)。
Options for explicitly laying out nodes
显式布置节点的选项
If you want to explicitly layout items in JavaFX do one of the following:
如果要在 JavaFX 中显式布局项目,请执行以下操作之一:
- Subclass Regionand override layoutChildren.
- Place your content in a Paneif you need the container to be styled with CSS or implement resizing functions.
- Place your content in a Groupif you don't need the container to be styled with CSS or implement resizing functions.
- 子类Region并覆盖layoutChildren。
- 如果您需要使用 CSS 对容器进行样式设置或实现大小调整功能,请将您的内容放在窗格中。
- 如果您不需要使用 CSS 对容器进行样式设置或实现大小调整功能,请将您的内容放在一个组中。
Related advice on node positioning
节点定位相关建议
If you want to have automatically laid out components using the predefined layout managers but you want to adjust or temporarily modify the locations of some of the components from their default positions, you can adjust the translateX/Y values rather than layoutX/Y values. According to the definition of translateX:
如果您想使用预定义的布局管理器自动布局组件,但又想从默认位置调整或临时修改某些组件的位置,您可以调整 translateX/Y 值而不是 layoutX/Y 值。根据translateX的定义:
The node's final translation will be computed as layoutX + translateX, where layoutX establishes the node's stable position and translateX optionally makes dynamic adjustments to that position. This variable can be used to alter the location of a node without disturbing its layoutBounds, which makes it useful for animating a node's location.
节点的最终平移将计算为 layoutX + translateX,其中 layoutX 建立节点的稳定位置,而 translateX 可选择对该位置进行动态调整。此变量可用于更改节点的位置,而不会干扰其 layoutBounds,这使其可用于为节点的位置设置动画。
This means that the layout manager can compute a child's default position using layoutX
, and you can adjust the position from the default using translateX
.
这意味着布局管理器可以使用 计算孩子的默认位置layoutX
,您可以使用 调整默认位置translateX
。
回答by Rupert
Not having deeply investigated the current case, I see a difference when I use an AnchorPane instead of the StackPane to place the Button on.
没有深入调查当前案例,当我使用 AnchorPane 而不是 StackPane 来放置按钮时,我看到了不同之处。
By changing the label text of the Button by the mouseMoved-Event the Pane is rendered (layout is requested). With a StackPane placing all it's children in the center of itself the Button's position is reset to the center of the Pane. When you have a look into the layoutChildren method of StackPane you'll see a call to resizeRelocate. So layoutX and layoutY are reset and the button moves back to the center position (or whatever you set the alignment of the StackPane to).
通过使用 mouseMoved-Event 更改 Button 的标签文本,将呈现 Pane(请求布局)。使用 StackPane 将其所有子项放置在其自身的中心,按钮的位置将重置为窗格的中心。当您查看 StackPane 的 layoutChildren 方法时,您会看到对 resizeRelocate 的调用。因此 layoutX 和 layoutY 被重置,按钮移回中心位置(或任何您将 StackPane 的对齐设置为)。
So I think this is a correct behavior of the StackPane and I recommend to use another Pane, e.g. AnchorPane.
所以我认为这是 StackPane 的正确行为,我建议使用另一个 Pane,例如 AnchorPane。