1
votes

Here i have created a custom listview using cellfactory and updated with custom nodes,but i need to change the graphic(contents) when i select a cell. i know we use css to change the appearance of selected cell,but here i would like to update graphic(content) of selected cell in listview not background color or text color.Is there any way to do like that??

normally my listview hierarchy is like this

Hbox->Label1,Label2

but when i select any cell it should(only selected cell) update like this

Hbox->Label1,Label2,Labe3,Label4,Button1

Here is my code

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
please read stackoverflow.com/help/mcve and act accordingly :) - kleopatra

1 Answers

1
votes

First of all Cells are designed to prevent unnecessary node creation when different items are displayed. For this reason you should not recreate the nodes every time updateItem is called. Furthermore you never remove the listener from the selected property which means there could be many HBoxes that are updated, which will never be visible again. Also there are quite some errors in your code that prevent it from compiling...

The following code should work though:

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

});