2017-04-05 17 views
0

私は次のプロパティを持つクラスを持っているの変更:通知してください。 ObservableProperties

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

私は、このオブジェクトに変更リスナーを追加するときに問題がある:私は値を変更するとき

{ 
    private ObjectProperty<Member> member; 

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

変更リスナーが通知されませんプロパティの。標準Observerパターンを実装するプロパティの変更についてリスナーに通知する方法は他にありますか?あなたは、その値のいくつかのプロパティを変更すると、それは価値memberProperty.setValue(otherMember)を変更したとき

+0

ここで何をしているのか明確にすることはできますか? 'member'の値を変更した場合、つまり' member.set(new member()) 'のようなことをすれば、登録した変更リスナーに通知が送られます。 'Member'インスタンスの個々のプロパティが変更されたときに通知を受けたい場合は、個々のプロパティにリスナーを登録する必要があります。 –

+0

個々のプロパティは、オブザーバーパターンの言語における「サブジェクト」です。 –

答えて

1

あなたがプロパティのいずれかに属しているときに通知された単一のリスナーを追加したい場合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)); 

具体的なプロパティクラスが所有豆とプロパティの名前を取りますので、あなたは使用のこの種をサポートする場合、あなたはそれらのコンストラクタを使用する場合がありますコンストラクタが含まれていることを注意:

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

がプロパティリスナーがトリガされ、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 
+0

でもOKです。 THX。しかし、私はプロパティとしてフィールドを持つ必要があります(私はこの要素を表示するためにTableViewを使用します)。私の場合は、上記のisbの応答をより良くしてください。 – VANILKA

関連する問題