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

时间:2016-10-17 23:07:19

标签: java css listview javafx

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

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

enter image description here

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

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

任何想法?

1 个答案:

答案 0 :(得分:3)

对于LabelListView等控件,使用节点子类(例如TableView)作为数据类型基本上总是错误的, (我能想到的唯一例外是,如果你正在编写一个GUI构建器,比如Scene Builder,那里的数据确实是实际的GUI节点。即便如此,你可能会发现它不会工作很好。)GUI节点类的创建成本非常高;它们通常具有数百个属性和大量与样式和CSS解析,事件监听器等相关的开销。将它与您的实际数据类Consultation进行比较,该数据类可能具有十几个属性或更少,而不是其他属性高架。如果您使用Label或其他节点类作为ListView的数据类型,则为列表中的每个创建一个节点。 ListView的重点是它只为每个可见的单元格创建节点,并重用这些单元格。因此,如果您有一个大型列表,您的方法可能会导致性能问题。 (另一点是您违反了视图(演示文稿)与模型(数据)的分离。)

所以你应该在这里有一个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 ;
}