有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java javafx微调器值侦听器导致无限循环

我有一个SimpleDoubleProperty双向绑定到微调器的应用程序,所有微调器都会交互,即当一个微调器发生更改时,需要执行计算来更改其余微调器

由于此设置,一个微调器上的值会使它们全部更改,然后调用它们的更改计算侦听器。这是来回的,因为每一个都在一个内循环中设置另一个

有没有办法在这里更新valueA、B或C,从而设置其他两个值,而不使其他值再次冲突

谢谢

import javafx.application.Application;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Scene;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class SpinnerBindDemo extends Application {
    SimpleDoubleProperty valueA = new SimpleDoubleProperty(100.0);
    SimpleDoubleProperty valueB = new SimpleDoubleProperty(55.5);
    SimpleDoubleProperty valueC = new SimpleDoubleProperty(41.0);

    @Override
    public void start(Stage stage) throws Exception {
        Spinner spinnerA = new Spinner();
        spinnerA.setValueFactory(new SpinnerValueFactory.DoubleSpinnerValueFactory(0.0, 999.9, valueA.get(), 0.1));
        spinnerA.getValueFactory().valueProperty().bindBidirectional(valueA);
        valueA.addListener((observable, oldValue, newValue) -> {
            valuesChanged("A", (double) newValue);
        });

        Spinner spinnerB = new Spinner();
        spinnerB.setValueFactory(new SpinnerValueFactory.DoubleSpinnerValueFactory(0.0, 999.9, valueB.get(), 0.1));
        spinnerB.getValueFactory().valueProperty().bindBidirectional(valueB);
        valueB.addListener((observable, oldValue, newValue) -> {
            valuesChanged("B", (double) newValue);
        });

        Spinner spinnerC = new Spinner();
        spinnerC.setValueFactory(new SpinnerValueFactory.DoubleSpinnerValueFactory(0.0, 999.9, valueC.get(), 0.1));
        spinnerC.getValueFactory().valueProperty().bindBidirectional(valueC);
        valueC.addListener((observable, oldValue, newValue) -> {
            valuesChanged("C", (double) newValue);
        });

        VBox root = new VBox();
        root.getChildren().add(spinnerA);
        root.getChildren().add(spinnerB);
        root.getChildren().add(spinnerC);

        Scene scene = new Scene(root, 200, 100);
        stage.setTitle("Demo");
        stage.setScene(scene);
        stage.show();
    }
    private void valuesChanged(String changedValue, double value){
        System.out.println("Value "+changedValue+" changed, calc "+value);
        if(changedValue.equals("A")){
            //some calc
            valueB.set(value - 33.3);
            valueC.set(value - 22.1);
        }else if(changedValue.equals("B")){
            //some calc
            valueA.set(value + 11);
            valueC.set(value + 12);

        }else if(changedValue.equals("C")){
            //some calc
            valueB.set(value - +15);
            valueA.set(value - 2.2);
        }
    }
    public static void main(String[] args){
        launch(args);
    }
}

共 (1) 个答案

  1. # 1 楼答案

    <> P>这并不完全清楚(对我来说)你试图在这里执行的逻辑,但是你可以考虑设置一个标志来指示正在进行的变化:

    public class SpinnerBindDemo extends Application {
    
        private boolean changing = false ;
    
        // ...
    
        private void valuesChanged(String changedValue, double value){
    
            if (changing) {
                return ;
            }
    
            changing = true ;
    
            System.out.println("Value "+changedValue+" changed, calc "+value);
            if(changedValue.equals("A")){
                //some calc
                valueB.set(value - 33.3);
                valueC.set(value - 22.1);
            }else if(changedValue.equals("B")){
                //some calc
                valueA.set(value + 11);
                valueC.set(value + 12);
    
            }else if(changedValue.equals("C")){
                //some calc
                valueB.set(value - +15);
                valueA.set(value - 2.2);
            }
    
            changing = false ;
        }
    }