如何在嵌套对象的TableView中显示数据?
How to show data in TableView of nested objects?
我在控制器的 class 中有一个 TableView<Marriage>
:
public class MarriageTableView extends AbstractTableViewController {
@FXML
private TableView<Marriage> tableView;
@FXML
private TableColumn<Groom, String> groomFirstNameColumn, groomLastNameColumn;
@FXML
private TableColumn<Bride, String> brideFirstNameColumn, brideLastNameColumn;
@FXML
private TableColumn<Marriage, LocalDate> marriageDateColumn;
@FXML
void initialize() {
this.groomFirstNameColumn.setCellValueFactory(new PropertyValueFactory<Groom, String>("firstName")); // <- Exception here
this.groomLastNameColumn.setCellValueFactory(new PropertyValueFactory<Groom, String>("lastName"));
this.brideFirstNameColumn.setCellValueFactory(new PropertyValueFactory<Bride, String>("firstName"));
this.brideLastNameColumn.setCellValueFactory(new PropertyValueFactory<Bride, String>("lastName"));
this.marriageDateColumn.setCellValueFactory(new PropertyValueFactory<Marriage, LocalDate>("marriageDate"));
}
在 initialize
方法中,我试图为每个 table 列设置 CellValueFactory
,这样我就可以在我的 table 视图中显示 Marriage
对象.
然而,Marriage 对象由另一个 Groom 和 Bride 类型的对象组成,我试图从中显示一些值。
public class Marriage {
private Groom groom;
private Bride bride;
private LocalDate marriageDate;
}
public class Groom:
{
private String firstName;
private String lastName;
}
public class Bride:
{
private String firstName;
private String lastName;
}
异常我得到:
java.lang.IllegalStateException: Cannot read from unreadable property firstName
如何设置 CellValueFactory
或编辑 TableColumn
的通用参数,以便显示嵌套对象的属性?
一种选择是使用知道如何显示 Groom
和 Bride
的所需数据的自定义单元格实现。例如:
TableColumn<Marriage, Groom> groomCol = ...;
groomCol.setCellValueFactory(new PropertyValueFactory<>("groom"));
groomCol.setCellFactory(tc -> new TableCell<>() {
@Override
protected void updateItem(Groom item, boolean empty) {
super.updateItem(item, empty); // must be called
if (empty || item == null) {
setText(null);
} else {
// replace with desired format
setText(item.getFirstName() + " " + item.getLastName());
}
}
});
请注意,TableColumn
的第一个类型参数必须与 TableView
的类型参数匹配(在本例中为 Marriage
)。
顺便说一句,你真的需要 Groom
和 Bride
class 吗?它们似乎具有相同的信息,并且可以组合成一个 Person
class.
另外,如果可以的话,您应该避免使用 PropertyValueFactory
。它是在 lambda 表达式之前的时代设计的,目的是使代码更简洁。但是使用 lambda 表达式,你可以做同样的事情,但具有编译时安全性(并且你可以避免反射)。但请注意,如果您将模型的属性公开为 JavaFX 属性,则效果最佳。例如:
// model class
public class Marriage {
private final ObjectProperty<Groom> groom = new SimpleObjectProperty<>(this, "groom");
public final void setGroom(Groom groom) { this.groom.set(groom); }
public final Groom getGroom() { return groom.get(); }
public final ObjectProperty<Groom> groomProperty() { return groom; }
// other properties...
}
// table column configuration
TableColumn<Marriage, Groom> groomCol = ...;
groomCol.setCellValueFactory(data -> data.getValue().groomProperty());
groomCol.setCellFactory( ... );
我在控制器的 class 中有一个 TableView<Marriage>
:
public class MarriageTableView extends AbstractTableViewController {
@FXML
private TableView<Marriage> tableView;
@FXML
private TableColumn<Groom, String> groomFirstNameColumn, groomLastNameColumn;
@FXML
private TableColumn<Bride, String> brideFirstNameColumn, brideLastNameColumn;
@FXML
private TableColumn<Marriage, LocalDate> marriageDateColumn;
@FXML
void initialize() {
this.groomFirstNameColumn.setCellValueFactory(new PropertyValueFactory<Groom, String>("firstName")); // <- Exception here
this.groomLastNameColumn.setCellValueFactory(new PropertyValueFactory<Groom, String>("lastName"));
this.brideFirstNameColumn.setCellValueFactory(new PropertyValueFactory<Bride, String>("firstName"));
this.brideLastNameColumn.setCellValueFactory(new PropertyValueFactory<Bride, String>("lastName"));
this.marriageDateColumn.setCellValueFactory(new PropertyValueFactory<Marriage, LocalDate>("marriageDate"));
}
在 initialize
方法中,我试图为每个 table 列设置 CellValueFactory
,这样我就可以在我的 table 视图中显示 Marriage
对象.
然而,Marriage 对象由另一个 Groom 和 Bride 类型的对象组成,我试图从中显示一些值。
public class Marriage {
private Groom groom;
private Bride bride;
private LocalDate marriageDate;
}
public class Groom:
{
private String firstName;
private String lastName;
}
public class Bride:
{
private String firstName;
private String lastName;
}
异常我得到:
java.lang.IllegalStateException: Cannot read from unreadable property firstName
如何设置 CellValueFactory
或编辑 TableColumn
的通用参数,以便显示嵌套对象的属性?
一种选择是使用知道如何显示 Groom
和 Bride
的所需数据的自定义单元格实现。例如:
TableColumn<Marriage, Groom> groomCol = ...;
groomCol.setCellValueFactory(new PropertyValueFactory<>("groom"));
groomCol.setCellFactory(tc -> new TableCell<>() {
@Override
protected void updateItem(Groom item, boolean empty) {
super.updateItem(item, empty); // must be called
if (empty || item == null) {
setText(null);
} else {
// replace with desired format
setText(item.getFirstName() + " " + item.getLastName());
}
}
});
请注意,TableColumn
的第一个类型参数必须与 TableView
的类型参数匹配(在本例中为 Marriage
)。
顺便说一句,你真的需要 Groom
和 Bride
class 吗?它们似乎具有相同的信息,并且可以组合成一个 Person
class.
另外,如果可以的话,您应该避免使用 PropertyValueFactory
。它是在 lambda 表达式之前的时代设计的,目的是使代码更简洁。但是使用 lambda 表达式,你可以做同样的事情,但具有编译时安全性(并且你可以避免反射)。但请注意,如果您将模型的属性公开为 JavaFX 属性,则效果最佳。例如:
// model class
public class Marriage {
private final ObjectProperty<Groom> groom = new SimpleObjectProperty<>(this, "groom");
public final void setGroom(Groom groom) { this.groom.set(groom); }
public final Groom getGroom() { return groom.get(); }
public final ObjectProperty<Groom> groomProperty() { return groom; }
// other properties...
}
// table column configuration
TableColumn<Marriage, Groom> groomCol = ...;
groomCol.setCellValueFactory(data -> data.getValue().groomProperty());
groomCol.setCellFactory( ... );