如何更新对象的 JavaFX 绑定引用



考虑以下型号,苹果

public class Apple {
    private StringProperty appleName = new SimpleStringProperty("Apple");
    public String getAppleName() {
        return appleName.get();
    }
    public StringProperty appleNameProperty() {
        return appleName;
    }
    public void setAppleName(String appleName) {
        this.appleName.set(appleName);
    }
}

和篮子

public class Basket {
    private Apple apple = new Apple();
    public Apple getApple() {
        return apple;
    }
    public void setApple(Apple apple) {
        this.apple = apple;
    }
}

篮子里有一个苹果。现在我正在尝试绑定一个简单的字符串属性,如下所示。

public class Food{
    public static void main(String[] args) {
        StringProperty localApple = new SimpleStringProperty("lGreenApple");
        Basket basket = new Basket();
        Apple rGreenApple = new Apple();
        rGreenApple.setAppleName("rGreenApple");
        basket.setApple(rGreenApple);
        Bindings.bindBidirectional(localApple, rGreenApple.appleNameProperty());
        rGreenApple.appleNameProperty().set("rGreenApple 2");
        System.out.println(localApple.getValue()); //rGreenApple 2
        Apple redApple = new Apple();
        redApple.setAppleName("rRedApple");
        basket.setApple(redApple);
        redApple.appleNameProperty().set("rRedApple 2");
        System.out.println(localApple.getValue());//Still rGreenApple 2
    }
}

在绑定后尝试检索值时,localApple对象仍然引用rGreenApple 。获得红苹果的干净方法是什么?

你需要

两样东西:

  1. 使 apple 属性Basket成为 JavaFX 可观察属性,而不是常规的 JavaBean 样式属性。
  2. 将本地字符串属性绑定到"属性的属性",即Basketapple财产的appleName属性。

第一部分很简单:

public class Basket {
    private final ObjectProperty<Apple> apple = new SimpleObjectProperty<>();
    public ObjectProperty<Apple> appleProperty() {
        return apple ;
    }
    public final Apple getApple() {
        return appleProperty().get();
    }
    public final void setApple(Apple apple) {
        appleProperty().set(apple);
    }
}

对于第二部分,最干净的方法是使用 EasyBind 框架:

public class Food{
    public static void main(String[] args) {
        Basket basket = new Basket();
        Apple rGreenApple = new Apple();
        rGreenApple.setAppleName("rGreenApple");
        basket.setApple(rGreenApple);
        Property<String> localApple = EasyBind.monadic(basket.appleProperty())
            .selectProperty(Apple::appleNameProperty);
        rGreenApple.appleNameProperty().set("rGreenApple 2");
        System.out.println(localApple.getValue()); //rGreenApple 2
        Apple redApple = new Apple();
        redApple.setAppleName("rRedApple");
        basket.setApple(redApple);
        System.out.println(localApple.getValue());// rRedApple
        redApple.appleNameProperty().set("rRedApple 2");
        System.out.println(localApple.getValue());// rRedApple 2
    }
}

如果没有 EasyBind,您必须手动管理中间侦听器。像这样:

    StringProperty localApple = new SimpleStringProperty();
    localApple.bindBidirectional(basket.getApple().appleNameProperty());
    basket.appleProperty().addListener((obs, oldApple, newApple) -> {
        if (oldApple != null) {
            localApple.unbindBidirectional(oldApple.appleNameProperty());
        }
        if (newApple == null) {
            localApple.set("");
        } else {
            localApple.bindBidirectional(newApple.appleNameProperty());
        }
    });

最新更新