java - 如何根据 JavaFX 中的条件设置 ListView 单元格的样式

标签 java css listview javafx

我正在尝试根据条件设置 ListView 中单个单元格的样式。 ListView 是Label类型,在 ListView 中插入标签时,根据另一个类判断条件。

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

enter image description here

我也研究过这篇文章,但它不适合我的情况,因为用于突出显示 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/

相关文章:

java - 在 Swing 中叠加多个 JSlider

javascript - jsPlumb setContainer 方法不存在 : "Uncaught TypeError: undefined is not a function"

css - 如何在div中隐藏p1

css - 高度 :100px to auto 之间的 CSS 过渡问题

c# - 回收 ListView 中这个看不见的、吞噬性能的单元格是什么?

java - 为高响应服务器应用程序调整 JVM (GC)

java - 我的内联图像未在 java 邮件 API 中加载,并带有其他一些 HTML 内容

listview - 如何为 ListView 的 ContextActions 的 MenuItem 添加可见性绑定(bind)

Android 在不再可见时停止异步加载列表元素

java - Android 版 Google 登录无法正常工作,并出现安全警告