Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8095003

[ListView] Deleting items from ListView with setCellFactory causes unexpected displaying behaviour



    • Bug
    • Resolution: Not an Issue
    • P4
    • 8u20
    • 8u5
    • javafx
    • Windows 7. JDK 8.


      The observed problem:
      I want to use a ListView to display complex objects. In the code below I used a simple StringWrapper Class to simulate the observed behaviour. When an item is deleted from the ListView, though internaly it is removed from the associated ObservableList, the user will still be shown the item in the list. However that item will not be selectable anymore. In fact, the list will always show the same amount of items (in the end very random items) until the last item has been deleted. With the deletion of the last item the list will be cleared.

      The Problem only occurs when an own CellFactory is used. Furthermore, the same code runs just fine with JDK 7.

      Here is the Code:

      package listviewbug;

      import java.util.ArrayList;
      import javafx.application.Application;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.event.ActionEvent;
      import javafx.fxml.FXML;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.ListCell;
      import javafx.scene.control.ListView;
      import javafx.scene.layout.FlowPane;
      import javafx.scene.layout.Pane;
      import javafx.scene.layout.VBox;
      import javafx.scene.text.Text;
      import javafx.stage.Stage;

       * @author me
      public class ListViewBug extends Application {

          ListView<StringWrapper> listView;
          Button removeButton;

          ObservableList<StringWrapper> stringList;

          public void start(Stage primaryStage) {
              //create a new ListView
              listView = new ListView();
              //intial set up for the example ListView
              //button to delete items from the list
              Button bt_delete = new Button();
              bt_delete.setText("delete selected");
              bt_delete.setOnAction((ActionEvent event) -> {
                  if (listView.getSelectionModel().getSelectedIndex() == -1) {
                      System.out.println("NOTHING SELECTED!");
                  } else {
              //button to fill list up again, start test over.
              Button bt_fillList = new Button();
              bt_fillList.setText("fill list");
              bt_fillList.setOnAction((ActionEvent event) -> fillList());

              //add elements to stack pane
              FlowPane root = new FlowPane();
              VBox vbox = new VBox(bt_delete, bt_fillList);
              root.getChildren().add(new Pane(listView));

              Scene scene = new Scene(root, 400, 250);

              primaryStage.setTitle("ListView Bug");
           * Fills list with some example StringWrappers
          public void fillList() {
              //Create some test StringWrapper
              ArrayList<StringWrapper> StringWrapper = new ArrayList();
              StringWrapper.add(new StringWrapper("a"));
              StringWrapper.add(new StringWrapper("b"));
              StringWrapper.add(new StringWrapper("c"));
              StringWrapper.add(new StringWrapper("d"));
              StringWrapper.add(new StringWrapper("e"));

              //add StringWrapper to an ObservableList
              stringList = FXCollections.observableArrayList(StringWrapper);
              //set items of the ObservableList for the ListView

              //set how the StringWrapper will be displayed
              listView.setCellFactory((ListView<StringWrapper> p) -> new StringWrapperEventCell());

           * A ListCell displaying a StringWrapper. The List Wrapper is simply
           * converted to a String and then put into a Text object.
          private static class StringWrapperEventCell extends ListCell<StringWrapper> {

              protected void updateItem(StringWrapper se, boolean bln) {
                  super.updateItem(se, bln); //To change body of generated methods, choose Tools | Templates.
                  if (se != null) {
                      Text t = new Text(se.toString());

           * @param args the command line arguments
          public static void main(String[] args) {

           * StringWrapper Class to represent a complex Object.
          public class StringWrapper {

              String string;

              public StringWrapper(String string) {
                  this.string = string;

              public String toString() {
                  return string;


          public void printInfo() {
              System.out.println("ListView Size: " + listView.getItems().size());
              System.out.println("ObservableList Size: " + stringList.size());




        Issue Links



              jgiles Jonathan Giles
              duke J. Duke
              0 Vote for this issue
              4 Start watching this issue