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

ListView and possibly TableView and TreeView call Cell.updateItem() when the item hasn't changed.

    XMLWordPrintable

Details

    Description

      After trying b94 I have determined that my lists and tables are sometimes getting stuck in an endless loop of updateItem calls on their cells.

      It looks like after the fix for bug RT-29923 a ListCell may often get updateItem() called when the item has not actually changed. This stems from the fact that anything that causes a re layout of the cells also seems to cause that all of their indexes get marked as changed and this results in updateItem() being called. Subsequently if there is anything in your updateItem() code that might cause a re layout we end up in an infinite loop of calls.

      The following test code will print out a message whenever an unnecessary call to updateItem() happens. You can resize the stage and see it gets printed out quite a lot. If you change the updating strategy in my updateItem() method to always reset the cell ui and then only set it when it has a non-null item you will observe an infinite loop of update calls.

      Also if you comment out my custom cell and use the TextFieldListCell I believe this bug also stops the cell from ever fully switching to editing mode. The installing of the textfield causes a re layout which changes all the indexes and results in a call to updateItem() even though the item hasn't changed. And updateItem() cancels the edit.

      *******************************************************************
      import javafx.application.Application;
      import javafx.scene.Scene;
      import javafx.scene.control.ListCell;
      import javafx.scene.control.ListView;
      import javafx.scene.image.Image;
      import javafx.scene.image.ImageView;
      import javafx.scene.layout.StackPane;
      import javafx.stage.Stage;
      import javafx.util.Callback;

      public class ListViewTest extends Application {
      private static final Image IMAGE = new Image("http://www.oracle.com/ocom/"
      + "groups/public/@otn/documents/digitalasset/1917282.jpg");

      @Override
      public void start(Stage primaryStage) throws Exception {

      primaryStage.centerOnScreen();
      primaryStage.setHeight(200);
      primaryStage.setWidth(550);

      final ListView<String> list = new ListView<>();
      list.setEditable(true);
      list.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
      @Override
      public ListCell<String> call(ListView<String> param) {
      return new ListCell<String>() {
      ImageView view = new ImageView();
      {setGraphic(view);};
      @Override public void updateItem(String item, boolean empty) {
      if ( (getItem() == null) ? item == null : getItem().equals(item) ) {
      System.out.println("unnecessary update");
      }
      super.updateItem(item, empty);

      if ( item == null || empty ) {
      view.setImage(null);
      setText(null);
      } else {
      view.setImage(IMAGE);
      setText(item);
      }

      // this less efficient but valid strategy can cause an
      // infinite loop of layouts and updateItem() calls.
      //view.setImage(null);
      //setText(null);
      //if ( item != null ) {
      // view.setImage(image);
      // setText(item);
      //}
      }
      };
      }
      });

      // if you try the builtin one it will never let you edit cause the
      // act of it installing the textfield will cause a layout and this
      // calls updateItem which cancels the edit.
      //list.setCellFactory(TextFieldListCell.forListView());

      list.getItems().setAll("one", "two", "three", "four", "five");

      primaryStage.setScene(new Scene(new StackPane(list)));
      primaryStage.show();

      }

      public static void main(String[] args) throws Exception {
      launch(args);
      }

      }

      Attachments

        Issue Links

          Activity

            People

              jgiles Jonathan Giles
              csmithjfx Charles Smith (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported: