Slider thumb drag can generate NullPointerExceptions

XMLWordPrintable

    • Type: Bug
    • Resolution: Fixed
    • Priority: P4
    • 8u20
    • Affects Version/s: 8
    • Component/s: javafx
    • None
    • Environment:

      Java 8.0.0-ea-b124, Mac OS X 10.9.1

      Under certain input scenarios, you can get NullPointerExceptions generated when you try to drag a slider thumb.

      The program below contains instructions on how to replicate the scenario.

      -----

      import javafx.application.Application;
      import javafx.geometry.Insets;
      import javafx.scene.Scene;
      import javafx.scene.control.*;
      import javafx.scene.layout.VBox;
      import javafx.scene.text.Font;
      import javafx.stage.Stage;

      public class SliderDragNull extends Application {
          public static void main(String[] args) { launch(args); }
          
          @Override public void start(Stage stage) {
              Label instructions = new Label(
                      "Instructions\n" +
                      "\n" +
                      " 1. Click the combo box button to drop down the combo.\n" +
                      " 2. Don't do anything else.\n" +
                      " 3. Try to drag the slider thumb.\n" +
                      " 4. NullPointerExceptions will be generated.\n" +
                      "\n" +
                      "Originally tested with: \tJava 8.0.0-ea-b124, Mac OS X 10.9.1\n" +
                      "You are testing with: \tJava "
                              + System.getProperty("javafx.runtime.version") + ", "
                              + System.getProperty("os.name") + " "
                              + System.getProperty("os.version")
                              + "\n" +
                      "\n"
              );

              final ComboBox<String> combo = new ComboBox<>();
              combo.setValue(Font.getDefault().getFamily());
              combo.getItems().addAll(Font.getFamilies());

              Slider slider = new Slider(50, 300, 100);

              VBox layout = new VBox(10,
                      instructions,
                      slider,
                      combo
              );
              layout.setPadding(new Insets(10));

              stage.setScene(new Scene(layout));
              stage.show();
          }
      }

      ------

      The exception stack trace is as below:

      Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
      at com.sun.javafx.scene.control.skin.SliderSkin$5.handle(SliderSkin.java:139)
      at com.sun.javafx.scene.control.skin.SliderSkin$5.handle(SliderSkin.java:135)
      at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
      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.EventUtil.fireEventImpl(EventUtil.java:74)
      at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
      at javafx.event.Event.fireEvent(Event.java:204)
      at javafx.scene.Scene$MouseHandler.process(Scene.java:3746)
      at javafx.scene.Scene$MouseHandler.access$1800(Scene.java:3471)
      at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1695)
      at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2486)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:314)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:243)
      at java.security.AccessController.doPrivileged(Native Method)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:345)
      at com.sun.glass.ui.View.handleMouseEvent(View.java:526)
      at com.sun.glass.ui.View.notifyMouse(View.java:898)

      -----

      The cause of the exception is that the dragStart variable has not been initialized and is null when the following code from SliderSkin.java tries to utilize it:

              thumb.setOnMouseDragged(new EventHandler<MouseEvent>() {
                  @Override public void handle(MouseEvent me) {
                      Point2D cur = thumb.localToParent(me.getX(), me.getY());
                      double dragPos = (getSkinnable().getOrientation() == Orientation.HORIZONTAL)?
                          cur.getX() - dragStart.getX() : -(cur.getY() - dragStart.getY());
                      getBehavior().thumbDragged(me, preDragThumbPos + dragPos / trackLength);
                  }
              });

      The dragStart variable is supposed to have been initialized in this event handler:

              thumb.setOnMousePressed(new EventHandler<MouseEvent>() {
                  @Override public void handle(MouseEvent me) {
                      getBehavior().thumbPressed(me, 0.0f);
                      dragStart = thumb.localToParent(me.getX(), me.getY());
                      preDragThumbPos = (getSkinnable().getValue() - getSkinnable().getMin()) /
                              (getSkinnable().getMax() - getSkinnable().getMin());
                  }
              });

      But, for some reason, dragStart is not initialized, so the thumb is not receiving a mouse pressed event before it receives a mouse dragged event => but only for a certain combination of UI input (for instance, as in the provided example, by pressing the Combo Button to drop down the combo before trying to slide the slider).

            Assignee:
            David Grieve
            Reporter:
            John Smith (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: