How does JavaBeans Property Adapter work?

2020-03-26 04:26发布

What I'm trying to do works fine if I follow the JavaFX property definition described here. Now, instead, I want to define properties from Java Beans objects using Java Beans Property Adapter. Since there is no documentation I can't figure out how it works.

Suppose I have a simple POJO class:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

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

and a 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;
    }
}

and finally a test:

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

I'm expecting to see:

from B to C
from C to D

Instead nothing appears.

If I add pp.nameProperty().set("E") at the end of personTest I get from B to E

标签: java javafx-2
1条回答
该账号已被封号
2楼-- · 2020-03-26 04:52

I think the issue here is that Person is indeed a POJO, but not a JavaBean: It is missing the hooks for PropertyChangeListeners. Java will not magically know when Person#name changes. Instead, the JavaFX adapter will look for a way to add a PropertyChangeListener and listen to events for a property called 'name'. If you add a PropertyChangeSupport instance to your Person class it will work as expected:

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);
    }
}
查看更多
登录 后发表回答