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

The Change object of TreeView selectedItems reports an invalid value of a index of a removed element

XMLWordPrintable

    • generic
    • generic

      FULL PRODUCT VERSION :
      java version "1.8.0_131"
      Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
      Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

      A DESCRIPTION OF THE PROBLEM :
      When multiple items are selected, reduce the number of selected items using the SHIFT key. Corresponding Change object of a selected items list will reports the indices of removed items relative the initial list of items although the items list is changed sequentially on each removing by one. As a result, the Bindings.bindContent is failed.

      Here's the example application:

      public class TreeViewSelectedItemsBindingTest extends Application {

          public class Item extends TreeItem<Integer> {
              public Item(Integer... value) {
                  Arrays.stream(value).forEach(v -> getChildren().add(new TreeItem<Integer>(v)));
              }
          }

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

              TreeView<Integer> treeView = new TreeView<>();
              treeView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
              treeView.setRoot(new Item(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
              treeView.getRoot().setExpanded(true);
              treeView.setShowRoot(false);

              ListView<TreeItem<Integer>> listView = new ListView<>();

              Bindings.bindContent(listView.getItems(), treeView.getSelectionModel().getSelectedItems());

              treeView.getSelectionModel().getSelectedItems()
                      .addListener((ListChangeListener<? super TreeItem<Integer>>) change -> {
                          System.out.println("Change: " + change);
                          System.out.println("TreeView size: " + treeView.getSelectionModel().getSelectedItems().size());
                          System.out.println("ListView size: " + listView.getItems().size());
                          System.out.println("-------------------");
                      });

              HBox box = new HBox();
              box.getChildren().addAll(treeView, listView);
              primaryStage.setScene(new Scene(box));
              primaryStage.show();
          }

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

      This application bind TreeView selected items to ListView items. Select in the tree view all elements from 0 to 9 and then press SHIFT+element 5, for example, to change selection from 0 to 5 elements. You will got an exeption:

      Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: toIndex = 9

      It is because ListChangeListener.Change reports from index relative to initial unmodified list, not relative a list changed previously:

      -------------------
      Change: { [TreeItem [ value: 6 ]] removed at 6, }
      TreeView size: 9
      ListView size: 9
      -------------------
      Change: { [TreeItem [ value: 7 ]] removed at 7, }
      TreeView size: 8
      ListView size: 8
      -------------------

      You can see "removed at 6" then "removed at 7", but size of underlying lists also changed so index should not be increased here, i.e. all "removed at" should be at 6. And because of this a Bindings.bindContent is failed.





      REPRODUCIBILITY :
      This bug can be reproduced always.

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: