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

NullPointerException on showing submenu of a contextmenu

    XMLWordPrintable

Details

    • b13

    Description

      If we use a custom ContextMenuSkin we get a NPE if a submenu of a context menu is shown. This doesn't happen the first time the context menu is opened, but from the second time it happens always.

      This must be somehow related to RT-39003. As far as I debugged it, the Scene of the ContextMenu is null which should not be the case in my opinion.

      Defining the dropshadow in the CSS doesn't cause the NPE.

      *How to reproduce:*
      Run the sample program and click the MenuButton. Context menu is openend. Now close the context menu and click the MenuButton again. The NPE is thrown on hovering the menu item which has a sub menu.

      *Exception*
      {code}
      Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
      at com.sun.javafx.Utils.positionX(Utils.java:567)
      at com.sun.javafx.Utils.pointRelativeTo(Utils.java:463)
      at javafx.scene.control.ContextMenu.show(ContextMenu.java:258)
      at com.sun.javafx.scene.control.skin.ContextMenuContent.showSubmenu(ContextMenuContent.java:877)
      at com.sun.javafx.scene.control.skin.ContextMenuContent.lambda$new$329(ContextMenuContent.java:793)
      at com.sun.javafx.scene.control.skin.ContextMenuContent$$Lambda$175/1385631.changed(Unknown Source)
      at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:361)
      at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
      at javafx.beans.property.ReadOnlyBooleanWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyBooleanWrapper.java:178)
      at javafx.beans.property.ReadOnlyBooleanWrapper$ReadOnlyPropertyImpl.access$100(ReadOnlyBooleanWrapper.java:148)
      at javafx.beans.property.ReadOnlyBooleanWrapper.fireValueChangedEvent(ReadOnlyBooleanWrapper.java:144)
      at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
      at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
      at javafx.scene.control.Menu.setShowing(Menu.java:210)
      at javafx.scene.control.Menu.show(Menu.java:408)
      at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$338(ContextMenuContent.java:1320)
      at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer$$Lambda$189/32347719.handle(Unknown Source)
      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.EventUtil.fireEventImpl(EventUtil.java:74)
      at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
      at javafx.event.Event.fireEvent(Event.java:198)
      at com.sun.javafx.event.EventQueue.fire(EventQueue.java:48)
      at javafx.scene.Scene$MouseHandler.handleEnterExit(Scene.java:3677)
      at javafx.scene.Scene$MouseHandler.process(Scene.java:3743)
      at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3486)
      at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
      at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2495)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350)
      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$350(GlassViewEventHandler.java:385)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$170/18444005.get(Unknown Source)
      at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404)
      at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384)
      at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
      at com.sun.glass.ui.View.notifyMouse(View.java:927)
      at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
      at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
      at com.sun.glass.ui.win.WinApplication$$Lambda$36/3326003.run(Unknown Source)
      at java.lang.Thread.run(Thread.java:745)
      {code}

      *Sample program:*
      {code:java}
      import javafx.application.Application;
      import javafx.fxml.FXMLLoader;
      import javafx.scene.Parent;
      import javafx.scene.Scene;
      import javafx.stage.Stage;

      public class MenuNPE extends Application
      {
          @Override
          public void start(Stage primaryStage) throws Exception
          {
              Parent l_content = FXMLLoader.load(getClass().getResource("demo.fxml"));
              primaryStage.setScene(new Scene(l_content));
              primaryStage.show();
          }
          
          public static void main(String[] args)
          {
              launch(args);
          }
      }

      import javafx.scene.control.ContextMenu;
      import javafx.scene.effect.BlurType;
      import javafx.scene.effect.DropShadow;
      import javafx.scene.paint.Color;

      import com.sun.javafx.scene.control.skin.ContextMenuSkin;

      @SuppressWarnings("restriction")
      public class ShadowContextMenuSkin extends ContextMenuSkin
      {
          public ShadowContextMenuSkin(final ContextMenu menu)
          {
              super(menu);
              DropShadow l_effect = new DropShadow();
              l_effect.setOffsetY(2);
              l_effect.setHeight(5);
              l_effect.setOffsetX(2);
              l_effect.setWidth(5);
              l_effect.setColor(new Color(0, 0, 0, 0.2));
              l_effect.setBlurType(BlurType.THREE_PASS_BOX);
              getNode().setEffect(l_effect);
          }
      }
      {code}

      *Corresponding FXML:*
      {code:xml}
      <?xml version="1.0" encoding="UTF-8"?>

      <?import java.lang.*?>
      <?import javafx.scene.control.*?>
      <?import javafx.scene.layout.*?>
      <?import javafx.scene.layout.AnchorPane?>


      <AnchorPane prefHeight="200.0" prefWidth="300.0" stylesheets="@demo.css" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
         <children>
            <MenuButton mnemonicParsing="false" text="MenuButton" AnchorPane.leftAnchor="50.0" AnchorPane.topAnchor="50.0">
              <items>
                <MenuItem mnemonicParsing="false" text="Action 1" />
                  <Menu mnemonicParsing="false" text="Unspecified Menu">
                    <items>
                      <MenuItem mnemonicParsing="false" text="Action 1" />
                        <MenuItem mnemonicParsing="false" text="Unspecified Action" />
                        <MenuItem mnemonicParsing="false" text="Unspecified Action" />
                    </items>
                  </Menu>
                <MenuItem mnemonicParsing="false" text="Action 2" />
                  <MenuItem mnemonicParsing="false" text="Action 3" />
              </items>
            </MenuButton>
         </children>
      </AnchorPane>
      {code}

      *And the CSS file:*
      {code:css}
      .context-menu {
      -fx-skin: "ShadowContextMenuSkin";
      /*-fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.2), 5.0, 0.1, 2, 2);*/
      -fx-background-color: #0084C6, #EBF5FA;
      -fx-background-insets: 0px, 1px;
         -fx-background-radius: 0;
         -fx-border-width: 0px;
         -fx-border-insets: 0px;
      -fx-padding: 1px;
      }
      {code}

      Attachments

        Issue Links

          Activity

            People

              kpk Karthik P K
              duke J. Duke
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported: