JavaFX TableView中的旧bean未更新
我们正在将JavaFX集成到一个包含许多“原始”JavaBean的大型遗留代码库中,即使用JavaFX TableView中的旧bean未更新,java,javafx,javafx-8,Java,Javafx,Javafx 8,我们正在将JavaFX集成到一个包含许多“原始”JavaBean的大型遗留代码库中,即使用Java.beans.PropertyChangeSupport实现的类型 JavaFX不支持更新这些风格的bean,只支持初始值,如中所述 如果不存在与此模式匹配的方法,则会出现故障 支持尝试调用get()或is()(即 是,getFirstName()或以上示例中的isFirstName()。如果是一种方法 如果存在与此模式匹配的,则此方法返回的值为 包装在ReadOnlyObjectWrapper中并
Java.beans.PropertyChangeSupport
实现的类型
JavaFX不支持更新这些风格的bean,只支持初始值,如中所述
如果不存在与此模式匹配的方法,则会出现故障
支持尝试调用get()或is()(即
是,getFirstName()或以上示例中的isFirstName()。如果是一种方法
如果存在与此模式匹配的,则此方法返回的值为
包装在ReadOnlyObjectWrapper中并返回到TableCell。
但是,在这种情况下,这意味着TableCell将不可用
能够观察ObservableValue的变化(如
第一种方法(见上文)
将bean升级到propertyapi不是一个选项,因为它们位于单独的代码库中,我们不希望添加JavaFX依赖项,因为遗留java6项目仍在使用它
我的问题是,当属性发生更改时,如何让TableView更新,而不必在表中的所有bean上添加/删除侦听器
我正在考虑创建自己版本的PropertyValueFactory来支持这一点,但我想知道是否还有其他可能的解决方案
我举了两个例子来说明这一点
使用老式bean的TableView
public类OldBeanTableView扩展应用程序{
公共类OldBean{
私有最终PropertyChangeSupport pcs=新PropertyChangeSupport(此);
公共静态最终字符串属性\u NAME\u FOO=“FOO”;
私人int foo=99;
公共int getFoo(){
返回foo;
}
公共void setFoo(int foo){
int oldValue=this.foo;
this.foo=foo;
pcs.firePropertyChange(属性名称、旧值、旧值);
}
public void addPropertyChangeListener(PropertyChangeListener侦听器){
pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener侦听器){
pcs.removePropertyChangeListener(监听器);
}
}
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
public void start(Stage primaryStage)引发异常{
ObservableList bean=FXCollections.observableArrayList();
添加(newoldbean());
TableView TableView=新建TableView();
TableColumn column=新的TableColumn();
tableView.getColumns().add(column);
列。setCellValueFactory(新的PropertyValueFactory(“foo”);
tableView.setItems(bean);
primaryStage.setScene(新场景(tableView));
primaryStage.show();
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(()->beans.get(0).setFoo(beans.get(0.getFoo()+1),0,
1,时间单位(秒);
}
}
使用新bean的TableView
public类NewBeanTableView扩展应用程序{
公共级纽宾{
私有IntegerProperty fooProperty=新的SimpleIntegerProperty(0);
公共int getFoo(){
返回fooProperty.get();
}
公共void setFoo(int foo){
fooProperty.set(foo);
}
public IntegerProperty fooProperty(){
归还财产;
}
}
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
public void start(Stage primaryStage)引发异常{
ObservableList bean=FXCollections.observableArrayList();
add(newnewbean());
TableView TableView=新建TableView();
TableColumn column=新的TableColumn();
tableView.getColumns().add(column);
列。setCellValueFactory(新的PropertyValueFactory(“foo”);
tableView.setItems(bean);
primaryStage.setScene(新场景(tableView));
primaryStage.show();
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(()->beans.get(0).setFoo(beans.get(0.getFoo()+1),0,
1,时间单位(秒);
}
}
将JavaBeanProperty用作valueFactory的一个非常简单的示例:
Callback<CellDataFeatures<OldBean, Integer>, ObservableValue<Integer>> valueFactory = cdf -> {
OldBean bean = cdf.getValue();
JavaBeanObjectProperty<Integer> wrappee;
try {
wrappee = JavaBeanObjectPropertyBuilder.create()
.name("foo").bean(bean).build();
return wrappee;
} catch (Exception e) {
e.printStackTrace();
}
return null;
};
column.setCellValueFactory(valueFactory);
callbackvaluefactory=cdf->{
OldBean=cdf.getValue();
JavaBeanObjectProperty wrappee;
试一试{
wrappee=JavaBeanObjectPropertyBuilder.create()
.name(“foo”).bean(bean).build();
返回包装;
}捕获(例外e){
e、 printStackTrace();
}
返回null;
};
列。setCellValueFactory(valueFactory);
请注意,bean必须有方法add/removePropertyChangeListeners(您的真实bean无论如何都会有:-)才能工作。将JavaBeanProperty用作valueFactory的一个非常简单的示例:
Callback<CellDataFeatures<OldBean, Integer>, ObservableValue<Integer>> valueFactory = cdf -> {
OldBean bean = cdf.getValue();
JavaBeanObjectProperty<Integer> wrappee;
try {
wrappee = JavaBeanObjectPropertyBuilder.create()
.name("foo").bean(bean).build();
return wrappee;
} catch (Exception e) {
e.printStackTrace();
}
return null;
};
column.setCellValueFactory(valueFactory);
callbackvaluefactory=cdf->{
OldBean=cdf.getValue();
JavaBeanObjectProperty wrappee;
试一试{
wrappee=JavaBeanObjectPropertyBuilder.create()
.name(“foo”).bean(bean).build();
返回包装;
}捕获(例外e){
e、 printStackTrace();
}
返回null;
};
列。setCellValueFactory(valueFactory);
注意,bean必须有方法add/removePropertyChangeListeners(您的真实bean无论如何都会有:-)才能工作。将kleopatra的答案外推到通用解决方案
public class LegacyValueFactory<T, F> implements Callback<CellDataFeatures<T, F>, ObservableValue<F>> {
private String propertyName;
public LegacyValueFactory(String propertyName) {
this.propertyName = propertyName;
}
@Override
public ObservableValue<F> call(CellDataFeatures<T, F> param) {
try {
return JavaBeanObjectPropertyBuilder.create().name(propertyName).bean(param.getValue()).build();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
}
公共类LegacyValueFactory实现回调{
私有字符串propertyName;
public LegacyValueFactory(字符串属性名称){
this.propertyName=propertyName;
}
@凌驾
公共observeValue调用(CellDataFeatures参数){
试一试{
返回JavaBeanObjectPropertyBuilder.create().name(propertyName).bean(param.getValue()).build();
}捕获(无此方法例外){
e、 printStackTrace();
}
返回null;
}
}
用法
column.setCellValueFactory(新旧版
public class LegacyValueFactory<T, F> implements Callback<CellDataFeatures<T, F>, ObservableValue<F>> {
private String propertyName;
public LegacyValueFactory(String propertyName) {
this.propertyName = propertyName;
}
@Override
public ObservableValue<F> call(CellDataFeatures<T, F> param) {
try {
return JavaBeanObjectPropertyBuilder.create().name(propertyName).bean(param.getValue()).build();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
}
column.setCellValueFactory(new LegacyValueFactory<OldBean, Integer>("foo"));