我使用JavaFX新发布的Java 8版本。
我写了这个小测试程序来模拟我的问题。
public class Main extends Application{
DoubleProperty widthProperty;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage){
HBox root = new HBox();
HBox root2 = new HBox();
HBox root3 = new HBox();
Scene scene = new Scene(root, 1200, 800);
primaryStage.setScene(scene);
primaryStage.show();
widthProperty = new SimpleDoubleProperty(400);
root2.setPrefSize(400, 400);
root3.setPrefHeight(400);
root3.prefWidthProperty().bind(widthProperty);
root2.setStyle("-fx-background-color: green");
root3.setStyle("-fx-background-color: red");
root2.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
root2.setMinWidth(600);
}
});
root2.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
Platform.runLater(new Runnable() {
@Override
public void run() {
widthProperty.set((Double) newValue);
}
});
//widthProperty.set((Double) newValue);
}
});
root.getChildren().addAll(root2, root3);
}
}
所以会发生什么,如果我点击root2,它的宽度会改变。 changelistener识别它并将widthproperty设置为root2的宽度。 widthproperty绑定到root3宽度。所以现在也应该改变root3的宽度。
但问题是,我必须在root2上点击两次。只有在第二次单击后,才会更新GUI。如果我使用Platform.runlater,GUI会在第一次点击后及时更新。
答案 0 :(得分:0)
您正在更改鼠标单击事件的root2的minWidth
,但是您要在更改root2的widthProperty
时设置widthProperty变量。 minWidthProperty
和widthProperty
是两个不同的属性,但widthProperty是readonly属性,不能由应用程序设置。它将由布局过程(窗口大小调整等)的父节点控制,其中包括宽度的最小值,最大值和首选值。所以改为将侦听器添加到minWidthProperty:
root2.minWidthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, final Number newValue) {
widthProperty.set((Double) newValue);
}
});
那么为什么它与Platform.runLater一起使用?
目前我无法给你一个具体的解释,因为我们没有深入观察JavaFX的系统架构。但原因在于FPS机制,应用程序线程和JavaFX的渲染器。也就是说,widthProperty的值更改事件可能不会陷入相同的时钟周期&#34; of minWidthProperty。