【问题标题】:How to easy customize JavaFX ListCell background color while selecting and unselecting cells如何在选择和取消选择单元格时轻松自定义 JavaFX ListCell 背景颜色
【发布时间】:2016-03-31 16:20:28
【问题描述】:

我有以下问题:

我有ListView<ViewsRecord>,其中ViewsRecord 有属性int favorites。 如果favorites > 0 是收藏夹,如果favorites == 0 是常规行(不是收藏夹)。

现在我想做的是:

  1. 当用户选择单元格(在多选模式下)时,这些单元格将具有默认选定背景(例如:-fx-background-color: -fx-selection-bar
  2. 当用户没有选择单元格时:

    2.1。如果单元格不在收藏夹中,则它具有常规的免费(例如白色)

    2.2。如果单元格在收藏夹中,则其背景为绿色

到目前为止,我想出了这个解决方案,但它是丑陋的代码,我想知道是否有最简单的方法来做到这一点。 此外,我不得不使用setUserData() 来检查是否应该选择单元格,否则在列表滚动或选择期间 - 单元格随机更改了它们的颜色。 (我认为这是因为可重用对象存储在内存中,并且 updateItem() 并不总是被触发)。

这是我的代码:

list.setCellFactory(new Callback<ListView<ViewsRecord>, ListCell<ViewsRecord>>(){
            @Override
            public ListCell<ViewsRecord> call(ListView<ViewsRecord> param) {
                ListCell<ViewsRecord> cell = new ListCell<ViewsRecord>(){
                         @Override
                        protected void updateItem(ViewsRecord item, boolean empty) {
                            super.updateItem(item, empty);
                            if(!empty){
                                if(item.getFavorites() > 0){  //favorite view
                                    if(!isSelected()){
                                        setStyle("-fx-background-color: darkseagreen;");
                                    }
                                    setUserData(new Integer(1));
                                } else {  //normal view
                                    if(!isSelected()){
                                        setStyle("-fx-background-color: white;");
                                    }
                                    setUserData(new Integer(0));
                                }
                                setText(item.toString());
                            } else { //empty view
                                setText(null); 
                                setStyle("-fx-background-color: white;");
                                setUserData(new Integer(0)); 
                            }
                        }
                    };
                //fix bacground color when cell is selected
                cell.selectedProperty().addListener( (obsVal, oldVal, newVal) -> {
                    if(newVal){
                        cell.setStyle("-fx-background-color: -fx-selection-bar;");
                    } else {
                        if((Integer)cell.getUserData() == 1){ //favorite
                            cell.setStyle("-fx-background-color: darkseagreen;");
                        } else { //normal
                            cell.setStyle("-fx-background-color: white;");
                        }
                    }
                });
                return cell;
            }   
        });

编辑

感谢jns,我设法简化了代码。 当前版本:

list.setCellFactory(new Callback<ListView<ViewsRecord>, ListCell<ViewsRecord>>(){   
            @Override
            public ListCell<ViewsRecord> call(ListView<ViewsRecord> param) {
                final PseudoClass FAVORITE_PSEUDO_CLASS = PseudoClass.getPseudoClass("favorite");
                ListCell<ViewsRecord> cell = new ListCell<ViewsRecord>(){
                         @Override
                        protected void updateItem(ViewsRecord item, boolean empty) {
                            if(!empty){
                                //favorite or not, and not selected
                                pseudoClassStateChanged(FAVORITE_PSEUDO_CLASS, (item.getFavorites() > 0) && !isSelected());
                                setText(item.toString());
                            } else { 
                                setText(null); 
                                //empty
                                pseudoClassStateChanged(FAVORITE_PSEUDO_CLASS, false);
                            }
                            super.updateItem(item, empty);
                         }
                };
                cell.selectedProperty().addListener( (obsVal, oldVal, newVal) -> {
                    if(newVal){
                        //selected
                        cell.pseudoClassStateChanged(FAVORITE_PSEUDO_CLASS, false); 
                    } else {
                        //favorite or not
                        cell.pseudoClassStateChanged(FAVORITE_PSEUDO_CLASS, cell.getItem().getFavorites() > 0); 
                    }
                });
                return cell;
            }
        });

【问题讨论】:

    标签: javafx javafx-8


    【解决方案1】:

    您可以使用 PseudoClass 根据喜爱的属性设置列表单元的样式。

    public class YourListCell extends ListCell<ViewsRecord> {
    
    private static PseudoClass FAVORITE_PSEUDO_CLASS = PseudoClass.getPseudoClass("favorite");
    
        @Override
         protected void updateItem(ViewsRecord item, boolean empty) {
             super.updateItem(item, empty);
             if (!empty) {
                 boolean isFavorite = item > 0;              
                 pseudoClassStateChanged(FAVOURITE_PSEUDO_CLASS, isFavorite);
                 ...
         }
    }
    

    这允许您通过样式表中的 css 设置列表单元格的样式:

    .list-cell:favorite {
    -fx-background-color: darkseagreen;
    }
    

    【讨论】:

      【解决方案2】:

      ListCell 包含一个getItem() 方法。因此,您可以访问您的数据对象。此外,您可以使用其 PseudoClass 为空并选择将更多样式处理转移到样式表:

      .list-cell, .list-cell:empty {
          -fx-background-color: white
          }
      
      .list-cell:favorite{
          -fx-background-color: darkseagreen;
      }
      
      .list-cell:selected {
          -fx-background-color: -fx-selection-bar;
      }
      

      【讨论】:

        猜你喜欢
        • 2016-06-29
        • 2017-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-09
        • 1970-01-01
        • 2018-04-18
        相关资源
        最近更新 更多