我目前正在开发一个应用程序,用于观察谁负责不同的患者,但是我还没有能够解决如何用不同的对象类型填充表格。
下面是我的TableView控制器的代码。 TableView将以四种不同的对象类型结束,所有这些都将从数据库中检索。
我希望我的表能够保存Patient对象,User对象(负责人)和RelationManager对象。
以下是我的代码,如果您需要更多代码,请告诉我: - )。
package fird.presentation;
import fird.Patient;
import fird.RelationManager;
import fird.User;
import fird.data.DAOFactory;
import fird.data.DataDAO;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
/**
* FXML Controller class
*
* @author SimonKragh
*/
public class KMAMainFrameOverviewController implements Initializable {
@FXML
private TextField txtCPRKMAMainFrame;
@FXML
private TableColumn<Patient, String> TableColumnCPR;
@FXML
private TableColumn<Patient, String> TableColumnFirstname;
@FXML
private TableColumn<Patient, String> TableColumnSurname;
@FXML
private TableColumn<User, String> TableColumnResponsible;
@FXML
private TableColumn<RelationManager, String> TableColumnLastEdited;
@FXML
private TableView<RelationManager> tblPatients;
@FXML
private Button btnShowHistory;
@FXML
private TableColumn<?, ?> TableColumnDepartment;
/**
* Initializes the controller clas @FXML private Button btnShowHistory;
*
* @FXML private TableColumn<?, ?> TableColumnDepartment; s.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
// Start of logic for the KMAMainFrameOverviewController
DataDAO dao = DAOFactory.getDataDao();
TableColumnCPR.setCellValueFactory(new PropertyValueFactory<Patient, String>("CPR"));
TableColumnFirstname.setCellValueFactory(new PropertyValueFactory<Patient, String>("Firstname"));
TableColumnSurname.setCellValueFactory(new PropertyValueFactory<Patient, String>("Surname"));
TableColumnResponsible.setCellValueFactory(new PropertyValueFactory<User, String>("Responsible"));
TableColumnLastEdited.setCellValueFactory(new PropertyValueFactory<RelationManager, String>("Last Edited"));
ObservableList<RelationManager> relationData = FXCollections.observableArrayList(dao.getAllActiveRelations());
tblPatients.setItems(relationData);
tblPatients.getColumns().addAll(TableColumnCPR, TableColumnFirstname, TableColumnSurname, TableColumnResponsible, TableColumnLastEdited);
System.out.println(tblPatients.getItems().toString());
}
}
relationData是返回的RelationManager对象。该对象包含User对象,Patient对象和Responsible对象。
最佳, 西蒙。
答案 0 :(得分:9)
如何执行此操作的具体细节取决于您的要求:例如,对于给定的RelationManager对象,与其关联的User,Patient或Responsible对象是否会发生变化?你需要表格可以编辑吗?
但基本思想是表中的每一行代表一些RelationManager,因此表类型为TableView<RelationManager>
。每列显示某种类型的值(称之为S
),因此每列的类型为TableColumn<RelationManager, S>
,其中S
可能因列而异。
单元格值工厂是一个对象,它指定如何从RelationManager
对象获取类型为S
的可观察值。您执行此操作的确切方式取决于您的模型类的设置方式。
如果与给定RelationManager
关联的单个对象永远不会更改(例如,给定Patient
的{{1}}始终相同),那么它非常简单。假设您有RelationManager
的常规设置:
Patient
然后你可以做
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
}
如果您不使用JavaFX属性,则可以使用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();
}
});
使用的相同后备,即:
PropertyValueFactory
但请注意,如果您将患者姓名从表格外部更改,则不会更新。
但是,如果与关系管理器关联的患者对象发生更改(该单元仍将观察到错误的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());
}
});
),则这些都不起作用。在这种情况下,您需要一个可观察的值,当“中间”患者属性或firstNameProperty更改时,该值会发生变化。 JavaFX有一个Bindings
API和一些firstNameProperty()
方法可以做到这一点:不幸的是,在JavaFX 8中,如果沿途的任何对象为空,它们会向控制台发出大量警告,他们将处于select(...)
上下文中。在这种情况下,我建议查看EasyBind框架,这将允许您执行类似
TableView
(EasyBind需要JavaFX 8,所以如果你使用它,你也可以使用lambda表达式和方法引用:)。)
在任何一种情况下,如果您希望表格是可编辑的,那么对于可编辑单元格,在布线编辑方面需要做一些额外的工作,提交回适当的调用以设置属性。