JavaFX Beans Binding suddenly stops working

主宰稳场 提交于 2019-11-27 02:05:53

The binding uses a WeakListener to observe the value of currentWidthPlusTen. Since you don't keep a reference to the boundNumberProperty, it is eligible for garbage collection as soon as the start(...) method exits. When the garbage collector kicks in, the reference is lost entirely and the binding no longer works.

To see this directly, add the line

root.setOnMousePressed( event -> System.gc());

to the start(...) method. You can force the listener to "stop working" by clicking on the window.

Obviously, that's not what you want: the fix is to retain the reference to boundNumberProperty after start(...) exits. For example:

import javafx.application.Application;
import javafx.beans.binding.NumberBinding;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class BindingsProblem extends Application {

    IntegerProperty boundNumberProperty;

    @Override
    public void start(Stage primaryStage) {
        // Initialization...
        StackPane root = new StackPane();
        Scene scene = new Scene(root, 300, 250);
        primaryStage.setScene(scene);
        primaryStage.show();

        // Binding - The problem occurrs here!
        NumberBinding currentWidthPlusTen = primaryStage.widthProperty()
                .add(10);

        boundNumberProperty = new SimpleIntegerProperty();
        boundNumberProperty.bind(currentWidthPlusTen);
        boundNumberProperty.addListener(new ChangeListener<Number>() {

            @Override
            public void changed(ObservableValue<? extends Number> observable,
                    Number oldValue, Number newValue) {
                System.out.println(newValue.toString());
            }

        });

    }

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

}

Update

Anyone running into this issue might also want to look at Tomas Mikula's ReactFX, which provides a cleaner workaround for this (at the expense of using a third-party library, which you would need to spend some time learning). Tomas explains this issue and how ReactFX resolves it in this blog and the subsequent post.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!