我有两节课:

Project                     Employee                Jobtitle
-------------------------   -------------------     ----------------------
name: String                firstname: String       title: String
employees: List<Employee>   jobtitle: Jobtitle      hourlyWage: BigDecimal
                            birthday: Date


如何显示和编辑树形表中的值,如下所示:

Name        fName   Title       Birthday
------------------------------------------
-Project A
            -Tom    Programmer  09-12-1980
            -Peter  Accountant  03-04-1970
-Project B
-Project D


到目前为止,我已经编写了以下程序。因为雇员是列表,我如何为雇员添加列?:

TreeItem<Project> root
                = new TreeItem<>(new Project("Root", null));

for (Project project : projectData) {
    root.getChildren().add(new TreeItem<>(project));
}

TreeTableColumn<Project, String> projectCol
    = new TreeTableColumn<>("Projects");
projectCol.setCellValueFactory((cellData) -> cellData.getValue()
                                    .getValue().nameProperty());

//Now how can I add columns for Employee?
//TreeTableColumn<Project, String> projectCol
//  = new TreeTableColumn<>("Firstname");
//projectCol.setCellValueFactory((cellData) -> cellData.getValue()
//                                  .getValue().employeesProperty()...?);

TreeTableView<Project> treeTable = new TreeTableView<>(root);
treeTable.getColumns().add(projectCol);


这些值来自ObservableLists,这些值具有我进行硬编码的值(稍后,我将使用JPA来获取具有双向关系的数据,即,您可以从员工那里获得项目,反之亦然。)

private final ObservableList<Jobtitle> jobtitleData
            = FXCollections.observableArrayList(
                    new Jobtitle("Programer", 60),
                    new Jobtitle("Accountant", 70));

private final ObservableList<Person> employeeData
        = FXCollections.observableArrayList(
                new Person("Jacob", jobtitleData.get(0), new Date()),
                new Person("Peter", jobtitleData.get(1), new Date()),);

private final ObservableList<Project> projectData
        = FXCollections.observableArrayList(
                new Project("Projekt A", employeeData),
                new Project("Projekt B", employeeData));


我已经读过tutorial by Oracle,但是它们只涉及基本类型。

最佳答案

TreeTableView<T>中,T是树表的每一行表示的项目的类型。

设置的问题是您声明了TreeTableView<Project>,但并非每行都表示Project:有些行表示Project,有些行表示Employee

我可以看到没有特别优雅的解决方案。您可以简单地声明一个TreeTableView<Object>,然后在单元格值工厂中对cellData.getValue()进行一些类型检查(和向下转换),以确定如何为该单元格创建适当的值(例如,如果((Employee)value).firstnameProperty())是一个和Employee(如果没有)。但是,这是非常不令人满意的。

另一种选择是创建专门用于new ReadOnlyStringWrapper("")ProjectEmployeeItem类。你可以做类似的事情

public class ProjectEmployeeItem {
    private final StringProperty name = new SimpleStringProperty(this, "name", "");
    private final StringProperty firstName new SimpleStringProperty(this, "firstname", "");
    private final ObjectProperty<JobTitle> title new SimpleObjectProperty<>(this, "title", null);
    private final ObjectProperty<LocalDate> birthday new SimpleObjectProperty<>(this, "birthday", null);

    // property, get, and set methods ...

    public ProjectEmployeeItem() {
    }

    public ProjectEmployeeItem(Project project) {
        name.bindBidirectional(project.nameProperty());
    }

    public ProjectEmployeeItem(Employee employee) {
        firstname.bindBidirectional(employee.firstnameProperty());
        title.bindBidirectional(employee.titleProperty());
        birthday.bindBidirectional(employee.birthdayProperty());
    }
}


然后创建一个TreeTableView并执行类似的操作

TreeItem<ProjectEmployeeItem> root = new TreeItem<>(new ProjectEmployeeItem());
for (Project project : projectData) {
    TreeItem<ProjectEmployeeItem> projectTreeItem = new TreeItem<>(new ProjectEmployeeItem(project));
    for (Employee employee : project.getEmployees()) {
        TreeItem<ProjectEmployeeItem> employeeTreeItem = new TreeItem<>(new ProjectEmployeeItem(employee));
        projectTreeItem.getChildren().add(employeeTreeItem);
    }
    root.getChildren().add(projectTreeItem);
}


可能存在涉及对TreeTableView<ProjectEmployeeItem>进行子类化的更好的解决方案,但要花费比我要花的时间要更多的时间,而不是看到这种方法是否更好(或根本没有效果)。

10-04 18:29