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