2

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

-fx-selection-bar-text: white;

但这不适用于 ListView。

更新:上述情况发生在使用 CellFactories 渲染单元格时。

lvRooms.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
        @Override public ListCell<String> call(ListView<String> list) {
            return new 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); 

            }
        }
    }
4

1 回答 1

5

-fx-selection-bar-text是在根默认 CSS 选择器中定义的调色板(不是 css 属性),它是Scene. 我不知道你是如何使用它的,但如果你定义它(全局因为它是场景的选择器),比如:

.root{
    -fx-selection-bar-text: red;
}

在您的 CSS 文件中,所有使用的控件的 CSS 属性-fx-selection-bar-text都将变为红色。ListView也会受到影响(请参阅下面注释掉的原始用法)。
但是,如果您只想自定义 ListView 的样式,请以这种方式覆盖默认属性
(注意:仅-fx-text-fill被覆盖。原始值被注释掉,在哪里-fx-selection-bar-text使用):

/* 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;
}

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


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

...我们仅使用很少的单元来表示非常大的数据集。每个 Cell 都被“回收”或重复使用。

请注意,不同的字符串项目可能使用相同的单元格,并以误导性的视觉效果/渲染结尾,就像isSelected()在您的代码中一样。另外在API中它说

因为到目前为止,单元格最常见的用例是向用户显示文本,所以此用例专门针对 Cell 内部进行了优化。这是由从 Labeled 扩展的 Cell 完成的。这意味着 Cell 的子类只需要设置 text 属性,而不是创建一个单独的 Label 并在 Cell 中设置它。

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

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

单元格文本的所有-fx-text-fill样式将根据 CSS 文件中的定义进行更改。

现在这里是单元格的文本阴影效果和它的 CSS 文件填充颜色之间的权衡:
-- 如果你想使用阴影效果,你应该像现在这样,即创建标签,设置它的文本,给 dorpshadow 效果标签和 setGraphic(标签)。但是这一次您不会喜欢设置setText(item)单元格的文本 ( ),因此 CSS 文件中的文本颜色样式将不起作用。
-- 另一方面,如果您更喜欢我重构的代码,那么您应该通过将其设置为或并在 CSS 文件中设置为 dropshadow 来禁用-fx-background-color单元格(扩展Labeled),以便能够将阴影效果应用于直接发文。清除单元格的背景不是 IMO 的首选方式。代码解释:transparentnull-fx-effect

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

测试它们以查看差异。就这样。

于 2012-06-16T12:49:08.250 回答