在 vbox 中有一个组时的奇怪行为

Strange behaviour when having a group in vbox

谁能解释一下为什么会出现这种奇怪的行为?当我在 vbox 中有一个组时,子项中的每个项目似乎都将兄弟姐妹修改为。

发生以下奇怪行为:

一切正常

这里也一切正常

糟糕,为什么搜索栏移动了???

我的应用程序的第一个结构:

root (VBox) //vbox so the menubar has its own space
├───menubar (MenuBar)
└───contentroot (Group)
    ├───searchbar (TextField) //searchbar should always be on the top left
    └───nodeRoot (Group)
        ├───circle1 (Nodes)
        └───circle2 (Nodes)

根是一个 vbox,所以菜单栏有它自己的未受挑战的 space。搜索栏应该总是在左上角,在菜单栏的正下方。 nodeRoot 应该包含所有其他节点。有点像画板,我应该可以拖来拖去。

代码:

public void start(Stage primaryStage) throws Exception{
    VBox root = new VBox();

    MenuBar menuBar = new MenuBar(new Menu("File"));
    Group contentRoot = new Group();
    contentRoot.getChildren().add(new TextField("SearchBar"));
    Group nodeRoot = new Group();
    contentRoot.getChildren().add(nodeRoot);

    root.getChildren().addAll(menuBar, contentRoot);

    Circle circle = new Circle(30, Color.RED);
    nodeRoot.getChildren().add(circle);

    Scene scene = new Scene(root, 300, 275);
    primaryStage.setScene(scene);
    primaryStage.show();

    scene.setOnMousePressed(event -> {
        circle.setTranslateX(event.getSceneX() - 15);
        circle.setTranslateY(event.getSceneY() - 15);
    });
}

我猜为什么会这样: 在我添加菜单栏并将所有内容放入 VBox 后,问题开始出现。这是 nodeRoot 的兄弟姐妹也发生变化的时候。我的猜测是,因为 VBox 是一个区域,所以行为不同于展开的普通组。但是后来我不明白为什么只有当项目移动到左侧或顶部时才会发生这种情况。

谁能解释一下为什么会这样,我该如何解决?

来自javadocs for Group

A Group will take on the collective bounds of its children and is not directly resizable.

当您在场景的顶部或左侧附近单击时,圆的边界包括负值。由于该组具有这些界限,因此它也具有负值。 TextField 从未设置任何布局边界,因此 Group 将其定位在 (0,0)。因此,文本字段可以位于圆圈的下方或右侧。 vbox 定位该组以尝试完全包含它,因此如果它包含负 x 值范围则将其右移,如果它包含负 y 值范围则将其下移。

如果您使用 Pane 来包含圆,而不是 Group:

Pane contentRoot = new Pane();

它的行为更直观:Pane 不接受其子节点边界的并集,因此如果圆有负边界,它只是向左 and/or 移动到窗格的上方可见区域。