This site is currently read-only as we are migrating to Oracle Forums for an improved community experience. You will not be able to initiate activity until January 30th, when you will be able to use this site as normal.

    Forum Stats

  • 3,889,831 Users
  • 2,269,775 Discussions
  • 7,916,823 Comments

Discussions

MenuItem.getStyle returns null (There's no getBackground method)

ed6d17b9-e648-4c81-90be-875de991fd27
edited Feb 14, 2016 5:36PM in JavaFX 2.0 and Later

I'm trying to figure out how to change the background color of a JavaFX MenuItem programmatically. There is no get or set background. Maybe I need to use setStyle? If so, how would I use getStyle in logic that will change the background color depending on the menu item's current color?

Answers

  • bouye-JavaNet
    bouye-JavaNet OfficeMember Posts: 394 Silver Badge
    edited Feb 14, 2016 5:36PM

    The thing is that for some reasons javafx.scene.control.MenuItem are not nodes but plain object used to describe how the "real" menu item in the popup menu will be achieved. This is probably due to the fact that the menu bar can be managed natively (ie: on Mac OS) or even in a completly deferent manner (ie: Mobile) depending on the underlying platform.

    By default, on Windows and on MacOS (when not using setUseSystemMenuBar(true)), the menu bar is done in "software mode": in JavaFX (can be easily seen using ScenicView). The real menu item nodes will be created and manipulated by the skin in order to have additional nodes appear in a popup Window when clicking on the parent menu.

    But when using the native bar (ie: when using setUseSystemMenuBar(true) on MacOS), the menu bar included in the scene is just an empty HBox (again you can use ScenicView to have a look at that) and all menus are in the native bar on top of the screen. You have 0 control over the menu that pops from the native menu bar (no additional node created, no Window showed, all is native and the menu and menu items look native).

    While in software mode, you might achieve what you want by trying to somwhow catchup the Window that pops when clicking on the menu and then trying to lookup the nodes inside. But when in native mode, this seems not feasible to me. You can try to send an RFE to http://bugs.java.com/ and ask them to make these property acessible to the MenuItem class and see what is their answer.

    Also support between CSS and setStyle appear inconsistant. Take the following code (in JDK8_72):

    public class Main extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            final MenuItem exitMenu = new MenuItem("Exit");
            final MenuItem openMenu = new MenuItem("Open...");
            openMenu.getStyleClass().add("open-menu-item");
            final MenuItem closeMenu = new MenuItem("Close");
            closeMenu.setStyle("-fx-background-color: green;");
            final Menu fileMenu = new Menu("File");
            fileMenu.getItems().addAll(openMenu, closeMenu, exitMenu);
            final MenuBar menuBar = new MenuBar();
            menuBar.setUseSystemMenuBar(true);
            menuBar.getMenus().add(fileMenu);
            final BorderPane root = new BorderPane();
            root.setTop(menuBar);
            final Scene scene = new Scene(root, 300, 250);
            final URL cssURL  = getClass().getResource("test.css");
            scene.getStylesheets().add(cssURL.toExternalForm());
            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
            ScenicView.show(scene);
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    

    .open-menu-item {
        -fx-background-color: blue;
    }
    
    

    On Windows :

    For OpenMenu (it uses CSS): the entre item is blue. There are no margins around the item.

    For CloseMenu (it uses setStyle()) : only the labelled inside the concrete menu item is green, there is a noticeable empty margin around the item.

    On MacOS (here we have setUseSystemMenuBar(true)) :

    All 3 items are in the menu that pop from the sytem bar. All 3 items are gray.

    I would say that CSS and CSS pseudo classes are probably the way to go instead of setStyle();

This discussion has been closed.