TL; версия DR: вы путаете cellValueFactory
с cellFactory
. См., Например, этот учебник для хорошего объяснения разницы, которая обобщена для этого конкретного примера ниже.
Столбец таблицы cellValueFactory
- это объект, который сообщает столбцу , какие значения отображать в ячейках, или, точнее, как получить эти значения из объектов, представляющих каждую строку. Это представлено Callback<CellDataFeatures<Holiday, LocalDate>, ObservableProperty<LocalDate>>
, то есть функцией, отображающей CellDataFeatures<Holiday, LocalDate>
в ObservableValue<LocalDate>
. Так что в коде Java вы должны сделать
dateColumn.setCellValueFactory(holidayRowData -> holidayRowData.getValue().dateProperty());
или, если вы предпочитаете использовать (несколько устаревший) класс PropertyValueFactory
, вы можете сделать
dateColumn.setCellValueFactory(new PropertyValueFactory<>("date"));
Последняя версия имеет (много недостатков, но единственное) преимущество, заключающееся в том, что это можно сделать и в FXML. Обратите внимание, что вы хотите cellValueFactory
, а не cellFactory
. Так что ваш FXML должен быть
<TableView fx:id="tableView">
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
</columnResizePolicy>
<columns>
<TableColumn text="Holiday Name">
<cellValueFactory>
<PropertyValueFactory property="name"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Date">
<cellValueFactory>
<PropertyValueFactory property="date" />
</cellValueFactory>
</TableColumn>
</columns>
</TableView>
cellFactory
, напротив, является объектом, который указывает столбцу , как отображать данные. Он представлен Callback<TableColumn<Holiday, LocalDate>, TableCell<Holiday, LocalDate>>
, то есть функцией, отображающей TableColumn<Holiday, LocalDate>
в TableCell<Holiday, LocalDate>
. ClassCastException
происходит потому, что заданная вами фабрика ячеек будет передана TableColumn
, но ожидает получения CellDataFeatures
, и поэтому, когда она пытается обработать ее как таковую, приведение не выполняется.
Возможно, вы захотите указать здесь фабрику ячеек, в дополнение к фабрике значений ячеек, чтобы вы могли контролировать как отображать дату (например, управлять форматом, используемым для нее). Если вы зададите для столбца даты fx:id
, скажем <TableColumn fx:id="dateColumn">
и вставите его в контроллер с помощью
@FXML
private TableColumn<Holiday, LocalDate> dateColumn ;
затем в методе инициализации контроллера вы можете сделать:
public void initialize() throws IOException {
data = new HolidayData();
data.loadHolidays();
tableView.setItems(data.getHolidays());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
dateColumn.setCellFactory(column -> new TableCell<Holiday, LocalDate>() {
@Override
protected void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
if (empty) {
setText("");
} else {
setText(formatter.format(date));
}
}
});
}