如何根据JavaFX中的条件设置列表视图单元格的样式

如何根据JavaFX中的条件设置列表视图单元格的样式,java,css,listview,javafx,Java,Css,Listview,Javafx,我试图根据条件设置列表视图中单个单元格的样式。列表视图的类型为Label,将标签插入列表视图时,根据另一个类确定条件 目前,我试图在列表视图中设置每个标签的背景颜色,但它并没有覆盖整个区域(见图) 我也研究过这篇文章,但它不适合我的情况,因为字符串中没有突出显示列表视图单元格的标识符 目前的代码: for (Consultation c : notifications){ Label l = new Label(": consult reminder - " + c

我试图根据条件设置列表视图中单个单元格的样式。列表视图的类型为Label,将标签插入列表视图时,根据另一个类确定条件

目前,我试图在列表视图中设置每个标签的背景颜色,但它并没有覆盖整个区域(见图)

我也研究过这篇文章,但它不适合我的情况,因为字符串中没有突出显示列表视图单元格的标识符

目前的代码:

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);
}

有什么想法吗?

使用节点子类(如
标签
)作为控件(如
列表视图
表格视图
等)的数据类型基本上总是错误的。(我能想到的唯一例外是,如果您正在编写GUI构建器,例如场景构建器,其中的数据实际上是实际的GUI节点。即使这样,您也可能会发现它工作得不太好。)GUI节点类的创建成本非常高;它们通常有数百个属性,以及与样式和CSS解析、事件侦听器等相关的大量开销。将其与实际数据类比较,
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);

使用节点子类(如
标签
)作为控件(如
列表视图
表格视图
)的数据类型基本上总是错误的。(我能想到的唯一例外是,如果您正在编写GUI构建器,例如场景构建器,其中的数据实际上是实际的GUI节点。即使这样,您也可能会发现它工作得不太好。)GUI节点类的创建成本非常高;它们通常有数百个属性,以及与样式和CSS解析、事件侦听器等相关的大量开销。将其与实际数据类比较,
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);

有什么原因导致我现在无法选择此列表中的项目吗?是的,我忘记了调用
super.updateItem(…)
。现在已修复。再次感谢James,这是一个很大的帮助。有什么原因导致我现在无法选择此列表中的项目吗?是的,我忘记了调用
super.updateItem(…)
。现在已修复。感谢詹姆斯,再一次帮了大忙