2016-10-12 5 views
0

Привет Я застрял в ситуации, когда использовать связывание для 2 ползунков valuePropertySlider bindBidirectional

двунаправленной Задача: есть 2 ползунки каждый из них имеет максимальное значение 100 Но это значение делится между этими 2 ползунков, например, если вы перемещаете первый слайдер на значение 20, тогда второе значение ползунка должно быть 80 и наоборот.

Я знаю, что это должно быть сделано с привязкой двунаправленной, но как я могу привязать выражение к свойству?

slider1.valueProperty().bindBidirectional(slider2.getMax() - slider2.valueProperty()); ??? 

Любая помощь будет высоко оценена.

ответ

2

Вы не можете сделать это с обязательным двунаправленным: вам нужно использовать два слушателя:

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); 
    } 
} 
+0

Получил его. Спасибо James_D. – orioncs

+0

@orioncs Добро пожаловать. Проверьте обновление. –