JavaFX 绑定 StringProperty 和 IntegerProperty

JavaFX binding StringProperty and IntegerProperty

我对 JavaFX 中的绑定有疑问。假设我有映射 1:"Aaa"、2:"Bbb"、3:"Ccc" 等等。我想要的是根据此映射绑定(双向)2 个属性 IntegerProperty 和 StringProperty。如何实现?

UPD: 我将尝试描述我的用例。我有一个 class

class A {
   IntegerProperty num;
   ...
}

但是在用户界面中我不想显示这个数值而是一些有意义的字符串。所以我想添加 StringProperty numValue 并绑定 numnumValue。在 table 中,我将使用 numValue 作为 TableColumn 的 属性。当用户更改 numValue 的值时(例如通过组合框),我希望 num 自动更新。

我建议尽可能避免双向绑定,它们是有问题的1

如果您确实需要双向绑定,那么您很幸运,您的类型之一是 StringbindBidirectional 方法让你指定一个 StringConverter 用于在 String 和其他类型 T 之间转换,在你的情况下 Integer.

Map<Integer, String> m = ...;
StringProperty sp = ...;
IntegerProperty ip = ...;

Bindings.bindBidirectional(sp, ip, new StringConverter<Number>() {

    @Override
    public Integer fromString(String s) {
        for(Integer key: m.keySet()) {
            if(m.get(key).equals(s)) {
                return key;
            }
        }
        return -1; // or whatever makes sense for you
    }

    @Override
    public String toString(Integer i) {
        return m.get(i);
    }
});

为什么支持类型 StringT 而不是任意类型 TU 对我来说是个谜。

更一般地说, 你有两种类型,TU,以及两个函数,f: T -> Ug: U -> T,然后您想使用这两个函数在 Property<T>Property<U> 之间建立双向绑定。上面的例子中,fg都是由StringConverter实现的(比如f就是fromStringg就是toString).您可以使用 ReactFXVars2:

建立这样的双向绑定
Function<T, U> f = ...;
Function<U, T> g = ...;
Var<T> vt = ...;
Var<U> vu = ...;

Var<U> vu1 = vt.map(f).asVar(u -> vt.setValue(g.apply(u)));
Bindings.bindBidirectional(vu, vu1);

你不一定需要fg的倒数,即你不需要g(f(x)) = x,但为了避免无限循环(堆栈溢出) ,它最好快速收敛,例如f(g(f(x))) = f(x),或g(f(g(f(g(f(g(f(x)))))))) = g(f(g(f(g(f(x))))))或类似的东西。


1 我意识到我只是在没有提供任何有效参数的情况下加入了这个声明。
2 Var 实际上只是一个带有一些额外方法的 Property