JavaFX节点的自定义布局
问题描述:
我正在开发一个应用程序,它需要互相排列节点(或彼此之间等)。但是,这种布局只是初始位置,用户可以任意移动这些节点。这是如何在JavaFX中以正确的方式完成的?我将用一个简化的例子来解释我的问题: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());
}
}
答
给出的例子从上面,如果我设置该级的场景为空,然后重新设置,按钮宽度将调用的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());
}
您可以创建'Pane'的子类并覆盖'layoutChildren()'。但是,我并不真正了解“这种布局只是初始布局,用户可以随意移动这些节点”。当用户移动节点时,你应该改变'layoutChildren()'方法所要求的一些属性,这样它就可以正确地定位子节点。 – 2014-10-08 19:22:28
简化,如果用户移动节点我使用节点的方法重定位(posX,posY)。该应用程序类似于图形编辑器。用户可以根据自己的意愿布置显示的节点。因此,我正在使用一个正常的窗格,而不是像GridPane等。 – user3740372 2014-10-08 20:39:15
@James_D我假设在JavaFX调用layoutChildren()方法时给定示例中的宽度将被正确设置?所以这个想法是在任意位置创建rect2,然后将其移动到layoutChildren()中的所需位置。我可以看到这个工作,并会试一试。 – user3740372 2014-10-08 21:04:43