Search code examples
javalistviewjavafxjavafx-8cell

JafaFX ListView change Color of single Cells/Items/Rows


Probably the answer to this question is very simple, so I'm going to try to keep my post so.

My Problem I want the Text-Color of different Cells/Rows/Items to be customizable through a JavaFX ColorPicker. My Code does work, but not really like I want it to.. Everytime a new Item is added to the ListView, the whole ListView changes its Text-Color the Text-Color chosen for the latest Item.

Here's my code (Full class linked below, but I don't think it's needed)

@FXML
void handleAdd(){   //When add button is clicked

    fontSize = 16.0;

    listView.setCellFactory(cell -> {
        ListCell<String> cel = new ListCell<String>() {
            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (item != null) {
                    setTextFill(colorPicker.getValue());
                    setFont(Font.font(16));
                    setText(item);
                } else {
                    setText("");
                }
            }
        };
        return cel;
    });


    listView.getItems().add(input.getText()); //input is my TextField

    input.clear();
}

full class

Thanks in advance!


Solution

  • Use a item type for the ListView that contains a ObjectProperty<Color> in addition to a string

    private static class ListItem {
        public ListItem(String text) {
            this.text = text;
        }
    
        private final String text;
        private final ObjectProperty<Color> color = new SimpleObjectProperty(Color.BLACK);
    }
    
    ListView<ListItem> listView;
    
    listView.setCellFactory(cell -> {
        ListCell<ListItem> cel = new ListCell<ListItem>() {
            @Override
            protected void updateItem(ListItem item, boolean empty) {
                super.updateItem(item, empty);
                if (item != null) {
                    textFillProperty().bind(item.color);
                    setFont(Font.font(16));
                    setText(item.text);
                } else {
                    setText("");
                    textFillProperty().unbind();
                    setTextFill(Color.BLACK);
                }
            }
        };
        return cel;
    });
    

    This way you simply need to set the property to a different value, if you want to change the color, e.g:

    ListItem selectedItem = listView.getSelectionModel().getSelectedItem();
    if (item != null) {
        item.color.set(Color.RED);
    }