JavaBeans属性适配器是如何工作的?

JavaBeans属性适配器是如何工作的?,java,javafx-2,Java,Javafx 2,如果我遵循所描述的JavaFX属性定义,那么我尝试做的工作将很好。 现在,我想使用JavaBeans属性适配器从JavaBeans对象定义属性。由于没有文档,我无法理解它是如何工作的 假设我有一个简单的POJO类: public class Person { private String name; public String getName() { return name; } public void setName( String name

如果我遵循所描述的JavaFX属性定义,那么我尝试做的工作将很好。 现在,我想使用JavaBeans属性适配器从JavaBeans对象定义属性。由于没有文档,我无法理解它是如何工作的

假设我有一个简单的POJO类:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName( String name ) {
        this.name = name;
    }
}
以及个人财产:

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" );
}
相反,什么也没有出现


如果我在personTest的末尾添加
pp.nameProperty().set(“E”)
,我会从B到E得到

,我认为这里的问题是,Person确实是一个POJO,但不是JavaBean:它缺少PropertyChangeListeners的钩子。Java不会神奇地知道人名何时改变。相反,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);
    }
}

为什么它不是JavaBean?它有一个没有参数和访问器方法的构造函数(即使它不可序列化,但如果它实现可序列化,则不会发生任何更改)。此外,我不能更改Person类,我无法访问它。我想从已经存在的JavaBean类创建一个属性,很抱歉这么晚才响应。是的,Hype类确实遵守JavaBean约定,但是如果您考虑“NoD”绑定属性(参见),则只会部分地使用JavaBean约定。每当绑定属性发生更改时,JavaBeans将通知注册的侦听器,这就是这里所需要的。如果您无法更改Person,那么您将有两个选择:为Person实例添加代理类或使用Aspect拦截set方法。
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);
    }
}