在JavaFX中显式定位节点



单击按钮后,它会更改位置。

但是当我移动鼠标时,按钮会回到场景的中心,为什么?

我有以下代码:

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);
}
}

建议的方法

对于您的特定代码段,也许使用Pane而不是StackPane是最好的方法。

为什么您的代码不能执行您想要的操作

如果要手动设置布局值,请不要使用自动为您设置布局值的布局窗格(如StackPane)。如果使用布局窗格,则在下一次布局窗格执行布局过程时,显式设置的布局值将自动覆盖(例如,调整其大小或其在场景图中的某些内容或位置变脏)。

显式布置节点的选项

如果您想在JavaFX中显式布局项目,请执行以下操作之一:

  1. 子类区域和覆盖layoutChildren
  2. 如果需要使用CSS设置容器样式或实现调整大小功能,请将内容放在窗格中
  3. 如果您不需要使用CSS设置容器样式或实现调整大小功能,请将您的内容放在一个组中

节点定位的相关建议

如果要使用预定义的布局管理器自动布置零部件,但要从默认位置调整或临时修改某些零部件的位置,则可以调整translateX/Y值,而不是layoutX/Y值。根据translateX的定义:

节点的最终平移将计算为layoutX+translateX,其中layoutX建立节点的稳定位置,translateX可选择对该位置进行动态调整。此变量可用于更改节点的位置,而不会干扰其布局边界,这对于设置节点位置的动画非常有用。

这意味着布局管理器可以使用layoutX计算子级的默认位置,您可以使用translateX从默认位置调整位置。

由于没有深入调查当前案例,当我使用AnchorPane而不是StackPane来放置按钮时,我看到了不同。

通过鼠标移动事件更改按钮的标签文本,可以呈现窗格(请求布局)。当StackPane将其所有子项放置在其自身的中心时,按钮的位置将重置为窗格的中心。当你查看StackPane的layoutChildren方法时,你会看到一个对resizeRelocate的调用。因此,layoutX和layoutY将重置,按钮将移回中心位置(或您将StackPane的对齐方式设置为的任何位置)。

所以我认为这是StackPane的正确行为,我建议使用另一个窗格,例如AnchorPane。

最新更新