Rezon Thomas
Rezon Thomas

Reputation: 11

Is this a Bug in my code or a problem with cellfactory

todoitemsListview.setCellFactory(new Callback<ListView<ToDoItems>, ListCell<ToDoItems>>() {
        @Override
        public ListCell<ToDoItems> call(ListView<ToDoItems> toDoItemsListView) {
            ListCell<ToDoItems> cell= new ListCell<ToDoItems>(){
                @Override
                protected void updateItem(ToDoItems items, boolean empty) {
                    super.updateItem(items, empty);
                    if(empty){
                        setText(null);
                    }else {
                        setText(items.getItemName());
                        if (items.getDeadline().equals(LocalDate.now())){
                            System.out.println(items.getDeadline().toString());
                            System.out.println(items.getItemName());
                            setTextFill(Color.RED);
                        }else if (items.getDeadline().equals(LocalDate.now().plusDays(1))){
                            System.out.println(items.getDeadline().toString());
                            System.out.println(items.getItemName());
                            setTextFill(Color.BLUE);
                        }else if (items.getDeadline().equals(LocalDate.now().plusDays(2))){
                            System.out.println(items.getDeadline().toString());
                            System.out.println(items.getItemName());
                            setTextFill(Color.GREEN);
                        }else if(items.getDeadline().isBefore(LocalDate.now())){
                            System.out.println(items.getDeadline().toString());
                            System.out.println(items.getItemName());
                            setTextFill(Color.GREY);
                        }
                    }
                }
            };
            return cell;
        }
    });

I used a cellfactory in listview to set text color to different values based on their due date. But when i add new items to the list, items which doesn't satisfy the if - else conditions is also highlighted.

This is part of a basic ToDo application based on a ObservabelList , Where ToDoItems class has three attributes, itemName,ItemDesription,Deadline.

Upvotes: 1

Views: 40

Answers (1)

Bill Tsagkas
Bill Tsagkas

Reputation: 539

Cells in a ListView are reused when needed. So in your case, you have set a specific cell with a red fill, but when that same cell is reused for a different ToDoItems instance (because you scrolled down or added a new item in the list), and that new ToDoItems instance doesn't fullfil any of your conditions that change the fill color, the cell is gonna keep its previous fill color incorrectly.

What you need to do is make sure you fall back to a default color if none of the conditions in your example are met:

todoitemsListview.setCellFactory(new Callback<ListView<ToDoItems>, ListCell<ToDoItems>>() {
    @Override
    public ListCell<ToDoItems> call(ListView<ToDoItems> toDoItemsListView) {
        ListCell<ToDoItems> cell = new ListCell<ToDoItems>() {
            @Override
            protected void updateItem(ToDoItems items, boolean empty) {
                super.updateItem(items, empty);
                if (empty) {
                    setText(null);
                    setTextFill(Color.BLACK);
                } else {
                    setText(items.getItemName());
                    if (items.getDeadline().equals(LocalDate.now())) {
                        System.out.println(items.getDeadline().toString());
                        System.out.println(items.getItemName());
                        setTextFill(Color.RED);
                    } else if (items.getDeadline().equals(LocalDate.now().plusDays(1))) {
                        System.out.println(items.getDeadline().toString());
                        System.out.println(items.getItemName());
                        setTextFill(Color.BLUE);
                    } else if (items.getDeadline().equals(LocalDate.now().plusDays(2))) {
                        System.out.println(items.getDeadline().toString());
                        System.out.println(items.getItemName());
                        setTextFill(Color.GREEN);
                    } else if (items.getDeadline().isBefore(LocalDate.now())) {
                        System.out.println(items.getDeadline().toString());
                        System.out.println(items.getItemName());
                        setTextFill(Color.GREY);
                    } else {
                        setTextFill(Color.BLACK);
                    }
                }
            }
        };
        return cell;
    }
});

Upvotes: 2

Related Questions