嗨,我被困在使用2个滑块valueProperty双向绑定的情况下
任务是:有两个滑块,每个滑块都有最大值100,但是这个值在这两个滑块之间分配,例如,如果你将第一个滑块移动到值20,那么第二个滑块的值必须是80,反之亦然。
我知道这应该使用bind bidirectional来完成,但是我如何将表达式绑定到属性?
slider1.valueProperty().bindBidirectional(slider2.getMax() - slider2.valueProperty()); ???任何帮助都会得到高度评价。
发布于 2016-10-12 20:13:06
使用双向绑定不能做到这一点:你需要使用两个监听器:
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);
}
}https://stackoverflow.com/questions/39998192
复制相似问题