Ответ 1
Классы Simple*Property
являются полными, автономными реализациями соответствующих абстрактных классов Property
и не зависят от каких-либо других объектов. Так, например, SimpleStringProperty
содержит поле (private) String
, которое содержит текущее значение свойства.
Параметры конструктора, который вы показали:
new SimpleStringProperty(bean, "name")
являются:
-
bean
: bean, к которому принадлежит свойство, если любой -
name
: имя свойства
bean
может быть полезен в методе ChangeListener
changed(...)
, так как вы можете получить "владение bean" свойства, которое было изменено из самого свойства. 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. Любые изменения в свойстве name
Java bean будут переведены с помощью изменений JavaBeanStringProperty
в свойства JavaFX. Следовательно, если базовый JavaBean поддерживает PropertyChangeListener
s, то изменяется на bean через
bean.setName(...);
приведет к любым ChangeListener
(или InvalidationListener
s), зарегистрированным с сообщением JavaBeanStringProperty
об изменении.
Итак, например, если класс 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 через bean.setName(...)
не будут передаваться в ChangeListener
или InvalidationListener
, зарегистрированном с помощью JavaBeanStringProperty
.
Итак, если 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