Two javafx Integer Spinners bound bidirectional: why is the binding unreliable?

旧时模样 提交于 2021-02-20 04:23:10

问题


I am trying to practice my binding. I want to make a window with two spinners and just get them to show the same value.

The problem is that the binding is unreliable: the spinners seem to stop updating each other if they are clicked too fast. Both spinners still respond to clicking, and clicks are counted correctly on the spinner being clicked, but the other spinner stops updating and never recovers. And it doesn’t have to be very fast clicking at all to cause it.

My code is based on this answer (currently scoring 8) showing how to bind a spinner to an IntegerProperty. That answer is enough to produce the behaviour I am struggling with, but I followed the brief discussion that ensued under that answer. It has other options shown and resources linked, including a hint to use .asObject() and strong references.

I am on oracle jdk 1.8.0_251, only because I was unable to get javaFX going under other JDKs I’ve tried. If it matters I am in eclipse 2019-12 on linux. Also, the spinners don't update each other at all in Debug mode, but they work (to start with) if I Run my code.

Why does it happen? My guesses are:

  1. I'm still suffering from garbage collection etc
  2. Something isn't keeping up with the fast clicking: my laptop's hardware, the linux OS, Eclipse, my jdk, javafx?

Can I somehow protect my code from this? Can I limit the clicking so that the spinner clicked only reacts to clicks if they are slow enough to keep the binding?

Please let me know if the behaviour described is unclear and I will upload a screen recording to youtube or something.

public class BindTwoSpinners extends Application {

@Override
public void start(Stage primaryStage) throws IOException {
    
    // Set up the topSpinner
    Spinner<Integer> topSpinner = new Spinner<Integer> (1,12,1);
    topSpinner.setEditable(true);
    ObjectProperty<Integer> topObjectProp = new SimpleObjectProperty<>(1);
    IntegerProperty topIntegerProperty = IntegerProperty.integerProperty(topObjectProp);
    topSpinner.getValueFactory().valueProperty().bindBidirectional(topObjectProp);
    
    // Set up the bottomSpinner
    Spinner<Integer> bottomSpinner = new Spinner<Integer> (1,12,1);
    bottomSpinner.setEditable(true);
    ObjectProperty<Integer> bottomObjectProp = new SimpleObjectProperty<>(1);
    IntegerProperty bottomIntegerProperty = IntegerProperty.integerProperty(bottomObjectProp);
    bottomSpinner.getValueFactory().valueProperty().bindBidirectional(bottomObjectProp);         

    // Need to keep the reference as bidirectional binding uses weak references
    // https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/IntegerProperty.html#bindBidirectional-javafx.beans.property.Property-

    ObjectProperty<Integer> topIntegerPropertyAsObject = topIntegerProperty.asObject();
    ObjectProperty<Integer> bottomIntegerPropertyAsObject = bottomIntegerProperty.asObject();

    // Bind the two spinners
    bottomSpinner.getValueFactory().valueProperty(). bindBidirectional(topIntegerPropertyAsObject);

    VBox root = new VBox(10, topSpinner, bottomSpinner);
    root.setAlignment(Pos.CENTER);
    primaryStage.setScene(new Scene(root));
    primaryStage.show();
}

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

来源:https://stackoverflow.com/questions/65462905/two-javafx-integer-spinners-bound-bidirectional-why-is-the-binding-unreliable

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