我有一个具有以下属性的类:
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模式的更改属性吗?
答案 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)
的某些属性时触发
示例:
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