代码之家  ›  专栏  ›  技术社区  ›  ihsan ikbal

JavaFX ListView使用cellfactory更新选定的单元格视图

  •  1
  • ihsan ikbal  · 技术社区  · 7 年前

    在这里,我使用cellfactory创建了一个自定义listview,并使用自定义节点进行了更新,但我需要在选择单元格时更改图形(内容)。我知道我们使用css来改变选定单元格的外观,但在这里我想在listview中更新选定单元格的图形(内容) 不是背景色或文本颜色 .有没有办法做到这一点??

    通常我的listview层次结构是这样的

    Hbox->标签1,标签2

    但当我选择任何单元格时,它应该(仅选择的单元格)如下更新

    Hbox->标签1、标签2、标签3、标签4、按钮1

    Callback<ListView<CustomListView>, ListCell<CustomListView>> cellFactory = new Callback<ListView<CustomListView>, ListCell<CustomListView>>() 
    { 
    
        @Override
            public ListCell<CustomListView> call(ListView<CustomListView> arg0) 
        {
    
            cell = new ListCell<CustomListView>() 
            {
    
                    @Override
                    protected void updateItem(CustomListView item, boolean bln) 
                {
    
                    super.updateItem(item, bln);
                                if(item == null)
                                {
                                    setGraphic(null);
                                    setText(null);
                                    return;
                                }
                                else
                    {
                        //Normally my listview will display like this(An HBOX with 2 Labels)
    
                        HBox h1 =new HBox();
                        Label itemName=new Label("item1);
                        Label price=new Label("100");
                        h1.getchildren.addAll(itemName,price);
                        setGraphic(h1);
    
                        //When i select any cell it should  display like this((An Hbox with 4 Labels(selected cell only,remaining cells in first format))
    
                        HBox h2 =new HBox();
                        Label itemName=new Label("item1);
                        Label price=new Label("100");
                        Label Discount=new Label("50%");
                        Label Tax=new Label("5%");  
                        Button b1=new Button();
                        h2.getchildren.addAll(itemName,price,discount,tax,b1); 
                        setGraphic(h2);
    
                        //i have tried with these lines of codes but it does not working properly
                        cell.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
                        if(isNowSelected==false)//not selected
                       {
                            //load hbox1
                        }
                        else //selected
                        { 
                            //load hbox2
                        }
    
    
    
                    }
                                 }
            }; return cell;
        }
    };
        listView.setCellFactory(cellFactory);
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   fabian    7 年前

    首先 Cell 设计用于在显示不同项目时防止不必要的节点创建。因此,您不应该每次都重新创建节点 updateItem 被称为。此外,您永远不会将侦听器从 selected 这意味着可能有很多 HBox 已更新的,将不再可见的。此外,您的代码中也存在一些错误,使其无法编译。。。

    不过,以下代码应该可以工作:

    listView.setCellFactory(l -> new ListCell<CustomListView >() {
    
        // create all nodes that could be displayed
        private final Label itemName = new Label("item1");
        private final Label price = new Label("100");
        private final HBox contentContainer = new HBox();
    
        private final Label discount = new Label("50%");
        private final Label tax = new Label("5%");
        private final Button button = new Button();
    
        {
            // update HBox every time the selection changes
            selectedProperty().addListener((observable, oldValue, newValue) -> {
                CustomListView item = getItem();
                if (!isEmpty() && item != null) {
                    updateItemSelection(item, newValue);
                }
            });
        }
    
        @Override
        protected void updateItem(CustomListView  item, boolean empty) {
            super.updateItem(item, empty);
    
            if (empty || item == null) {
                setGraphic(null);
            } else {
                setGraphic(contentContainer);
                updateItemSelection(item, isSelected());
            }
        }
    
        private void updateItemSelection(CustomListView item, boolean selected) {
            // update for HBox for non-empty cells based on selection
            if (selected) {
                contentContainer.getChildren().setAll(itemName, price, discount, tax, button);
            } else {
                contentContainer.getChildren().setAll(itemName, price);
            }
        }
    
    });