如何基于JavaFX中的条件设置列表视图单元格的样式 [英] How to set the style of list view cells based on a condition in JavaFX

查看:97
本文介绍了如何基于JavaFX中的条件设置列表视图单元格的样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to set the style of individual cells in a list view based on a condition. The list view is of type Label, and the condition is determined based on another class when labels are inserted into the listview.

当前,我试图在列表视图中设置每个标签的背景颜色,但是它不能覆盖整个区域(参见图片).

Currently, I have tried to set the background colour of each label in the list view but it doesn't cover the entire area (see picture).

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

I've also researched this article but it doesn't suit my case as the identifier for highlighting the list view cell is not carried in the string.

如何在JavaFX中动态更改列表视图中项目的背景

到目前为止的当前代码:

Current code so far:

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 类型的控件,基本上总是错误的ListViewTableView等.(我唯一想到的例外是,如果您正在编写一个GUI构建器,例如Scene Builder,其中的数据实际上是实际的GUI节点.即使那样,您也可能会找到它不能很好地工作.)GUI节点类的创建非常昂贵;它们通常具有数百个属性,并且与样式和CSS解析,事件侦听器等相关的开销很大.将其与实际数据类Consultation进行比较,它可能具有十几个属性或更少的属性,而没有其他开销.如果将Label或其他节点类用作ListView的数据类型,则为列表中的每个 item 创建一个节点. ListView的全部意义在于,它仅为每个可见的 cell 创建节点,并重用这些单元.因此,如果您的清单很大,那么您的方法可能会导致性能问题. (另一点是您违反了视图(演示文稿)与模型(数据)的分离.)

It is basically always an error to use a node subclass (such as Label) as the data type for controls such as ListView, TableView, etc. (The only exception I can think of is if you were writing a GUI builder, such as Scene Builder, where the data really were the actual GUI nodes. Even then you'd probably find it wouldn't work so well.) GUI node classes are very expensive to create; they typically have hundreds of properties and lots of overhead associated with styling and CSS parsing, event listeners, etc etc. Compare that to your actual data class, Consultation, which probably has a dozen properties or fewer and none of the other overhead. If you use a Label or other node class as the data type for your ListView, you create one node for every item in the list. The whole point of a ListView is that it only creates nodes for each visible cell, and reuses those cells. So if you have a large list, your approach will likely lead to performance issues. (The other point is that you are violating the separation of the view (the presentation) from the model (the data).)

因此,您实际上应该在此处使用ListView<Consultation>,并使用单元格工厂来配置单元格的文本和样式:

So you should really have a ListView<Consultation> here, and use a cell factory to configure the text and style of the cells:

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打开和关闭不同的样式:

It's a little better to factor the style out into an external CSS file. You can use a CSS PseudoClass to turn the different styles on and off:

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文件中执行以下操作:

Now in your external CSS file you can do:

.list-cell:reminder-read {
    -fx-background-color: #33CEFF ;
}

这篇关于如何基于JavaFX中的条件设置列表视图单元格的样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆