Sun*_*ame 1 java binding javafx javafx-8
我想双向绑定两个DoubleProperty,但不是真正的1:1,例如以1:1.2的比例绑定。
我需要类似的东西:
DoubleProperty x;
DoubleProperty y;
x.bindBidirectional(y.multiply(1.2));
Run Code Online (Sandbox Code Playgroud)
因此,每次设置x的值时,y值应为x * 1.2 ,每次设置y值时,x值应为y / 1.2
我该怎么做?
Afaik还不存在,因此您需要自己补充类似的内容。
public abstract class BidirectionalBinding<S, T> {
protected final Property<S> property1;
protected final Property<T> property2;
protected boolean calculating = false;
private final InvalidationListener listener;
/**
* Convert value for property 1 to value for property 2
*
* @param value
* @return
*/
protected abstract T convert(S value);
/**
* Convert value for property 2 to value for property 1
*
* @param value
* @return
*/
protected abstract S inverseConvert(T value);
protected BidirectionalBinding(Property<S> property1, Property<T> property2) {
if (property2.isBound() || property1 == null) {
throw new IllegalArgumentException();
}
this.property1 = property1;
this.property2 = property2;
property2.setValue(convert(property1.getValue()));
listener = o -> {
if (!calculating) {
calculating = true;
try {
if (o == property1) {
T value = convert(property1.getValue());
property2.setValue(value);
} else {
S value = inverseConvert(property2.getValue());
property1.setValue(value);
}
} catch (Exception ex) {
dispose();
}
calculating = false;
}
};
property1.addListener(listener);
property2.addListener(listener);
}
public void dispose() {
property1.removeListener(listener);
property2.removeListener(listener);
}
}
Run Code Online (Sandbox Code Playgroud)
DoubleProperty x = new SimpleDoubleProperty(3);
DoubleProperty y = new SimpleDoubleProperty();
final double factor = 1.2;
BidirectionalBinding<Number, Number> binding = new BidirectionalBinding<>(x, y) {
@Override
protected Number convert(Number value) {
return value.doubleValue() * factor;
}
@Override
protected Number inverseConvert(Number value) {
return value.doubleValue() / factor;
}
};
System.out.printf("x = %f; y = %f\n", x.get(), y.get());
x.set(5);
System.out.printf("x = %f; y = %f\n", x.get(), y.get());
y.set(15);
System.out.printf("x = %f; y = %f\n", x.get(), y.get());
Run Code Online (Sandbox Code Playgroud)
请注意,此实现是通用的。如果要处理特殊属性,则可能需要修改代码以使用基本类型,以避免转换为包装器类型...