Object 具有不同对象的TableView(javafx)

Object 具有不同对象的TableView(javafx),object,javafx,tableview,Object,Javafx,Tableview,我目前正在开发一个应用程序来观察谁对不同的病人负责,但是我还不能解决如何用不同的对象类型填充表格的问题 下面是我的TableView控制器的代码。TableView将以四种不同的对象类型结束,所有对象类型都将从数据库中检索 我希望我的表能够容纳患者对象、用户对象(负责人)和RelationManager对象 下面是我的代码,如果您需要更多的代码,请让我知道:-) package fird.presentation; 进口一级病人; 导入fird.RelationManager; 导入第一用户;

我目前正在开发一个应用程序来观察谁对不同的病人负责,但是我还不能解决如何用不同的对象类型填充表格的问题

下面是我的TableView控制器的代码。TableView将以四种不同的对象类型结束,所有对象类型都将从数据库中检索

我希望我的表能够容纳患者对象、用户对象(负责人)和RelationManager对象

下面是我的代码,如果您需要更多的代码,请让我知道:-)

package fird.presentation;
进口一级病人;
导入fird.RelationManager;
导入第一用户;
导入fird.data.dao工厂;
导入fird.data.DataDAO;
导入java.net.URL;
导入java.util.array;
导入java.util.List;
导入java.util.ResourceBundle;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.fxml.fxml;
导入javafx.fxml.Initializable;
导入javafx.scene.control.Button;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TableView;
导入javafx.scene.control.TextField;
导入javafx.scene.control.cell.PropertyValueFactory;
/**
*FXML控制器类
*
*@作者西蒙克拉夫
*/
公共类KmainFrameOverviewController实现可初始化{
@FXML
私有文本字段txtcprm;
@FXML
私有表列表列CPR;
@FXML
私有TableColumn TableColumnFirstname;
@FXML
私有表列表列姓氏;
@FXML
私人TableColumn TableColumn负责;
@FXML
私有TableColumn TableColumnLastEdit;
@FXML
私有TableView-tblpa患者;
@FXML
私人按钮显示历史;
@FXML
私人餐桌部;
/**
*初始化控制器clas@FXML专用按钮btnShowHistory;
*
*@FXML private TableColumn部门;s。
*/
@凌驾
公共void初始化(URL、ResourceBundle rb){
//启动主框架概览控制器的逻辑
DataDAO=DAOFactory.getDataDao();
TableColumnCPR.setCellValueFactory(新属性值工厂(“CPR”);
TableColumnFirstname.setCellValueFactory(新的PropertyValueFactory(“Firstname”));
TableColumnName.setCellValueFactory(新属性值工厂(“姓氏”);
TableColumnResponsible.setCellValueFactory(新属性值工厂(“Responsible”));
TableColumnLastEdited.setCellValueFactory(新属性值工厂(“上次编辑”));
ObservableList relationData=FXCollections.observableArrayList(dao.GetAllActivations());
tblPatients.setItems(relationData);
tblPatients.getColumns().addAll(TableColumnCPR、TableColumnFirstname、TableColumn姓氏、TableColumnResponsible、TableColumnLastEdit);
System.out.println(tblPatients.getItems().toString());
}
}
relationData是返回的RelationManager对象。此对象包含用户对象、患者对象和责任对象

最好的,
西蒙

如何做到这一点的具体细节取决于您的需求:例如,对于给定的RelationManager对象,与之相关联的用户、患者或负责对象是否会发生变化?是否需要表格可编辑

但其基本思想是表中的每一行都代表一些RelationManager,因此表类型为
TableView
。每列显示某种类型的值(称之为
S
),因此每列的类型为
TableColumn
,其中
S
可能因列而异

单元格值工厂是一个对象,它指定如何从
RelationManager
对象获取类型为
S
的可观察值。执行此操作的确切方式取决于模型类的设置方式

如果与给定的
RelationManager
关联的单个对象从未更改(例如,给定的
RelationManager
患者
始终是相同的),那么就相当简单了。假设您对
患者进行了常规设置

public class Patient {
    private StringProperty firstName = new SimpleStringProperty(...);
    public StringProperty firstNameProperty() {
        return firstName ;
    }
    public String getFirstName() {
        return firstName.get();
    }
    public void setFirstName(String firstName) {
        this.firstName.set(firstName);
    }
    // etc etc
}
那你就做吧

TableColumn<RelationManager, String> firstNameColumn = new TableColumn<>("First Name");
firstNameColumn.setCellValueFactory(new Callback<CellDataFeatures<RelationManager,String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(CellDataFeatures<RelationManager, String> data) {
        return data.getValue() // the RelationManager
           .getPatient().firstNameProperty();
    }
});
但请注意,如果您将患者的姓名从外部更改到表中,则不会更新此信息

但是,如果与关系管理器关联的patient对象发生更改(单元格仍将观察到错误的
firstNameProperty()
),则所有这些都不起作用。在这种情况下,您需要一个可观察的值,该值在“中间”患者属性或firstNameProperty更改时发生更改。JavaFX有一个API,其中包含一些可以做到这一点的
select(…)
方法:不幸的是,在JavaFX8中,如果沿途的任何对象为null,它们会向控制台发出大量警告,这些警告将出现在
TableView
上下文中。在本例中,我建议查看框架,它将允许您执行以下操作

firstNameColumn.setCellValueFactory( data -> 
    EasyBind.select(data.getValue().patientProperty())
        .selectObject(Patient::firstNameProperty));
(EasyBind需要JavaFX8,所以如果要使用它,还可以使用lambda表达式和方法引用:))


在这两种情况下,如果您希望表格可编辑,则需要为可编辑的单元格做一些额外的工作,例如将编辑提交回相应的调用以设置属性。

Hi James。谢谢你的帖子!真的很感激!在我的patient类中,我使用String而不是StringProperty,这让我有点头疼,但我所有用于接收数据等的控制器都工作正常,没有任何问题。你能不能看一下我的项目,给我一个关于我具体情况的提示?这是我的第一个更大的项目,所以我对DataDAO的等有一些问题。最好的,Simon。我真的没有时间浏览整个项目(这对付钱给我的人不公平)。但我会快速更新,以展示如果您的对象是传统bean,您可以做些什么。感谢您的更新,我会尝试查看一下。A b
TableColumn<RelationManager, String> firstNameColumn = new TableColumn<>("First Name");
firstNameColumn.setCellValueFactory(new Callback<CellDataFeatures<RelationManager,String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(CellDataFeatures<RelationManager, String> data) {
        return new ReadOnlyStringWrapper(data.getValue().getPatient().getFirstName());
    }
});
firstNameColumn.setCellValueFactory( data -> 
    EasyBind.select(data.getValue().patientProperty())
        .selectObject(Patient::firstNameProperty));