2015-04-06 55 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