【问题标题】:How to update JavaFX binding reference of an Object如何更新对象的 JavaFX 绑定引用
【发布时间】:2015-04-06 13:57:57
【问题描述】:

考虑以下型号,Apple

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。获得红苹果的干净方法是什么?

【问题讨论】:

    标签: binding javafx-8


    【解决方案1】:

    你需要两件事:

    1. Basket 中的apple 属性设为JavaFX 可观察属性, 而不是常规的 JavaBean 样式的属性。
    2. 将本地字符串属性绑定到“属性的属性”,即 apple 属性的appleName 属性Basket

    第一部分很简单:

    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 framework

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

    【讨论】:

    • 我们可以在没有任何新的附加依赖项的情况下做到这一点吗?
    • 不容易......你基本上只是最终复制了框架代码的相关部分。
    • 添加了一种无需 EasyBind 的方法。如果你有更长的属性链,它会变得很丑。
    • 都试过了。虽然它的 EasyBind 很好,但我会和听众一起去了解更多。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    相关资源
    最近更新 更多