当使用CellFactory时,Javafx ListView选择栏文本颜色 [英] Javafx ListView selection bar text color when using CellFactory

查看:344
本文介绍了当使用CellFactory时,Javafx ListView选择栏文本颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在列表视图中更改选择栏文本颜色?
优选使用CSS。在TableView中,您可以使用:

  -fx-selection-bar-text:white; 

但这不适用于ListView。



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

  lvRooms。 setCellFactory(new Callback< ListView< String>,ListCell< String>>(){
@Override public ListCell< String> call(ListView< String> list){
return new RoomCell b $ b}
});

在单元格工厂类中,我很乐意覆盖选择行时的情况。 p>

:在开始时只调用一次,而不是每次移动选择栏时调用,因此isSelected()方法总是返回false 。



UPDATE 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); //房间名称将显示在这里
lbl.setFont(Font.font(Segoe UI,FontWeight.BOLD,18));
lbl.setStyle( - fx-text-fill:black);

//lbl.setTextFill(isSelected()?Color.WHITE:Color.BLACK);
if(isSelected())//这总是false:(
lbl.setStyle( - fx-text-fill:yellow);

if 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 -yang.png)));
lbl.setEffect(new DropShadow(15,Color.WHITE));
}
setGraphic(lbl);

}
}
}


解决方案

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

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

然后所有控件的css属性使用 -fx-selection-bar-text 将为红色。 ListView 也会受到影响(请参阅下面注释掉的原始用法)。

但是如果您只想自定义ListView的样式,请覆盖默认属性这样

(注意:只有 -fx-text-fill 被覆盖。原始值被注释掉,其中 -fx使用选择条形文本):

  / *和聚焦* / 
.list-view:focused .list-cell:filled:focused:selected {
-fx-background-color:-fx-focus-color,-fx-cell-focus-内部边框,-fx选择栏;
-fx-background-insets:0,1,2;
-fx-background:-fx-accent;
/ * -fx-text-fill:-fx-selection-bar-text; * /
-fx-text-fill:red;
}

/ *当选择并选择列表单元格但未聚焦时。
在选择了多个项目但未聚焦时应用* /
.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;
}

/ *当选择列表单元格时,焦点和鼠标悬停* /
.list-view:focused .list-cell:filled:focused: 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 。从那里


...我们用极少的单元格表示极大的数据集。
每个单元格都被回收或重用。


警告不同的String项目可能使用相同的单元格,以误导的视觉效果/效果图结尾,例如 isSelected()。此外,在API中,它表示


因为目前为止,单元格最常见的用例是向
用户显示文本用例在Cell内特别优化。这是由从Labeled延伸的Cell完成的
。这意味着
Cell的子类只需要设置text属性,而不是创建一个单独的
Label并在单元格中设置。


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

 code> 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); //图像将显示在这里
setText(item); //房间名称将显示在这里
}
}
}

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



现在这里是单元格的文本阴影效果和它的CSS文件的填充颜色之间的折衷:

- 如果你想使用dropshadow效果,你应该像当前的方式,即创建标签,设置其文本,给标签和setGraphic(标签)dorpshadow效果。但是这次你不喜欢设置单元格的文本( setText(item)),因此CSS文件中的文本颜色样式将没有效果。

- 另一方面,如果你喜欢我重构的代码,那么你应该禁用单元格的 -fx-background-color (扩展<$将 transparent null 设置为 code> -fx-effect 到CSS文件中的dropshadow,以便能够直接对文本应用dropshadow效果。清除单元格的背景不是IMO的首选方式。代码解释:

 标签lbl = new Label(此文本将直接在自身上有一个阴影 
lbl.setEffect(new DropShadow(15,Color.BLUE));

标签another_lbl = new Label(此文本将在背景边界上应用阴影,而不是应用于文本);
another_lbl.setEffect(new DropShadow(15,Color.BLUE));
another_lbl.setStyle( - fx-background-color:gray);

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


Is there any way to change the selection bar text color in a list view? Preferably using CSS. In a TableView, you can use:

-fx-selection-bar-text: white;

But this does not work for a ListView.

UPDATE: The above case happens when using CellFactories to render the cells.

lvRooms.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
        @Override public ListCell<String> call(ListView<String> list) {
            return new RoomCell();
        }
    });

In the Cell Factory class, I'd gladly cover the case when the row is selected.

But: It is called just once at the beginning, not every time the selection bar is moved, and therefore the isSelected() method always renders false.

UPDATE 2: This is the RoomCell implementation:

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

            }
        }
    }

解决方案

-fx-selection-bar-text is a color palette (not css property) defined in a root default CSS selector, which is selector of the Scene. I don't know how are you using it but if you define it (globally since it is scene's selector) like:

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

in your CSS file then all controls' css properties using -fx-selection-bar-text will be red. ListView will be affected as well (see commented out original usages below).
However if you want to customize the ListView's style only, override the default properties this way
(Note: only -fx-text-fill are overriden. Original values are commented out, where -fx-selection-bar-text is used):

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

These CSS properties and more are avaliable in built-in caspian.css.


UPDATE: I strongly advice you to read the Cell API. From there

... We represent extremely large data sets using only very few Cells. Each Cell is "recycled", or reused.

Be warned about the different String items may use the same cell, ending with misleading visual effects/renderings, like isSelected() in your code. Additionally in API it says

Because by far the most common use case for cells is to show text to a user, this use case is specially optimized for within Cell. This is done by Cell extending from Labeled. This means that subclasses of Cell need only set the text property, rather than create a separate Label and set that within the Cell.

So I refactored your code as follows.

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

All -fx-text-fill styles of the cell's text will change according to definitions in CSS file.

Now here is a trade-off between cell's text dropshadow effect and its fill colors from CSS file:
-- if you want to use dropshadow effect, you should go like current way, namely creating label, setting its text, give dorpshadow effect to the label and setGraphic(label). However this time you will not prefer to set the text (setText(item)) of the cell thus text color styles in CSS file will have no effect.
-- On other hand, if you prefer the code that I have refactored, then you should to disable -fx-background-color of the cell (which extends Labeled) by setting it to transparent or null and set the -fx-effect to dropshadow in CSS file to be able to apply dropshadow effect to the text directly. Clearing the background of the cell is not the preferred way either IMO. An explanation by the code:

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

Test them to see the difference. That's all.

这篇关于当使用CellFactory时,Javafx ListView选择栏文本颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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