如何使用T对象列表作为子项显示TreeTableView

时间:2014-09-25 12:13:06

标签: java javafx javafx-8

我有两个班级:

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

如何以如下格式显示和编辑treetable中的值?

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,但它们只涵盖基本类型。

1 个答案:

答案 0 :(得分:0)

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

您的设置问题是您已声明TreeTableView<Project>,但并非每行都代表Project:某些行代表Project,而某些行代表{{} 1}} S上。

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

另一种选择是创建专门用于new ReadOnlyStringWrapper("")的{​​{1}}类。你可以做点什么

ProjectEmployeeItem

然后你创建一个TreeTableView并执行类似

的操作
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<ProjectEmployeeItem>但是我需要花费更多的时间来看看这种方法是否会更好(或者根本不是......)。