2015-04-06 173 views
0

考虑以下车型的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

你需要两样东西:

  1. 充分利用apple财产Basket一个JavaFX观察特性, 而不是常规的JavaBean样式属性。
  2. 将本地字符串属性绑定到“属性属性”,即 appleName属性的apple属性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()); 
     } 
    }); 
+0

我们可以做到这一点,没有任何新的额外的依赖? – Jones 2015-04-06 14:35:43

+0

不容易......你基本上最终会复制框架代码的相关部分。 – 2015-04-06 14:37:30

+0

增加了一种不使用EasyBind的方法。如果你有更长的属性链,它会变得非常难看。 – 2015-04-06 15:14:40