JavaFx:绑定号码双向 add/multiply/

JavaFx: Bind number bidirectional with add/multiply/

我想绑定两个 DoubleProperty 双向但不是真的 1:1,但是例如 1:1.2 比例。

我需要这样的东西:

DoubleProperty x;
DoubleProperty y;

x.bindBidirectional(y.multiply(1.2));

所以每次设置x的值,y的值应该是x*1.2 每次设置 y 值时,x 应该是 y/1.2

我该怎么做?

据我所知,目前还没有任何东西存在,因此您需要自己实施类似的东西。

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);
    }
}
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());

请注意,此实现是通用的。如果您正在处理专门的属性,您可能需要修改代码以使用原始类型以避免转换为包装类型...