JavaFX PropertyValueFactory无法检索属性 总结:

JavaFX PropertyValueFactory无法检索属性 总结:,java,javafx,Java,Javafx,我试图通过按“重新加载按钮”将ArrayList中的数据添加/重新加载到TableView(目前我只是使用TableView的一列进行测试)。 因为TableView需要一个ObservableList,所以我制作了一个ObservableList getter方法,其中ObservableList是从现有的ArrayList创建的(我测试了这两个列表,通过打印它们的值而没有问题)。每次按下“重新加载”按钮时,只会创建一定数量的行,并且我会收到一个错误,这是由以下代码行引起的: columnPr

我试图通过按“重新加载按钮”将ArrayList中的数据添加/重新加载到TableView(目前我只是使用TableView的一列进行测试)。 因为TableView需要一个ObservableList,所以我制作了一个ObservableList getter方法,其中ObservableList是从现有的ArrayList创建的(我测试了这两个列表,通过打印它们的值而没有问题)。每次按下“重新加载”按钮时,只会创建一定数量的行,并且我会收到一个错误,这是由以下代码行引起的:

columnProject.setCellValueFactory(新属性值工厂(“项目”);
在过去的3个小时里,我查找了这个问题,并尝试了在Stack Overflow上找到的所有方法,但没有成功

资料:
  • Java:openjdk 11.0.3和Javafx-11
  • 操作系统:内核为5.0.7-1的Manjaro Linux
  • IDE:IntelliJ Idea Ultimate 2019
  • 我将FXML与SceneBuilder一起用于所有JavaFX对象
错误: 控制器类:

package net.strobl.main;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.event.ActionEvent;
导入javafx.fxml.fxml;
导入javafx.scene.control.*;
导入javafx.scene.control.cell.PropertyValueFactory;
导入net.strobl.processing.DataManager;
导入java.io.IOException;
公共类控制器{
私人应用程序;
专用数据管理器数据管理器;
//region@FXML对象新账单
@FXML
按钮提交按钮;
@FXML
TextField输入项目;
@FXML
文本字段输入量;
@FXML
TextField输入车间;
@FXML
文本字段输入;
@FXML
文本字段输入人员;
@FXML
文本字段inputDate1;
@FXML
文本字段inputDate2;
@FXML
文本字段输入日期3;
@FXML
无线电按钮输入;
@FXML
无线按钮输入数字;
@FXML
无线按钮输入;
//端区
//区域@FXML对象视图项目
@FXML
纺纱机纺纱机项目选择;
@FXML
TextField TextField项目花费;
@FXML
TextField TextField项目获得;
@FXML
TextField TextField项目收入;
@FXML
滚动窗格滚动窗格;
//region@FXML TableView和Columns
@FXML
TableView TableView;
@FXML
表列项目;
@FXML
表列数量;
@FXML
表列式进水管;
@FXML
数字化表格;
@FXML
台柱店;
@FXML
表列原因;
@FXML
表列人;
@FXML
TableColumnDate1;
@FXML
TableColumnDate2;
@FXML
TableColumnDate3;
@FXML
表1:支付的费用;
public void addTableViewData(ActionEvent事件){
columnProject.setCellValueFactory(新的PropertyValueFactory(“项目”));
setItems(getObservableBills());
}
私有可观察列表getObservableBills(){
返回FXCollections.observableArrayList(app.getBills());
}
公共控制器()引发IOException{
app=新app();
dataManager=新的dataManager();
}
}
fxml文件(仅包括按钮和TableView):

module-info.java
模块自动化财务{
需要javafx.controls;
需要javafx.fxml;
需要opencsv;
打开net.strobl.main;
}

我不是JavaFX的专家。但是如果我读对了文档,PropertyValueFactory构造函数中的String参数不是指TableView类型参数的字段,而是指TableColumn构造函数的String参数。如果我是对的,它不应该是
“project”
(Bill中的私有字段),而是
“project”
(FXML中第一个表列的参数文本)。

Bill
类中,您有:

public class Bill {

    private String project;

    // getter
    public String getProject() {
        return project;
    }

    // setter
    public void setProject(String project) {
        this.project = project;
    }

    // ????
    public String projectProperty() {
        return project;
    }

}
当您对TableColumn单元格值工厂使用回调
new PropertyValueFactory(“项目”)
时,当计算
call
方法时,会发生以下情况:

@Override 
public ObservableValue<T> call(CellDataFeatures<S,T> param) {
    return getCellDataReflectively(param.getValue());
}

private ObservableValue<T> getCellDataReflectively(S rowData) {
    ...

     if (propertyRef.hasProperty()) {
         return propertyRef.getProperty(rowData);
     } else {
         T value = propertyRef.get(rowData);
         return new ReadOnlyObjectWrapper<T>(value);
     }
     ...   
}
由于您提供的是
projectProperty()
方法,因此此方法被错误地视为
propertyGetter
,因为它在
reflect()
中以
Property
结尾:

因此它将返回true,然后
getProperty()
将尝试强制转换此属性:

try {
    return (ReadOnlyProperty<T>)MethodHelper.invoke(propertyGetter, bean, (Object[])null);
}
private final StringProperty project = new SimpleStringProperty();

public final StringProperty projectProperty() {
   return project;
}

public final String getProject() {
   return project.get();
}

public final void setProject(String value) {
    project.set(value);
}
因为您的
字符串项目
显然无法强制转换为
只读属性

解决方案

您可以使用适当的属性:

try {
    return (ReadOnlyProperty<T>)MethodHelper.invoke(propertyGetter, bean, (Object[])null);
}
private final StringProperty project = new SimpleStringProperty();

public final StringProperty projectProperty() {
   return project;
}

public final String getProject() {
   return project.get();
}

public final void setProject(String value) {
    project.set(value);
}
或者删除了错误的属性getter,然后回调将默认为第二种情况,使用
getCellDataReflective
中的字符串原语,该原语将转换为只读属性:

T value = propertyRef.get(rowData);
return new ReadOnlyObjectWrapper<T>(value);
T value=propertyRef.get(rowData);
返回新的ReadOnlyObjectWrapper(值);

虽然这很好,但首选第一种方法,即使用适当的JavaFX属性。

为什么使用此方法
Bill:projectProperty
?它不会返回一个属性…@JoséPereda我在这里尝试了第二个评论,我可能误解了它请。。请注意,m不需要几十个属性或列,只有两个左右enough@kleopatra,谢谢,我不知道怎么回事(现在我知道我应该知道)。下次我会考虑的!谢谢,它现在工作得很好!我甚至没想到会在这么短的时间内得到如此详细的答案,不仅是一个解决方案,而且是一个完整的解释。谢谢你的回答,但这不是我问题的解决方案。我可能解释得不好(不是以英语为母语的人)。
private final StringProperty project = new SimpleStringProperty();

public final StringProperty projectProperty() {
   return project;
}

public final String getProject() {
   return project.get();
}

public final void setProject(String value) {
    project.set(value);
}
T value = propertyRef.get(rowData);
return new ReadOnlyObjectWrapper<T>(value);