JavaFX – Avoid ghost duplicated elements in ListView

Recently I’ve started learning GUI development with JavaFX. To do so I decided to code a Contacts app capable of adding, removing, editing and showing a list of Person. My idea was having a side bar with a ListView and the rest for showing selected contact details.

I wanted to customize the listView in order to show last name with a bold font,  first name regular and a profile picture on the right of listview cell. JavaDoc was helpful for this and according to it, extending ListCell<E> and overriding the updateItem() method was enough. So I wrote this:

public class ContactsListCell extends ListCell<Person> {
    @Override
    protected void updateItem(Person item, boolean empty) {
        super.updateItem(item, empty);

        if (!empty) {
            try {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("../View/CellLayout.fxml"));
                GridPane cellLayout = (GridPane) loader.load();
                CellLayoutController cellLayoutController = loader.getController();
                cellLayoutController.CellSetup(item);
                setGraphic(cellLayout);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

Where CellLayoutController class is:

public class CellLayoutController {
    @FXML
    private Label nameLabel;
    @FXML
    private Label surnameLabel;
    @FXML
    private ImageView profilePic;

    public void CellSetup(Person person) {
        nameLabel.textProperty().bind(person.nameProperty());
        surnameLabel.textProperty().bind(person.surnameProperty());
        Utils.ProfilePicSetup(profilePic, 30);
    }
}

ProfilePicSetup method handles ImageView properties. That produces the following:

contacts_1

Great I said. Until I started playing with window resizing and adding elements. Here’s what occurs:

Contacts_2

Although Test 3 item is actually the last selectable, for a still not clear reason, my ListView draws 2 other elements, non-selectable, that are shown until new items are added to fill the list view height. I Googled a bit but everyone seemed to implement custom cells just like I was. Even official Java examples have the same problem (try to add new items to this Oracle example’s listview and see). I guess that’s a bug. I managed to easily fix this attitude by adding a simple else statement in the ListCell class:

public class ContactsListCell extends ListCell {
    @Override
    protected void updateItem(Person item, boolean empty) {
        super.updateItem(item, empty);

        if (!empty) {
            try {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("../View/CellLayout.fxml"));
                GridPane cellLayout = (GridPane) loader.load();
                CellLayoutController cellLayoutController = loader.getController();
                cellLayoutController.CellSetup(item);
                setGraphic(cellLayout);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } else {
            setGraphic(null);
        }

    }
}

And no more ghost items. I hope Oracle fixes this soon. Until that time I hope this post will be helpful.

Cheers.
Leonardo Arcari

Tag:, , , ,

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: