2012-11-04 37 views
3

我試圖做的工作正常,如果我遵循描述here描述的JavaFX屬性定義。 現在,我想使用Java Bean屬性適配器從Java Beans對象定義屬性。由於沒有文檔,我無法弄清楚它是如何工作的。JavaBeans屬性適配器如何工作?

假設我有一個簡單的POJO類:

public class Person { 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

和PersonProperty:

public class PersonProperty { 
    private Person person = new Person(); 

    private JavaBeanStringProperty name; 

    public PersonProperty() throws NoSuchMethodException { 
     name = JavaBeanStringPropertyBuilder.create().bean(person).name("name").build(); 
    } 

    public Person getPerson() { 
     return person; 
    } 

    public void setPerson(Person person) { 
     this.person = person; 
    } 

    public JavaBeanStringProperty nameProperty() { 
     return name; 
    } 
} 

最後一個測試:

public void personTest() throws NoSuchMethodException { 
    PersonProperty pp = new PersonProperty(); 

    pp.getPerson().setName("A"); 
    pp.getPerson().setName("B"); 

    pp.nameProperty().addListener(new ChangeListener<String>() { 
     @Override 
     public void changed(ObservableValue<? extends String> ov, String t, String t1) { 
      System.out.println("from " + t + " to " + t1); 
     } 
    }); 

    pp.getPerson().setName("C"); 
    pp.getPerson().setName("D"); 
} 

我期待看到:

from B to C 
from C to D 

而不是顯示。

如果我在personTest的末尾添加pp.nameProperty().set("E")我得到from B to E

回答

3

我覺得這裏的問題是,人確實是一個POJO,而不是一個JavaBean:它缺少掛鉤的PropertyChangeListeners。 Java不會神奇地知道Person#名稱何時更改。相反,JavaFX適配器將尋找一種方法來添加PropertyChangeListener並偵聽名爲'name'的屬性的事件。如果將PropertyChangeSupport實例添加到Person類,它將按預期工作:

public class Person { 
    private String name; 
    private PropertyChangeSupport _changeSupport; 

    public Person() { 
     _changeSupport = new PropertyChangeSupport(this); 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     final String prev = this.name; 
     this.name = name; 
     _changeSupport.firePropertyChange("name", prev, name); 
    } 

    public void addPropertyChangeListener(final PropertyChangeListener listener) { 
     _changeSupport.addPropertyChangeListener(listener); 
    } 
} 
+0

爲什麼不是JavaBean?它有一個沒有參數和存取方法的構造函數(儘管它不是可序列化的,但是如果它實現了可序列化,則沒有改變)。此外,我不能更改Person類,我無法訪問它。我想從已經存在的JavaBean類 – Alf

+0

中創建一個屬性來回應這麼晚。是的,Person類確實遵守了JavaBean慣例,但只有部分如果您考慮'name'綁定屬性(請參閱http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html)。只要綁定屬性發生變化,JavaBeans就會通知註冊的監聽器,這就是這裏所要求的。如果你不能改變Person,你只剩下兩個選項,我很害怕:爲Person實例添加一個代理類或者使用方面來截取set方法。 – sarcan

+0

好的,我明白了,你是對的。非常感謝你 – Alf