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

Slider thumb drag can generate NullPointerExceptions

    XMLWordPrintable

    Details

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

      Java 8.0.0-ea-b124, Mac OS X 10.9.1

      Description

      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).

        Attachments

          Activity

            People

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

              Dates

              Created:
              Updated:
              Resolved:
              Imported: