【问题标题】:JavaFX custom layout of nodes [duplicate]节点的JavaFX自定义布局[重复]
【发布时间】:2014-12-03 08:26:11
【问题描述】:

我正在开发一个应用程序,需要将节点布置在彼此旁边(或彼此之上等)。然而,这种布局只是一个初始布局,用户可以任意移动这些节点。这是如何在 JavaFX 中以正确的方式完成的?我将用一个简化的例子来解释我的问题:

假设我有 2 个矩形,并且想将 rect2 放在 rect1 的右侧。

// create first rectangle at position x= 5, y=5
rect1 = rectangle(5,5);
// create second rectangle to the right of rect1
rect2 = rectangle(5+rect1.width(), 5); 

在这种情况下,JavaFX 尚未确定 rect1 的宽度,它将为零。直观地说,我会执行一个调用,让 JavaFX 绘制 rect1,从而确定它的宽度,然后添加 rect2。请参阅以下示例:

// create first rectangle at position x= 5, y=5
rect1 = rectangle(5,5);
// let JavaFX draw rect1 (width will be calculated and set)
draw();
// create second rectangle to the right of rect1
rect2 = rectangle(5+rect1.width(), 5);

不幸的是,我还没有找到一种方法可以满足我的要求。我当前的解决方法使用 Platform.runLater() 但这并不总是正常工作。如果我对绑定的理解是正确的,那么绑定也不适合这个问题。我只想对节点进行初始布局,所以我必须在初始布局之后删除绑定(否则如果 rect1 被移动,rect2 会移动)。

提前感谢您的帮助。

编辑:这是一个最小的工作示例。按钮的宽度为 0。我尝试调用 root.layout() 来强制布局传递等,但它似乎不起作用。

public class Test extends Application {

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage primaryStage) {
    Button btn = new Button();
    StackPane root = new StackPane();
    Scene scene = new Scene(root, 300, 250);
    primaryStage.setScene(scene);
    primaryStage.show();
    btn.setText("Say 'Hello World'");
    root.getChildren().add(btn);

    // prints out 0
    System.out.println(btn.getWidth());
}

}

【问题讨论】:

  • 您可以创建Pane 的子类并覆盖layoutChildren()。但是,我真的不明白“这个布局只是一个初始放置,用户可以任意移动这些节点”。当用户移动节点时,您应该更改layoutChildren() 方法将遵循的一些属性,以便它始终正确定位子节点。
  • 简化,如果用户移动节点,我使用节点的方法 relocate(posX, posY)。该应用程序类似于图形编辑器。用户可以按照自己的意愿布局显示的节点。因此,我正在使用普通窗格而不是像 GridPane 等。
  • @James_D 我假设当 JavaFX 调用 layoutChildren() 方法时,给定示例中的宽度将正确设置?所以想法是在任意位置创建 rect2,然后将其移动到 layoutChildren() 中的所需位置。我可以看到这个工作,并会试一试。
  • @jewelsea applyCss() 和 layout() 完全符合我的要求。非常感谢。我对 stackoverflow 和 Oracle JavaFX 论坛有点陌生,很抱歉没有引用交叉帖子。此外,如果出现重复问题,我应该接受答案吗?您已将您的答案与另一篇 stackoverflow 帖子相关联,我有什么办法可以接受它作为答案吗?

标签: layout javafx javafx-2 javafx-8


【解决方案1】:

鉴于上面的例子,如果我将舞台的场景设置为空然后重置它,调用 System.out.println() 时将正确设置按钮宽度。似乎这迫使整个舞台上的布局传递?然而,这似乎只是另一种解决方法,特别是我有性能问题。

@Override
public void start(Stage primaryStage) {
    Button btn = new Button();
    StackPane root = new StackPane();
    Scene scene = new Scene(root, 300, 250);
    primaryStage.setScene(scene);
    primaryStage.show();
    btn.setText("Say 'Hello World'");
    root.getChildren().add(btn);

    // reset scene
    primaryStage.setScene(null);
    primaryStage.setScene(scene);

    // prints out 107.0
    System.out.println(btn.getWidth());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 2011-07-02
    • 1970-01-01
    相关资源
    最近更新 更多