NullPointer in ContextMenu sub-menu when graphic and style classes are changed while the menu is open

XMLWordPrintable

    • Type: Bug
    • Resolution: Unresolved
    • Priority: P3
    • tbd
    • Affects Version/s: jfx11, jfx17, jfx21, jfx25, jfx26
    • Component/s: javafx

      ADDITIONAL SYSTEM INFORMATION :
      JavaFX 24.0.2

      Java:
      openjdk version "25.0.1" 2025-10-21 LTS
      OpenJDK Runtime Environment Temurin-25.0.1+8 (build 25.0.1+8-LTS)
      OpenJDK 64-Bit Server VM Temurin-25.0.1+8 (build 25.0.1+8-LTS, mixed mode, sharing)

      A DESCRIPTION OF THE PROBLEM :
      A NullPointerException is thrown when a submenu of a ContextMenu is opened for the second time, and the graphic and style classes are changed while the menu is open.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1: start the supplied reproducer program
      2: open the ContextMenu or the main menu
      3: hover the mouse over the 'menu...' item (this opens the submenu)
      4: hover the mouse over the 'dummy' item (this hides the submenu)
      5: hover the mouse over the 'menu...' item (this opens the submenu again) >>>>>> ERROR

      ---------- BEGIN SOURCE ----------
      import javafx.application.Application;
      import javafx.application.Platform;
      import javafx.scene.Scene;
      import javafx.scene.control.ContextMenu;
      import javafx.scene.control.Label;
      import javafx.scene.control.Menu;
      import javafx.scene.control.MenuBar;
      import javafx.scene.control.MenuItem;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;

      public class SubMenuNullPointer extends Application {

          public static class Launcher {
              public static void main(String[] args) {
                  SubMenuNullPointer.main(args);
              }
          }

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

          @Override
          public void start(Stage primaryStage) throws Exception {
              MenuBar menuBar = new MenuBar(new Menu("Main menu", null, new MenuItem("dummy"), createSubMenu()));

              ContextMenu contextMenu = new ContextMenu();
              contextMenu.getItems().addAll(new MenuItem("dummy"), createSubMenu());

              BorderPane root = new BorderPane();

              root.setTop(menuBar);
              Label label = new Label("open context menu here");
              label.setContextMenu(contextMenu);
              root.setCenter(label);
              primaryStage.setScene(new Scene(root));
              primaryStage.show();
          }

          private Menu createSubMenu() {
              Menu menu = new Menu("menu...");

              MenuItem item = new MenuItem("item");
              menu.getItems().add(item);

              menu.setOnShown(event -> {
                  Platform.runLater(() -> {
                      // Update the graphic while the menu is visible
                      item.setGraphic(new Label("graphic"));

                      // BUG: NullPointer
                      item.getStyleClass().removeAll("test");
                      item.getStyleClass().add("test");
                  });
              });
              return menu;
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Use a container node (e.g. StackPane) to wrap the MenuItem graphic and replace the graphic in the container node, rather than in the MenuItem itself.

      FREQUENCY :
      ALWAYS

            Assignee:
            Dmitry Markov
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: