通知。更改ObservableProperties

时间:2017-04-05 14:13:45

标签: javafx observer-pattern

我有一个具有以下属性的类:

public class Member {
    private LongProperty version;

    private LongProperty id;

    private StringProperty name;

    private StringProperty surname;

    private StringProperty bornname;

    private StringProperty photo;

    private ObjectProperty<Age> age;

    private ObjectProperty<Sex> sex;
}

问题是,当我在这个对象上添加Change Listener时:

{
    private ObjectProperty<Member> member;

    public void addMemberChangeListener() {
        this.member.addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                (...)
      }
    }
}

更改属性值时,不会通知更改侦听器。还有其他方法可以通知侦听器有关实现标准Observer模式的更改属性吗?

2 个答案:

答案 0 :(得分:2)

如果要添加在属于Member实例的任何属性发生更改时收到通知的单个侦听器,您可以执行以下操作:

Member member = new Member();

ChangeListener<Object> listener = (obs, oldValue, newValue) -> 
    System.out.println(obs + " changed from " + oldValue + " to " + newValue);

Stream.of(member.versionProperty(), member.idProperty(), member.nameProperty() /*, ... */)
    .forEach(p -> p.addListener(listener));

请注意,具体属性类包含一个构造函数,该构造函数接受拥有bean和属性的名称,因此如果要支持这种使用,可能需要使用这些构造函数:

public class Member {

    private final LongProperty version = new SimpleLongProperty(this, "version");
    private final StringProperty name = new SimpleStringProperty(this, "name");

    // ...
}

然后您可以在更改侦听器中利用它:

ChangeListener<Object> listener = (obs, oldValue, newValue) -> 
    System.out.println(((Property<?>)obs).getName() + " changed from " + oldValue + " to " + newValue);

只是评论:根据我的经验,需要这种情况很少见(充其量)。您通常(总是?)发现为每个属性注册不同的侦听器更方便,因为通常在更改属性时要采取的操作取决于更改的属性。在其他情况下,无论如何通常都会有更优雅的解决方案。

答案 1 :(得分:1)

属性侦听器在更改值memberProperty.setValue(otherMember)时触发,而不是在修改其值memberProperty.getValue().setId(0)的某些属性时触发

尝试使用  PropertyChangeSupport

示例:

public class Member
{

    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);

    private long id;
    private String name;

    public void addChangeListener(PropertyChangeListener listener)
    {
        this.pcs.addPropertyChangeListener(listener);
    }

    public void removeChangeListener(PropertyChangeListener listener)
    {
        this.pcs.removePropertyChangeListener(listener);
    }

    public void setId(long newId)
    {
        long oldId = this.id;
        this.id = newId;
        pcs.firePropertyChange("id", oldId, newId);
    }

    public void setName(String newName)
    {
        String oldName = this.name;
        this.name = newName;
        pcs.firePropertyChange("name", oldName, newName);
    }

}

使用:

Member member = new Member();

member.addChangeListener((evt) ->
{
    System.out.println("Changed "
            + evt.getPropertyName()
            + ": " + evt.getOldValue()
            + " -> " + evt.getNewValue());
});

member.setId(15);
member.setName("Maria");
member.setName("Ana");

输出:

Changed id: 0 -> 15
Changed name: null -> Maria
Changed name: Maria -> Ana