所以首先,我试图将一个单元格涂成红色,或者根据另一列的值(同一行)将该单元格设置为红色。 例如,有一个“已注册”日期列和一个“ DeadlineToEnrollBy”日期列。这是一个通用示例。
因此,如果“截止日期”日期是明天,则该单元格不会以红色显示,因为学生还有时间,但是,如果“截止日期”是昨天并且该学生仍未注册,则“已注册”日期单元格将以红色显示,表示立即关注该学生。我实际上可以做到这一点,但是表有时表现得“笨拙”。
如果我快速滚动到底部,则会出现错误。有时,当上下滚动时,红色单元格将位于其他位置,或者列中的所有单元格都将变为红色,即使不应该如此。我相信,即使上传新数据,因此刷新表也会导致红色单元格关闭。
我得到的错误是
Exception in thread "JavaFX Application Thread"
java.lang.IndexOutOfBoundsException
在此行代码上
Person student= ClassPanelView.retrieveTable().getItems.get(getIndex());
这是相关的代码流
在ClassPanelView中
createTable(){
.
.
TableColumn<Person, Date> enrolledBy = new TableColumn<>("Enrolled");
enrolledBy.setCellValueFactory(new PropertyValueFactory<>("dateEnrolled"));
enrolledBy.setCellFactory(column -> {
return new util.EditEnrolledDateCell<Person, Date>();
});
table.getColumns().addAll(enrolledBy, ..etc);
}
public static TableView<Person> retrieveTable() {
return table;
}
该列调用/返回的另一个类/单元格
public class EditEnrolledDateCell<S,T> extends TextFieldTableCell<Person, Date> {
private Date now = new Date();
...
...
@Override
public void updateItem(Date item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
if(this.getIndex() > -1) {
/*int currentIndex = indexProperty().getValue() < 0 ? 0
: indexProperty().getValue(); */
Person student = ClassPanelView.retrieveTable().getItems().get(getIndex()); //<==== This line is the problem
if(student.getDeadline != null && student.getDeadline.before(now)) {
setStyle("-fx-border-color: #f40404;\n"
+ "-fx-border-width: 1 1 1 1;\n");
}
}
}
else { //if there is something here, format it
setStyle("");
setText(GuiUtils.monthFirstDateFormat.format(item));
}
}
}
任何提示/知识将不胜感激!谢谢
答案 0 :(得分:0)
对于从未超过截止日期的人员,您永远不会重置单元格的样式。您需要执行这种更新。此外,表的末尾可能有空单元格,它们具有非负索引。 (只有当单元格为空时,您才尝试检索此人。)
为使单元更可重用,我建议使用TableCell.getTableView
而不是访问static
字段。
@Override
public void updateItem(Date item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setStyle(null);
setText("");
} else {
Person student = getTableView().getItems().get(getIndex());
setStyle(student.getDeadline != null && !now.after(student.getDeadline)
? null
: "-fx-border-color: #f40404; -fx-border-width: 1 1 1 1;");
// I recommend passing the formatter in a constructor to make the cell type easier to reuse
setText(item == null ? "" : GuiUtils.monthFirstDateFormat.format(item));
}
}
注意:您还应该将字段getDeadline
重命名为deadline
。按照惯例,getDeadline
是deadline
属性的getter方法的名称,我想不出为什么以通常用于getter的方式命名字段是一个好习惯。 / p>
我目前也看不到将类型参数添加到自定义单元格类型的原因。这些类型从不使用。
public class EditEnrolledDateCell extends TextFieldTableCell<Person, Date>
在某些情况下,您可能希望保留这些内容。如果要将单元格与TableView<T>
一起使用,其中T
是Person
的子类型,或者在列中使用值为Date
的子类型的值类型,但这需要不同的声明:
public class EditEnrolledDateCell<S extends Person, T extends Date> extends TextFieldTableCell<S, T> {
...
@Override
public void updateItem(T item, boolean empty) {
...
此外,如果可能的话,我建议使用LocalDate
而不是Date
,因为这种类型更现代/更易于使用。