Вы не можете сделать это с обязательным двунаправленным: вам нужно использовать два слушателя:
slider1.valueProperty().addListener((obs, oldValue, newValue) ->
slider2.setValue(slider2.getMax() - newValue.doubleValue()));
slider2.valueProperty().addListener((obs, oldValue, newValue) ->
slider1.setValue(slider1.getMax() - newValue.doubleValue()));
SSCCE:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ConverselyBoundSliders extends Application {
@Override
public void start(Stage primaryStage) {
Slider slider1 = new Slider(0, 100, 50);
Slider slider2 = new Slider(0, 100, 50);
slider1.valueProperty().addListener((obs, oldValue, newValue) ->
slider2.setValue(slider2.getMax() - newValue.doubleValue()));
slider2.valueProperty().addListener((obs, oldValue, newValue) ->
slider1.setValue(slider1.getMax() - newValue.doubleValue()));
VBox root = new VBox(5, slider1, slider2);
root.setPadding(new Insets(12));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Это, кажется, хорошо работать без каких-либо бесконечной рекурсии происходящего; однако, поскольку он включает арифметику с плавающей запятой и сравнения, чтобы это было правдой, вы можете убедиться, что ошибки округления в вычислении slider.getMax() - newValue.doubleValue()
не заканчиваются тем, что каждый слушатель вызывает другой, не выходя из рекурсии. Следующим является пуленепробиваемый способ сделать это:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ConverselyBoundSliders extends Application {
@Override
public void start(Stage primaryStage) {
Slider slider1 = new Slider(0, 100, 50);
Slider slider2 = new Slider(0, 100, 50);
new ConverseSliderBinding(slider1, slider2);
VBox root = new VBox(5, slider1, slider2);
root.setPadding(new Insets(12));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
private static class ConverseSliderBinding {
private ChangeListener<Number> listener1 ;
private ChangeListener<Number> listener2 ;
private final Slider slider1 ;
private final Slider slider2 ;
private boolean adjusting ;
public ConverseSliderBinding(Slider slider1, Slider slider2) {
this.slider1 = slider1 ;
this.slider2 = slider2 ;
listener1 = (obs, oldValue, newValue) -> {
if (adjusting) return ;
adjusting = true ;
slider2.setValue(slider2.getMax() - newValue.doubleValue());
adjusting = false ;
};
listener2 = (obs, oldValue, newValue) -> {
if (adjusting) return ;
adjusting = true ;
slider1.setValue(slider1.getMax() - newValue.doubleValue());
adjusting = false ;
};
slider1.valueProperty().addListener(listener1);
slider2.valueProperty().addListener(listener2);
}
public void dispose() {
slider1.valueProperty().removeListener(listener1);
slider2.valueProperty().removeListener(listener2);
}
}
public static void main(String[] args) {
launch(args);
}
}
Получил его. Спасибо James_D. – orioncs
@orioncs Добро пожаловать. Проверьте обновление. –