我正在尝试根据条件设置 ListView 中单个单元格的样式。 ListView 是Label类型,在 ListView 中插入标签时,根据另一个类判断条件。
目前,我尝试在 ListView 中设置每个标签的背景颜色,但它并没有覆盖整个区域(见图)。
我也研究过这篇文章,但它不适合我的情况,因为用于突出显示 ListView 单元格的标识符未包含在字符串中。
How do I dynamically change the background of an item in a listview in JavaFX
目前的代码:
for (Consultation c : notifications){
Label l = new Label(": consult reminder - " + c.getReminderTime());
if(c.getReminderRead() == 1){ //if the consultation reminder hasn't been read
l.setStyle("-fx-background-color: #33CEFF");
counter = counter + 1;
}
notificationList.getItems().add(l);
}
有什么想法吗?
最佳答案
使用节点子类(例如 Label
)作为控件的 data 类型基本上总是错误的,例如 ListView
, TableView
等等(我能想到的唯一异常(exception)是,如果您正在编写一个 GUI 构建器,例如 Scene Builder,其中数据实际上是实际的 GUI 节点。即使那样您可能会发现它不会很好地工作。 ) GUI 节点类的创建成本非常高;它们通常有数百个属性和大量与样式和 CSS 解析、事件监听器等相关的开销。将其与您的实际数据类进行比较,Consultation
,它可能有十几个或更少的属性,没有其他开销。如果您使用 Label
或其他节点类作为 ListView
的数据类型,您为列表中的每个 item 创建一个节点。整点了ListView
是它只为每个可见的 cell 创建节点,并重用这些 cell。因此,如果您有一个大列表,您的方法可能会导致性能问题。 (另一点是您违反了 View (表示)与模型(数据)的分离。)
所以你真的应该有一个ListView<Consultation>
在这里,并使用一个单元格工厂来配置单元格的文本和样式:
ListView<Consultation> notificationList = ... ;
notificationList.setCellFactory(lv -> new ListCell<Consultation>() {
@Override
protected void updateItem(Consultation c, boolean empty) {
super.updateItem(c, empty);
if (empty) {
setText(null);
setStyle("");
} else {
setText(": consult reminder - " + c.getReminderTime());
// Are you REALLY using an int for the reminderRead property??!?
// Surely this should be a boolean...
if (c.getReminderRead() == 1) { // I feel dirty just writing that
setStyle("-fx-background-color: #33CEFF");
} else {
setStyle("");
}
}
}
});
notificationList.getItems().setAll(notifications);
将样式分解到外部 CSS 文件中会好一些。您可以使用 CSS PseudoClass 来打开和关闭不同的样式:
ListView<Consultation> notificationList = ... ;
PseudoClass reminderRead = PseudoClass.getPseudoClass("reminder-read");
notificationList.setCellFactory(lv -> new ListCell<Consultation>() {
@Override
protected void updateItem(Consultation c, boolean empty) {
super.updateItem(c, empty);
if (empty) {
setText(null);
} else {
setText(": consult reminder - " + c.getReminderTime());
}
// assumes Consultation.getReminderRead() returns a boolean...
pseudoClassStateChanged(reminderRead, c != null && c.getReminderRead())
}
});
notificationList.getItems().setAll(notifications);
现在在您的外部 CSS 文件中您可以:
.list-cell:reminder-read {
-fx-background-color: #33CEFF ;
}
关于java - 如何根据 JavaFX 中的条件设置 ListView 单元格的样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40097025/