Listview 如何在JavaFX中基于字符串值以编程方式为列表视图定义颜色

Listview 如何在JavaFX中基于字符串值以编程方式为列表视图定义颜色,listview,javafx-2,highlighting,javafx-8,Listview,Javafx 2,Highlighting,Javafx 8,我需要有能力突出显示列表框中的一行,如果该行中的文本与用户指定的文本匹配,也就是用户说的突出显示所有包含“警告”等字样的行… 我四处打听,发现Alex在哪里教我如何使用样式表 我实现了上面的解决方案。但现在我想对其进行增强,以便用户可以选择多个字符串值的前后底色(第一个指定的值具有最高优先级) 我已经使用了CSS并添加了一个样式,根据是否找到文本,我删除并添加了CSS样式表,以产生如下效果: highlighter.css /** Highlighting for list-view searc

我需要有能力突出显示列表框中的一行,如果该行中的文本与用户指定的文本匹配,也就是用户说的突出显示所有包含“警告”等字样的行… 我四处打听,发现Alex在哪里教我如何使用样式表

我实现了上面的解决方案。但现在我想对其进行增强,以便用户可以选择多个字符串值的前后底色(第一个指定的值具有最高优先级) 我已经使用了CSS并添加了一个样式,根据是否找到文本,我删除并添加了CSS样式表,以产生如下效果:

highlighter.css

/** Highlighting for list-view search result cells */

.list-cell.search-highlight {
-fx-background-color: tomato;
-fx-accent: firebrick;
}

.list-cell:filled:hover.search-highlight {
-fx-background-color: derive(tomato, -20%);
}

.list-cell.search-highlight2 {
-fx-background-color: yellow;
-fx-accent: firebrick;
}

.list-cell:filled:hover.search-highlight2 {
-fx-background-color: derive(yellow, -20%);
}
删除/添加css的java代码 SearchHighlightedTextCell.java

public class SearchHighlightedTextCell extends ListCell<String> {

private static final String HIGHLIGHT_CLASS = "search-highlight";
private static final String HIGHLIGHT_CLASS2 = "search-highlight2";
private StringProperty searchText = new SimpleStringProperty("");
private StringProperty searchText2 =  new SimpleStringProperty("");

SearchHighlightedTextCell(StringProperty searchText, StringProperty searchText2) {
    this.searchText = searchText;
    this.searchText2 = searchText2;
}

@Override
protected void updateItem(String text, boolean empty) {
    super.updateItem(text, empty);

    setText(text == null ? "" : text);

    updateStyleClass();
    searchText.addListener(new InvalidationListener() {
        @Override
        public void invalidated(Observable observable) {
            updateStyleClass();
        }
    });

    searchText2.addListener(new InvalidationListener() {
        @Override
        public void invalidated(Observable observable) {
            updateStyleClass();
        }
    });
}

private void updateStyleClass() {
    try {
        if (!isEmptyString(searchText.get()) && !isEmptyString(getText()) && getText().toUpperCase().contains(searchText.get().toUpperCase())) {           
            getStyleClass().remove(HIGHLIGHT_CLASS2);
            getStyleClass().add(HIGHLIGHT_CLASS);

        } else if (!isEmptyString(searchText2.get()) && !isEmptyString(getText()) && getText().toUpperCase().contains(searchText2.get().toUpperCase())) {
            getStyleClass().remove(HIGHLIGHT_CLASS);
            getStyleClass().add(HIGHLIGHT_CLASS2);            

        } else {
            getStyleClass().remove(HIGHLIGHT_CLASS2);
            getStyleClass().remove(HIGHLIGHT_CLASS);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }             
}

private boolean isEmptyString(String text) {
    return text == null || text.equals("");
}
公共类SearchHighlightedTextCell扩展ListCell{
私有静态最终字符串突出显示\u CLASS=“搜索突出显示”;
私有静态最终字符串突出显示_CLASS2=“search-highlight2”;
private StringProperty searchText=new SimpleStringProperty(“”);
private StringProperty searchText2=新的SimpleStringProperty(“”);
SearchHighlightedTextCell(StringProperty searchText,StringProperty searchText2){
this.searchText=searchText;
this.searchText2=searchText2;
}
@凌驾
受保护的void updateItem(字符串文本,布尔空){
super.updateItem(文本,空);
setText(text==null?“:text);
updateStyleClass();
searchText.addListener(新的invalizationListener(){
@凌驾
公共无效(可观察到){
updateStyleClass();
}
});
searchText2.addListener(新的InvalizationListener(){
@凌驾
公共无效(可观察到){
updateStyleClass();
}
});
}
私有void updateStyleClass(){
试一试{
如果(!isEmptyString(searchText.get())&&&!isEmptyString(getText())&&getText().toUpperCase()包含(searchText.get().toUpperCase()){
getStyleClass().remove(突出显示_CLASS2);
getStyleClass().add(突出显示_类);
}如果(!isEmptyString(searchText2.get())&&!isEmptyString(getText())&&getText().toUpperCase()包含(searchText2.get().toUpperCase()),则为else{
getStyleClass().remove(突出显示_类);
getStyleClass().add(突出显示_CLASS2);
}否则{
getStyleClass().remove(突出显示_CLASS2);
getStyleClass().remove(突出显示_类);
}
}捕获(例外e){
e、 printStackTrace();
}             
}
专用布尔isEmptyString(字符串文本){
返回text==null | | text.equals(“”);
}
这就产生了类似这样的东西

但问题是我不可能定义样式表wrt前景色和背景色中的所有组合。 是否有一种方法可以根据用户的首选项以编程方式手动添加样式表。 还是有其他方法可以做到这一点。 这是我为用户设计的屏幕,用于指示应该突出显示的内容


据我所知,JavaFX 2.2目前缺少该功能。到目前为止,我在这些情况下所做的是以编程方式创建CSS文件,将其写入临时文件,并在用户选择新首选项时将其添加为样式表。当然,这是一个非常棘手的解决方法


另一种可能,尽管可以说更不干净,但根本不使用具体的CSS类,直接使用
Node#setStyle(String)

操作元素的样式。通过在listview上使用cellfactory,您可以轻松地做到这一点

listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
            @Override
            public ListCell<String> call(ListView<String> stringListView) {
                return new ListCell<String>(){
                    @Override
                    protected void updateItem(String s, boolean b) {
                        super.updateItem(s, b);    //To change body of overridden methods use File | Settings | File Templates.
                        if (b) {
                            setText(null);
                            setGraphic(null);
                        }
                        if (s.contains("warning")){
                            setStyle(your style here);
                                    setGraphic(your graphics);
                            setText(your text);
                        }
                        if (s.contains("error")){
                            setStyle(your style here);
                            setGraphic(your graphics);
                            setText(your text);
                        }
                    }
                };
            }
        });
listView.setCellFactory(新回调(){
@凌驾
公共ListCell调用(ListView stringListView){
返回新的ListCell(){
@凌驾
受保护的void updateItem(字符串s,布尔值b){
super.updateItem(s,b);//要更改重写方法的主体,请使用文件|设置|文件模板。
如果(b){
setText(空);
设置图形(空);
}
如果(s.包含(“警告”)){
setStyle(你在这里的风格);
设置图形(您的图形);
setText(您的文本);
}
如果(s.包含(“错误”)){
setStyle(你在这里的风格);
设置图形(您的图形);
setText(您的文本);
}
}
};
}
});