0

My program is changing ListCell styles based on it's content:

    debugListView.setCellFactory(listCell -> new ListCell<String>() {
        @Override
        public void updateItem(String content, boolean isEmpty) {
            super.updateItem(content, isEmpty);
            if (isEmpty || content == null) {
                setText("");
                setStyle("");
            } else {
                setText(content);
                if (content.contains("INFO")) {
                    getStyleClass().addAll("info", "debug");
                } else if (content.contains("WARN")) {
                    getStyleClass().addAll("warning", "debug");
                } else if (content.contains("ERROR")) {
                    getStyleClass().addAll("error", "debug");
                }
            }
        }
    });

This works great but if you scroll through the list the styles get messed up. I'm read about how ListCells in a ListView are managed while scrolling and that they are destroyed and recreated everytime and that this could be the problem (https://stackoverflow.com/a/12425646/4469105). Similar to the TableView sorting problem where TableCell styles get messed up when sorting columns which seems to get fixed with 8u60 (https://stackoverflow.com/a/11066040/4469105).

Nevertheless I found no workaround for this one. So does anyone have an idea or some keywords?

Thank you in advance!

Community
  • 1
  • 1
cmtjk
  • 359
  • 2
  • 12

1 Answers1

2

The problem arises because the style class is implemented as a List, which allows duplicate entries. So as the user scrolls, causing calls to updateItem(...), you are adding more and more entries to the cell's style class list, without ever removing them.

Remove all the specific style classes you are using before you implement your logic:

List<String> allStyles = Arrays.asList("info", "debug", "warning", "error");

debugListView.setCellFactory(listCell -> new ListCell<String>() {
    @Override
    public void updateItem(String content, boolean isEmpty) {
        super.updateItem(content, isEmpty);

        getStyleClass().removeAll(allStyles);

        if (isEmpty || content == null) {
            setText("");
            setStyle("");
        } else {
            setText(content);
            if (content.contains("INFO")) {
                getStyleClass().addAll("info", "debug");
            } else if (content.contains("WARN")) {
                getStyleClass().addAll("warning", "debug");
            } else if (content.contains("ERROR")) {
                getStyleClass().addAll("error", "debug");
            }
        }
    }
});
James_D
  • 201,275
  • 16
  • 291
  • 322