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

CustomMenuItem does not hide other submenus upon mouse enter

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Any OS with recent Java and JavaFX.

      A DESCRIPTION OF THE PROBLEM :
      When the mouse enters a CustomMenuItem, other sub-menus are not automatically dismissed. (NOTE: I selected a previous release where this worked only because the form forced me to... I have never seen this work in any JavaFX release, but obviously haven't bothered to review all of them.)


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Add a CustomMenuItem and a [sub]Menu into a Menu. Open the submenu and move the mouse over the CustomMenuItem.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Submenus should automatically hide whenever the mouse enters any other MenuItem on the same Menu, regardless of that MenuItem's exact type. CustomMenuItem should be included for this behavior.
      ACTUAL -
      The submenu does not hide when the mouse enters another MenuItem.

      ---------- BEGIN SOURCE ----------
      N/A because the JavaFX source code itself can be clearly seen to omit submenu closing for CustomMenuItem. See ContextMenuContent.java in JavaFX 20.0.1 source code. On line 1203, CustomMenuItems are handled specially. But their handling does not include any call to hideSubmenu() analogous to that on line 1294. The behavior on line 1294 should be applied equally across all MenuItem types including CustomMenuItem.
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I have successfully worked around this by painstakingly adding a container under my CustomMenuItem which is analogous to ContextMenuContent.MenuItemContainer. By carefully creating the exact same sub-structure and style classes, I can get similar behavior. That container can then also contain code like the following:

                  EventHandler<MouseEvent> mouseEnteredEventHandler = event -> {
                      var parentMenu = item.getParentMenu();
                      if (parentMenu != null)
                      {
                          parentMenu.getItems().forEach(siblingItem -> {
                              if (siblingItem instanceof Menu submenu)
                              {
                                  submenu.hide();
                              }
                          });
                      }
                      else
                      {
                          var parentContextMenu = item.getParentPopup();
                          if (parentContextMenu != null)
                          {
                              parentContextMenu.getItems().forEach(siblingItem -> {
                                  if (siblingItem instanceof Menu submenu)
                                  {
                                      submenu.hide();
                                  }
                              });
                          }
                      }
                  };


      FREQUENCY : always


            angorya Andy Goryachev
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: