在JavaFX中明确定位节点

时间:2014-01-14 16:17:59

标签: java events netbeans javafx mouse

当我点击一个按钮时,它会改变它的位置。

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

我有以下代码:

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

2 个答案:

答案 0 :(得分:17)

建议的方法

对于您的特定代码段,可能使用Pane代替StackPane是最好的方法。

为什么您的代码无法执行您想要的操作

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

明确布置节点的选项

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

  1. 子类Region并覆盖layoutChildren
  2. 如果您需要使用CSS设置容器或实现调整大小功能,请将内容放在Pane中。
  3. 如果您不需要使用CSS设置容器或实现调整大小功能,请将内容放在Group中。
  4. 关于节点定位的相关建议

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

      

    节点的最终转换将计算为layoutX + translateX,其中layoutX建立节点的稳定位置,translateX可选择对该位置进行动态调整。   此变量可用于更改节点的位置而不会干扰其layoutBounds,这使得它可用于动画节点的位置。

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

答案 1 :(得分:0)

我没有深入调查当前的情况,当我使用AnchorPane而不是StackPane来放置Button时,我看到了一个区别。

通过mouseMoved-Event更改Button的标签文本,将呈现Pane(请求布局)。使用StackPane将其所有子项放在其自身的中心时,Button的位置将重置为窗格的中心。当您查看StackPane的layoutChildren方法时,您将看到对resizeRelocate的调用。因此,layoutX和layoutY被重置,按钮移回中心位置(或者设置StackPane对齐的任何位置)。

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