我有两节课:
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>
进行子类化的更好的解决方案,但要花费比我要花的时间要更多的时间,而不是看到这种方法是否更好(或根本没有效果)。