JavaFx:双向绑定数字,带加/乘/

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

我该怎么做?

fab*_*ian 6

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)

请注意,此实现是通用的。如果要处理特殊属性,则可能需要修改代码以使用基本类型,以避免转换为包装器类型...