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

NPE during TableView row selection when table contains null

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 9
    • 8u66
    • javafx
    • x86_64
    • windows_7

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

      ADDITIONAL OS VERSION INFORMATION :
      Windows 7 64bit
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      If a TableView contains a null value, selecting this row and then selecting another row generates a NullPointerException



      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      See attached source code.
      Let's say we have a TableView with 3 rows.
      Rows 1 and 2 contain non-null object.
      Row 3 contains the value null.
      If the user selected rows 1 or 2 there is no issue.
      If the user selects rows 3 (which contains null) there is no issue. BUT if the user then selects either row 1 or 2, an NPE is raised.
      The issue will occur every time the user selects a row containing null before selecting another row.

      This bug is due to a test at line 3052 in TableView where the equals() method of the removed item is called without testing if the item is null first.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      No exception should be raised
      ACTUAL -
      An exception is raised.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
      at javafx.scene.control.TableView$TableViewArrayListSelectionModel.handleSelectedCellsListChangeEvent(TableView.java:3052)
      at javafx.scene.control.TableView$TableViewArrayListSelectionModel.clearAndSelect(TableView.java:2423)
      at javafx.scene.control.TableView$TableViewSelectionModel.clearAndSelect(TableView.java:1914)
      at com.sun.javafx.scene.control.behavior.TableCellBehaviorBase.simpleSelect(TableCellBehaviorBase.java:215)
      at com.sun.javafx.scene.control.behavior.TableCellBehaviorBase.doSelect(TableCellBehaviorBase.java:148)
      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.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:352)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
      at java.security.AccessController.doPrivileged(Native Method)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:388)
      at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
      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 ----------
      import javafx.application.Application;
      import javafx.scene.Scene;
      import javafx.scene.control.TableColumn;
      import javafx.scene.control.TableView;
      import javafx.scene.layout.StackPane;
      import javafx.stage.Stage;

      public class Main extends Application {
          
          @Override
          public void start(Stage primaryStage) {
              final TableView<Boolean> tableView = new TableView();
              final TableColumn<Boolean, Boolean> col1 = new TableColumn("1");
              tableView.getColumns().setAll(col1);
      // col1.setCellFactory(CheckBoxTableCell.forTableColumn(col1));
              tableView.getItems().setAll(Boolean.TRUE, Boolean.FALSE, null);
              tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
              final StackPane root = new StackPane();
              root.getChildren().add(tableView);
              final Scene scene = new Scene(root, 800, 800);
              primaryStage.setTitle("Hello World!");
              primaryStage.setScene(scene);
              primaryStage.show();
          }

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


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

      CUSTOMER SUBMITTED WORKAROUND :
      We must insert a blank (stateless) object in the TableView instead of the value null.

            jgiles Jonathan Giles
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: