JavaFX:GUI没有刷新

时间:2014-03-25 14:05:40

标签: binding javafx

我使用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会在第一次点击后及时更新。

1 个答案:

答案 0 :(得分:0)

您正在更改鼠标单击事件的root2的minWidth,但是您要在更改root2的widthProperty时设置widthProperty变量。 minWidthPropertywidthProperty是两个不同的属性,但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。