带有 TableColumns 数组的 JavaFX TableView
JavaFX TableView with array of TableColumns
我有一个TableView<MonthRow>
,我想在其中显示一年中的每个月及其相关日期。
我得到了那三个 类 用于演示目的:
public record DayCell(
LocalDate date,
DayType type
) {
public String nameOfDay() {
return DateTimeFormatter.ofPattern("EE", Locale.ENGLISH).format(date);
}
}
public enum DayType {
COMPASSIONATE_LEAVE("C"),
EMPTY("E"),
NOT_ON_PAYROLL("N"),
QUARANTINE("Q"),
REGULAR_LEAVE("R"),
SICK_LEAVE("S"),
TRAINING("TRG"),
TRAVEL("T"),
UNPAID_LEAVE("U");
private final String shortName;
DayType(String shortName) {
this.shortName = shortName;
}
}
public record MonthRow(
String name,
DayCell[] days // amount of days in that specific month
) {
}
然后我创建 table 内容:
public ObservableList<MonthRow> createMonth(int year) {
MonthRow[] months = new MonthRow[12];
for (int i = 0; i < months.length; i++) {
LocalDate date = LocalDate.of(year, i + 1, 1);
months[i] = new MonthRow(date.getMonth().getDisplayName(TextStyle.FULL, Locale.ENGLISH), createCells(date));
}
return FXCollections.observableArrayList(months);
}
public DayCell[] createCells(LocalDate date) {
DayCell[] cells = new DayCell[date.lengthOfMonth()];
for (int i = 0; i < cells.length; i++) {
cells[i] = new DayCell(date.plusDays(i), DayType.EMPTY);
}
return cells;
}
现在有了用于 TableView 的 ObservableList,我有点卡住了。我想为月份设置一个 TableColumn,为 DayCell 设置 31 个 TableColumns。但是,因为它是一个数组,所以我不确定如何将每个 DayCell 的 cellData 反映到每个 TableCell 中。
另外,因为有些月份没有 31 天,因此,
单元格不应显示缺失日期的任何内容。
每个单元格应根据 DayType
显示 nameOfDay()
内容和颜色(将在某个时候在各自的 cellFactory 中完成)。
TableView Example
这可能是一个完全错误的方法,所以请不要犹豫,指导我寻找不同的解决方案。
你可以这样做:
TableView<MonthRow> table = new TableView<>();
TableColumn<MonthRow, String> monthColumn = new TableColumn<>("Month");
monthColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getName()));
table.getColumns().add(monthColumn);
for (int i = 0; i < 31 ; i++) {
TableColumn<MonthRow, DayCell> dayColumn = new TableColumn<>(Integer.toString(i+1));
final int index = i ;
dayColumn.setCellValueFactory(cellData -> {
MonthRow month = cellData.getValue();
if (index < month.getDays().size()) {
return new SimpleObjectProperty<>(month.getDays()[index]);
} else {
return new SimpleObjectProperty<>(null);
}
});
dayColumn.setCellFactory(new TableCell<>() {
@Override
protected void updateItem(DayCell day, boolean empty) {
super.updateItem(day, empty);
if (empty | day == null) {
setText("");
} else {
setText(day.nameOfDay());
}
}
});
table.getColumns().add(dayColumn);
}
This might be a completely wrong approach
也许吧。您在这里需要 TableView
的功能吗?例如。选择一个月(行)等?也许 ScrollPane
中的简单 GridPane
会是一种更方便的方法;这实际上取决于您的项目要求。
我有一个TableView<MonthRow>
,我想在其中显示一年中的每个月及其相关日期。
我得到了那三个 类 用于演示目的:
public record DayCell(
LocalDate date,
DayType type
) {
public String nameOfDay() {
return DateTimeFormatter.ofPattern("EE", Locale.ENGLISH).format(date);
}
}
public enum DayType {
COMPASSIONATE_LEAVE("C"),
EMPTY("E"),
NOT_ON_PAYROLL("N"),
QUARANTINE("Q"),
REGULAR_LEAVE("R"),
SICK_LEAVE("S"),
TRAINING("TRG"),
TRAVEL("T"),
UNPAID_LEAVE("U");
private final String shortName;
DayType(String shortName) {
this.shortName = shortName;
}
}
public record MonthRow(
String name,
DayCell[] days // amount of days in that specific month
) {
}
然后我创建 table 内容:
public ObservableList<MonthRow> createMonth(int year) {
MonthRow[] months = new MonthRow[12];
for (int i = 0; i < months.length; i++) {
LocalDate date = LocalDate.of(year, i + 1, 1);
months[i] = new MonthRow(date.getMonth().getDisplayName(TextStyle.FULL, Locale.ENGLISH), createCells(date));
}
return FXCollections.observableArrayList(months);
}
public DayCell[] createCells(LocalDate date) {
DayCell[] cells = new DayCell[date.lengthOfMonth()];
for (int i = 0; i < cells.length; i++) {
cells[i] = new DayCell(date.plusDays(i), DayType.EMPTY);
}
return cells;
}
现在有了用于 TableView 的 ObservableList,我有点卡住了。我想为月份设置一个 TableColumn,为 DayCell 设置 31 个 TableColumns。但是,因为它是一个数组,所以我不确定如何将每个 DayCell 的 cellData 反映到每个 TableCell 中。 另外,因为有些月份没有 31 天,因此, 单元格不应显示缺失日期的任何内容。
每个单元格应根据 DayType
显示 nameOfDay()
内容和颜色(将在某个时候在各自的 cellFactory 中完成)。
TableView Example
这可能是一个完全错误的方法,所以请不要犹豫,指导我寻找不同的解决方案。
你可以这样做:
TableView<MonthRow> table = new TableView<>();
TableColumn<MonthRow, String> monthColumn = new TableColumn<>("Month");
monthColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getName()));
table.getColumns().add(monthColumn);
for (int i = 0; i < 31 ; i++) {
TableColumn<MonthRow, DayCell> dayColumn = new TableColumn<>(Integer.toString(i+1));
final int index = i ;
dayColumn.setCellValueFactory(cellData -> {
MonthRow month = cellData.getValue();
if (index < month.getDays().size()) {
return new SimpleObjectProperty<>(month.getDays()[index]);
} else {
return new SimpleObjectProperty<>(null);
}
});
dayColumn.setCellFactory(new TableCell<>() {
@Override
protected void updateItem(DayCell day, boolean empty) {
super.updateItem(day, empty);
if (empty | day == null) {
setText("");
} else {
setText(day.nameOfDay());
}
}
});
table.getColumns().add(dayColumn);
}
This might be a completely wrong approach
也许吧。您在这里需要 TableView
的功能吗?例如。选择一个月(行)等?也许 ScrollPane
中的简单 GridPane
会是一种更方便的方法;这实际上取决于您的项目要求。