JavaFX bean binding suddenly stops working

I use JavaFX numberbindings to calculate certain values At first, everything worked as expected However, after a fairly short time, the binding just stops working I didn't get any exceptions either

I tried several bindings, as well as high - and low - level methods Even if the calculation itself (when overridden) just stops and is no longer called I also updated to the latest JDK (1.8.0_05) and rebuilt / restarted everything

The following minimum working example illustrates this problem System. out. Println sets the current width of the main window to stdout After adjusting the window for about 10 seconds, the output will stop I also tried to bind the result property to a JavaFX control to ensure that the property continues to be used, but it didn't help I believe I missed some very basic property / binding behavior here, which Google doesn't seem to know

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 {

@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);
    IntegerProperty 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);
}

}

Solution

The binding uses the weaklistener to observe the value of currentwidth plusten Since you do not retain a reference to boundnumberproperty, garbage collection can be used once the start (...) method exits When the garbage collector starts, the reference is completely lost and the binding is no longer valid

To view directly, add a row

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

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

Obviously, this is not what you want: the fix is to keep 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,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 newValue) {
                System.out.println(newValue.toString());
            }

        });

    }

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

}

to update

Anyone who encounters this problem may also want to see Tomas mikula's reactfx, which provides a cleaner solution (at the expense of using a third-party library, you need to spend some time learning) Tomas explained this problem and how reactfx solves it in this blog and subsequence post

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>