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

TreeView NullPointerException or IndexOutOfBoundException using ListChangeListener of SelectionModel with MultipleSelection enabled

XMLWordPrintable

    • x86_64
    • windows_7

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

      ADDITIONAL OS VERSION INFORMATION :
      Windows 7 Entreprise
      Service Pack 1

      A DESCRIPTION OF THE PROBLEM :
      When listening on changes from selected items from selection model of the tree,
      internal troubles happened making the parameters of the change to be misconfigured.

      getFrom() will return -1, so getAddedSubList() will throw IndexOutOfBound (as it is a shortcut for getList().subList(getFrom(), getTo());

      This is strange because the list is not empty (added elements will be set in).

      So trying another way around I go on trying to filter that list:
      getList().filtered(item -> item.isSomething())

      and this will throw a NPE.

      It seems that the indexes of the objects in the list are incorrectly sets so the list is not empty but first index is not 0.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      from the given example:

      start the application
      click on child 2
      shift click on child 1
      shift click on child 3

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      from the given example:

      févr. 03, 2017 4:51:50 PM sample.TreeViewChangeListIoobe lambda$null$1
      INFOS: Child 2
      févr. 03, 2017 4:51:51 PM sample.TreeViewChangeListIoobe lambda$null$1
      INFOS: Child 1
      févr. 03, 2017 4:51:56 PM sample.TreeViewChangeListIoobe lambda$null$1
      INFOS: Child 2
      févr. 03, 2017 4:51:56 PM sample.TreeViewChangeListIoobe lambda$null$1
      INFOS: Child 3

      ACTUAL -
      févr. 03, 2017 4:52:03 PM sample.TreeViewChangeListIoobe lambda$null$1
      INFOS: Child 1
      févr. 03, 2017 4:52:03 PM sample.TreeViewChangeListIoobe lambda$null$1
      INFOS: Child 2
      Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
      at sample.TreeViewChangeListIoobe.lambda$null$0(TreeViewChangeListIoobe.java:26)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException
      at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.subList(ReadOnlyUnbackedObservableList.java:136)
      at javafx.collections.ListChangeListener$Change.getAddedSubList(ListChangeListener.java:242)
      at sample.TreeViewChangeListIoobe.lambda$computeChangeListener$2(TreeViewChangeListIoobe.java:23)
      at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
      at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
      at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:75)
      at javafx.scene.control.MultipleSelectionModelBase$1.onChanged(MultipleSelectionModelBase.java:97)
      at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
      at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
      at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:75)
      at javafx.scene.control.MultipleSelectionModelBase.selectIndices(MultipleSelectionModelBase.java:529)
      at javafx.scene.control.MultipleSelectionModel.selectRange(MultipleSelectionModel.java:176)
      at com.sun.javafx.scene.control.behavior.CellBehaviorBase.selectRows(CellBehaviorBase.java:306)
      at com.sun.javafx.scene.control.behavior.CellBehaviorBase.doSelect(CellBehaviorBase.java:236)
      at com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:150)
      at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
      at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
      at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
      at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
      at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
      at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
      at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
      at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
      at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
      at javafx.event.Event.fireEvent(Event.java:198)
      at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
      at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
      at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
      at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
      at java.security.AccessController.doPrivileged(Native Method)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417)
      at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
      at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
      at com.sun.glass.ui.View.notifyMouse(View.java:937)
      at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
      at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
      at java.lang.Thread.run(Thread.java:745)

      or

      Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
      at sample.TreeViewChangeListIoobe.lambda$null$0(TreeViewChangeListIoobe.java:26)
      at javafx.collections.transformation.FilteredList.refilter(FilteredList.java:327)
      at javafx.collections.transformation.FilteredList.access$000(FilteredList.java:50)
      at javafx.collections.transformation.FilteredList$1.invalidated(FilteredList.java:102)
      at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:111)
      at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
      at javafx.collections.transformation.FilteredList.setPredicate(FilteredList.java:125)
      at javafx.collections.transformation.FilteredList.<init>(FilteredList.java:69)
      at javafx.collections.ObservableList.filtered(ObservableList.java:114)
      at sample.TreeViewChangeListIoobe.lambda$computeChangeListener$2(TreeViewChangeListIoobe.java:26)
      at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
      at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
      at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:75)
      at javafx.scene.control.MultipleSelectionModelBase$1.onChanged(MultipleSelectionModelBase.java:97)
      at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
      at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
      at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:75)
      at javafx.scene.control.MultipleSelectionModelBase.selectIndices(MultipleSelectionModelBase.java:529)
      at javafx.scene.control.MultipleSelectionModel.selectRange(MultipleSelectionModel.java:176)
      at com.sun.javafx.scene.control.behavior.CellBehaviorBase.selectRows(CellBehaviorBase.java:306)
      at com.sun.javafx.scene.control.behavior.CellBehaviorBase.doSelect(CellBehaviorBase.java:236)
      at com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:150)
      at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
      at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
      at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
      at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
      at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
      at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
      at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
      at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
      at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
      at javafx.event.Event.fireEvent(Event.java:198)
      at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
      at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
      at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
      at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
      at java.security.AccessController.doPrivileged(Native Method)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417)
      at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
      at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
      at com.sun.glass.ui.View.notifyMouse(View.java:937)
      at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
      at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
      at java.lang.Thread.run(Thread.java:745)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package sample;

      import java.util.logging.Level;
      import java.util.logging.Logger;

      import javafx.application.Application;
      import javafx.collections.ListChangeListener;
      import javafx.scene.Group;
      import javafx.scene.Scene;
      import javafx.scene.control.SelectionMode;
      import javafx.scene.control.TreeItem;
      import javafx.scene.control.TreeView;
      import javafx.stage.Stage;

      public class TreeViewChangeListIoobe extends Application {

        private final Logger LOGGER = Logger.getGlobal();

        private ListChangeListener<? super TreeItem<String>> computeChangeListener() {
          return change -> {
            while (change.next()) {
              if (change.wasAdded()) {
      // change.getAddedSubList(); // IOOBE

                change.getList()
                    .filtered(item -> /*(item != null) &&*/ !item.getValue().trim().isEmpty()) // NPE if previous line commentated
                    .forEach(item -> LOGGER.info(item.getValue()));
              }
            }
          };
        }

        @Override
        public void start(Stage primaryStage) throws Exception {
          LOGGER.setLevel(Level.ALL);

          TreeItem<String> parent = new TreeItem<>("Root");
          TreeItem<String> child1 = new TreeItem<>("Child 1");
          TreeItem<String> child2 = new TreeItem<>("Child 2");
          TreeItem<String> child3 = new TreeItem<>("Child 3");

          parent.getChildren().addAll(child1, child2, child3);

          TreeView<String> treeView = new TreeView<>(parent);
          treeView.setShowRoot(false);
          treeView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
          treeView.getSelectionModel().getSelectedItems().addListener(computeChangeListener());

          Group root = new Group(treeView);
          primaryStage.setScene(new Scene(root));
          primaryStage.show();
        }

        public static void main(String... args) {
          Application.launch(args);
        }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      do not use : "change.getAddedSubList();"

      use

      change.getList()
                    .filtered(item -> (item != null) && item.isWhatIWant())
                    .forEach(item -> doStuff());

            scfitch Stephen Fitch
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: