TableView与不同的对象(javafx)

时间:2014-05-09 18:37:03

标签: object javafx tableview

我目前正在开发一个应用程序,用于观察谁负责不同的患者,但是我还没有能够解决如何用不同的对象类型填充表格。

下面是我的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对象。

最佳, 西蒙。

1 个答案:

答案 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表达式和方法引用:)。)

在任何一种情况下,如果您希望表格是可编辑的,那么对于可编辑单元格,在布线编辑方面需要做一些额外的工作,提交回适当的调用以设置属性。