2014-10-08 111 views
0

我正在开发一个应用程序,它需要互相排列节点(或彼此之间等)。但是,这种布局只是初始位置,用户可以任意移动这些节点。这是如何在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()); 
} 

} 
+0

您可以创建'Pane'的子类并覆盖'layoutChildren()'。但是,我并不真正了解“这种布局只是初始布局,用户可以随意移动这些节点”。当用户移动节点时,你应该改变'layoutChildren()'方法所要求的一些属性,这样它就可以正确地定位子节点。 – 2014-10-08 19:22:28

+0

简化,如果用户移动节点我使用节点的方法重定位(posX,posY)。该应用程序类似于图形编辑器。用户可以根据自己的意愿布置显示的节点。因此,我正在使用一个正常的窗格,而不是像GridPane等。 – user3740372 2014-10-08 20:39:15

+0

@James_D我假设在JavaFX调用layoutChildren()方法时给定示例中的宽度将被正确设置?所以这个想法是在任意位置创建rect2,然后将其移动到layoutChildren()中的所需位置。我可以看到这个工作,并会试一试。 – user3740372 2014-10-08 21:04:43

回答

0

给出的例子从上面,如果我设置该级的场景为空,然后重新设置,按钮宽度将调用的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()); 
}