UIバインディングにJavaFXプロパティを使用したいのですが、モデルクラスにそれらを使用したくありません( モデルクラスでのjavafx.beansプロパティの使用 を参照)。私のモデルクラスにはゲッターとセッターがあり、それらに基づいてプロパティを作成したいと思います。たとえば、メソッドString getName()
とsetName(String name)
を持つインスタンスbean
を想定すると、次のようになります。
_ SimpleStringProperty property = new SimpleStringProperty(bean, "name")
_
property.set("Foobar")
が_bean.setName
_への呼び出しをトリガーすることを期待します。しかし、これはうまくいかないようです。何が足りないのですか?
_Simple*Property
_クラスは、対応するProperty
抽象クラスの完全なスタンドアロン実装であり、他のオブジェクトに依存しません。したがって、たとえば、SimpleStringProperty
には、プロパティの現在の値を保持する(プライベート)String
フィールド自体が含まれます。
示したコンストラクターのパラメーター:
_new SimpleStringProperty(bean, "name")
_
は:
bean
:プロパティが属するBean(存在する場合)name
:プロパティの名前bean
は、プロパティ自体から変更されたプロパティの「所有Bean」を取得できるため、ChangeListener
のchanged(...)
メソッドで役立ちます。 name
も同様に使用できます(同じリスナーが複数のプロパティに登録されている場合、どのプロパティが変更されたかを把握できます。ただし、このパターンは使用しません)。
したがって、オブジェクトの監視可能なプロパティとしてのSimpleStringProperty
の一般的な使用法は、次のようになります。
_public class Person {
private final StringProperty firstName
= new SimpleStringProperty(this, "firstName");
public final String getFirstName() {
return firstName.get();
}
public final void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public StringProperty firstNameProperty() {
return firstName ;
}
// ... other properties, etc
}
_
探している機能:既存のJava BeanスタイルのプロパティをJavaFXの監視可能なプロパティでラップすることは、_javafx.beans.property.adapter
_パッケージのクラスによって実装されます。したがって、たとえば、次のことができます。
_StringProperty nameProperty = new JavaBeanStringPropertyBuilder()
.bean(bean)
.name("name")
.build();
_
呼び出し
_nameProperty.set("James");
_
この設定では、効果的にへの呼び出しが発生します
_bean.setName("James");
_
BeanがPropertyChangeListener
sをサポートしている場合、JavaBeanStringProperty
はPropertyChangeListener
をBeanに登録します。 Java Beanのname
プロパティへの変更は、JavaBeanStringProperty
によってJavaFXプロパティの変更に変換されます。したがって、基盤となるJavaBeanがPropertyChangeListener
sをサポートしている場合は、経由でBeanに変更されます。
_bean.setName(...);
_
ChangeListener
に登録されているInvalidationListener
s(またはJavaBeanStringProperty
s)には、変更が通知されます。
したがって、たとえば、Beanクラスが
_import Java.beans.PropertyChangeListener;
import Java.beans.PropertyChangeSupport;
public class Bean {
private String name ;
private final PropertyChangeSupport propertySupport ;
public Bean(String name) {
this.name = name ;
this.propertySupport = new PropertyChangeSupport(this);
}
public Bean() {
this("");
}
public String getName() {
return name ;
}
public String setName(String name) {
String oldName = this.name ;
this.name = name ;
propertySupport.firePropertyChange("name", oldName, name);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertySupport.addPropertyChangeListener(listener);
}
}
_
次に、次のコード:
_Bean bean = new Bean();
StringProperty nameProperty() = new JavaBeanStringPropertyBuilder()
.bean(bean)
.name("name")
.build();
nameProperty().addListener((obs, oldName, newName) -> System.out.println("name changed from "+oldName+" to "+newName));
bean.setName("James");
System.out.println(nameProperty().get());
_
出力を生成します:
_name changed from to James
James
_
JavaBeanがPropertyChangeListener
sをサポートしていない場合、bean.setName(...)
を介したBeanへの変更は、ChangeListener
sまたはInvalidationListener
に登録されているJavaBeanStringProperty
sに伝播されません。
つまり、Beanが単純な場合
_public class Bean {
public Bean() {
this("");
}
public Bean(String name) {
this.name = name ;
}
private String name ;
public String getName() {
return name ;
}
public void setName(String name) {
this.name = name ;
}
}
_
JavaBeanStringPropertyには変更を監視する方法がないため、変更リスナーがbean.setName()
の呼び出しによって呼び出されることはありません。したがって、上記のテストコードは単純に出力されます
_James
_