Javafx 通知可观测属性的变化

Javafx 通知可观测属性的变化,javafx,observer-pattern,Javafx,Observer Pattern,我有一个具有以下属性的类: public class Member { private LongProperty version; private LongProperty id; private StringProperty name; private StringProperty surname; private StringProperty bornname; private StringProperty photo; p

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

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;
}
公共类成员{
私有产权版本;
私人物业id;
私有财产名称;
私有财产姓氏;
私有财产博纳姆;
私人物业照片;
私有财产年龄;
私人财产性;
}
问题是,当我在此对象上添加更改侦听器时:

{
    private ObjectProperty<Member> member;

    public void addMemberChangeListener() {
        this.member.addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                (...)
      }
    }
}
{
私有财产成员;
public void addMemberChangeListener(){
this.member.addListener((可观察、旧值、新值)->{
if(newValue!=null){
(...)
}
}
}

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

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

尝试使用

例如:

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

}
使用:

输出:

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

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

尝试使用

例如:

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

}
使用:

输出:

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

如果要添加一个侦听器,当属于
成员
实例的任何属性发生更改时,该侦听器会收到通知,可以执行以下操作:

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));
然后您可以在更改侦听器中利用这一点:

ChangeListener<Object> listener = (obs, oldValue, newValue) -> 
    System.out.println(((Property<?>)obs).getName() + " changed from " + oldValue + " to " + newValue);
ChangeListener侦听器=(obs、旧值、新值)->
System.out.println(((属性)obs.getName()+)从“+oldValue+”更改为“+newValue”);

只是一个评论:以我的经验,需要这是罕见的(最多)。你通常会(总是?)为每个属性注册一个不同的侦听器会更方便,因为通常情况下,属性更改时要采取的操作取决于更改的属性。在其他情况下,通常会有一个更优雅的解决方案。

如果要添加一个侦听器,当属于某个实例的任何属性对于
成员
更改,您可以执行以下操作:

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));
然后您可以在更改侦听器中利用这一点:

ChangeListener<Object> listener = (obs, oldValue, newValue) -> 
    System.out.println(((Property<?>)obs).getName() + " changed from " + oldValue + " to " + newValue);
ChangeListener侦听器=(obs、旧值、新值)->
System.out.println(((属性)obs.getName()+)从“+oldValue+”更改为“+newValue”);

只是一个评论:以我的经验,需要这是罕见的(最多)。你通常会(总是?)发现为每个属性注册不同的侦听器更方便,因为通常情况下,更改属性时要采取的操作取决于更改的属性。在其他情况下,通常会有一个更优雅的解决方案。

您能澄清您在这里做什么吗?如果您更改,您注册的更改侦听器将收到通知
member
的值,即如果执行类似于
member.set(new member())
的操作。如果希望在某些
member
实例的个别属性更改时收到通知,则需要使用个别属性注册侦听器。个别属性是“主题”如果有帮助,请使用观察者模式的语言。您能澄清您在这里做什么吗?如果您更改
member
的值,即如果您执行类似
member.set(new member())的操作,您注册的更改侦听器将收到通知
。如果您想在某些
成员
实例的个别属性更改时收到通知,则需要使用个别属性注册侦听器。如果有帮助,个别属性是观察者模式语言中的“主题”。这也可以。THX。但我需要将字段作为属性(我使用TableView来显示这些元素)。在isb上面的响应更适合我的案例。这也可以。THX。但是我需要字段作为属性(我使用TableView来显示这些元素)。在isb上面的响应更适合我的案例。