我想将JavaFX属性用于UI绑定,但我不希望它们出现在我的模型类中(请参阅Using javafx.beans properties in model classes)。我的模型类有getter和setter,我想根据这些创建属性。例如,假设一个实例bean
包含方法String getName()
和setName(String name)
,我会写
SimpleStringProperty property = new SimpleStringProperty(bean, "name")
期望property.set("Foobar")
会触发对bean.setName
的调用。但这似乎不起作用。我错过了什么?
答案 0 :(得分:44)
Simple*Property
类是对应的Property
抽象类的完整独立实现,不依赖于任何其他对象。因此,例如,SimpleStringProperty
包含一个(私有)String
字段本身,它保存属性的当前值。
您显示的构造函数的参数:
new SimpleStringProperty(bean, "name")
是:
bean
:属性所属的bean,如果有的话name
:属性的名称 bean
在ChangeListener
的{{1}}方法中非常有用,因为您可以检索"拥有的bean"从物业本身改变的财产。可以类似地使用changed(...)
(如果您使用多个属性注册了相同的侦听器,则可以确定哪个属性已更改:尽管我从不使用此模式)。
因此,name
作为对象的可观察属性的典型用法如下所示:
SimpleStringProperty
您正在寻找的功能:将现有Java Bean样式属性包装在JavaFX observable属性中是由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
}
包中的类实现的。所以,例如,你可以做到
javafx.beans.property.adapter
致电
StringProperty nameProperty = new JavaBeanStringPropertyBuilder()
.bean(bean)
.name("name")
.build();
使用此设置将有效地调用
nameProperty.set("James");
如果bean支持bean.setName("James");
,则PropertyChangeListener
将向bean注册JavaBeanStringProperty
。对Java Bean的PropertyChangeListener
属性的任何更改都将由name
转换为JavaFX属性更改。因此,如果底层JavaBean支持JavaBeanStringProperty
,则通过
PropertyChangeListener
将导致向bean.setName(...);
注册的任何ChangeListener
s(或InvalidationListener
s)通知此更改。
因此,例如,如果Bean类是
JavaBeanStringProperty
然后是以下代码:
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());
如果JavaBean不支持name changed from to James
James
,那么通过PropertyChangeListener
对bean的更改将不会传播到bean.setName(...)
或ChangeListener
注册的InvalidationListener
}}
所以如果bean只是
JavaBeanStringProperty
JavaBeanStringProperty无法观察更改,因此调用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 ;
}
}
永远不会调用更改侦听器。所以上面的测试代码只会输出
bean.setName()