Css 使用CellFactory时的Javafx ListView选择栏文本颜色

Css 使用CellFactory时的Javafx ListView选择栏文本颜色,css,listview,javafx-2,Css,Listview,Javafx 2,是否有任何方法可以更改列表视图中的选择栏文本颜色? 最好使用CSS。在TableView中,您可以使用: -fx-selection-bar-text: white; 但这不适用于ListView 更新:使用CellFactorys渲染单元格时会发生上述情况 lvRooms.setCellFactory(new Callback<ListView<String>, ListCell<String>>() { @Override public

是否有任何方法可以更改列表视图中的选择栏文本颜色? 最好使用CSS。在TableView中,您可以使用:

-fx-selection-bar-text: white;
但这不适用于ListView

更新:使用CellFactorys渲染单元格时会发生上述情况

lvRooms.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
        @Override public ListCell<String> call(ListView<String> list) {
            return new RoomCell();
        }
    });
lvRooms.setCellFactory(新回调(){
@覆盖公共ListCell调用(ListView列表){
返回新的RoomCell();
}
});
在Cell Factory类中,当选择行时,我很乐意讨论这个问题

但是:它在开始时只被调用一次,而不是每次移动选择栏时都被调用,因此isSelected()方法总是呈现false

更新2:这是RoomCell实现:

class RoomCell extends ListCell<String> {
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);

            if (item != null) {
                Log.debug("RoomCell called, item: "+item);
                final Label lbl = new Label(item); // The room name will be displayed here
                lbl.setFont(Font.font("Segoe UI", FontWeight.BOLD, 18));
                lbl.setStyle("-fx-text-fill: black");

                //lbl.setTextFill(isSelected()?Color.WHITE: Color.BLACK);
                if (isSelected())  // This is always false :(
                   lbl.setStyle("-fx-text-fill: yellow");

                if (Rooms.getBoolean(item, "OwnerStatus")) {
                    lbl.setEffect(new DropShadow(15, Color.BLUEVIOLET));
                    lbl.setGraphic(new ImageView(
                                    new Image(getClass().getResourceAsStream("images/universal.png"))));
                } else  {
                    lbl.setGraphic(new ImageView(
                                    new Image(getClass().getResourceAsStream("images/yin-yang.png"))));
                    lbl.setEffect(new DropShadow(15, Color.WHITE));
                } 
                setGraphic(lbl); 

            }
        }
    }
class RoomCell扩展了ListCell{
@凌驾
public void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
如果(项!=null){
调试(“调用RoomCell,项:“+item”);
最终标签lbl=新标签(项目);//房间名称将显示在此处
lbl.setFont(Font.Font(“Segoe UI”,fontwweight.BOLD,18));
lbl.setStyle(“-fx文本填充:黑色”);
//lbl.setTextFill(isSelected()?Color.WHITE:Color.BLACK);
if(isSelected())//这始终为false:(
lbl.setStyle(“-fx文本填充:黄色”);
if(Rooms.getBoolean(项目“OwnerStatus”)){
lbl.setEffect(新DropShadow(15,颜色为蓝紫色));
lbl.setGraphic(新图像视图(
新图像(getClass().getResourceAsStream(“images/universal.png”);
}否则{
lbl.setGraphic(新图像视图(
新图像(getClass().getResourceAsStream(“images/yin-yang.png”));
lbl.setEffect(新的DropShadow(15,彩色,白色));
} 
设置图形(lbl);
}
}
}

-fx选择栏文本
是在根默认css选择器中定义的调色板(不是css属性),它是
场景
的选择器。我不知道您如何使用它,但如果您定义它(全局,因为它是场景的选择器),如:

在CSS文件中,使用
-fx选择栏文本的所有控件的CSS属性将变为红色。
ListView
也将受到影响(请参见下面注释掉的原始用法)。
但是,如果只想自定义ListView的样式,请通过这种方式覆盖默认属性
(注意:仅覆盖
-fx文本填充
。原始值被注释掉,其中使用了
-fx选择栏文本
):

这些CSS属性和更多属性在内置的caspian.CSS中可用


更新:我强烈建议您从那里阅读

…我们只使用很少的单元格来表示非常大的数据集。 每个单元都是“回收”或重复使用的

请注意,不同的字符串项可能使用相同的单元格,并以误导性的视觉效果/渲染结束,如代码中的
isSelected()
。此外,在API中还显示

因为到目前为止,单元格最常见的用例是向 用户,这个用例是专门为单元内优化的 这意味着 单元格只需设置文本属性,而无需创建单独的 在单元格中标记并设置

所以我重构了你的代码如下

class RoomCell extends ListCell<String> {
    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);

        if (item != null) {
            Log.debug("RoomCell called, item: "+item);
            setFont(Font.font("Segoe UI", FontWeight.BOLD, 18));
            ImageView iView = new ImageView();
            if (Rooms.getBoolean(item, "OwnerStatus")) {
                iView.setEffect(new DropShadow(15, Color.BLUEVIOLET));
                iView.setImage(new Image(getClass().getResourceAsStream("images/universal.png")));
            } else  {
                iView.setEffect(new DropShadow(15, Color.WHITE));
                iView.setImage(new Image(getClass().getResourceAsStream("images/yin-yang.png")));
            } 
            setGraphic(iView);  // The image will be displayed here
            setText(item); // The room name will be displayed here
        }
    }
}

测试它们以查看差异。仅此而已。

谢谢你,乌鲁克。你的两种解决方案都很好,但在我的情况下不行。正如我在上述问题的更新中所解释的,我使用CellFactory渲染单元格。在这种情况下我能做些什么?是的,我在尝试破解不同的解决方案时总是打开caspian.css文件,这是非常宝贵的资源。@betaman,我已经在官方的ListView教程中测试了这个解决方案。CellFactory也用于定制单元格
ColorRectCell
(扩展ListCell)。发布您的
RoomCell
或将其与
ColorRectCell
进行比较。我刚刚发布了我的RoomCell factory。我查看了ListView教程,不幸的是它只显示颜色矩形,没有文本。是的,实际上我在回答中已经指出了它作为解释。顺便问一下,您如何处理单元格的背景样式?
/* When the list-cell is selected and focused */
.list-view:focused .list-cell:filled:focused:selected {
    -fx-background-color: -fx-focus-color, -fx-cell-focus-inner-border, -fx-selection-bar;
    -fx-background-insets: 0, 1, 2;
    -fx-background: -fx-accent;
    /* -fx-text-fill: -fx-selection-bar-text;  */
    -fx-text-fill: red;
}

/* When the list-cell is selected and selected-hovered but not focused. 
    Applied when the multiple items are selected but not focused */
.list-view:focused .list-cell:filled:selected, .list-view:focused .list-cell:filled:selected:hover {
    -fx-background: -fx-accent;
    -fx-background-color: -fx-selection-bar;
    /* -fx-text-fill: -fx-selection-bar-text;  */
    -fx-text-fill: green;
}

/* When the list-cell is selected, focused and mouse hovered */
.list-view:focused .list-cell:filled:focused:selected:hover {
    -fx-background: -fx-accent;
    -fx-background-color: -fx-focus-color, -fx-cell-focus-inner-border, -fx-selection-bar;
    -fx-background-insets: 0, 1, 2;
    /* -fx-text-fill: -fx-selection-bar-text;  */
    -fx-text-fill: yellow;
}
class RoomCell extends ListCell<String> {
    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);

        if (item != null) {
            Log.debug("RoomCell called, item: "+item);
            setFont(Font.font("Segoe UI", FontWeight.BOLD, 18));
            ImageView iView = new ImageView();
            if (Rooms.getBoolean(item, "OwnerStatus")) {
                iView.setEffect(new DropShadow(15, Color.BLUEVIOLET));
                iView.setImage(new Image(getClass().getResourceAsStream("images/universal.png")));
            } else  {
                iView.setEffect(new DropShadow(15, Color.WHITE));
                iView.setImage(new Image(getClass().getResourceAsStream("images/yin-yang.png")));
            } 
            setGraphic(iView);  // The image will be displayed here
            setText(item); // The room name will be displayed here
        }
    }
}
Label lbl = new Label("This text will have a dropshadow on itself directly");
lbl.setEffect(new DropShadow(15, Color.BLUE));

Label another_lbl = new Label("This text will have a dropshadow applied on the background bounds, not to text");
another_lbl.setEffect(new DropShadow(15, Color.BLUE));
another_lbl.setStyle("-fx-background-color:gray");