JavaFX 2.0 Activating a Menu like a MenuItem

筅森魡賤 提交于 2019-11-27 14:05:49
Uluk Biy

AFAIK, A Menu, if has not any added submenu or Menuitems, does not fire events neither on click, on shown nor on hide. However the workaround is to set its graphic where this graphic node will handle mouse clicks for example,

Label menuLabel = new Label("File");
menuLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent event) {

        Stage myDialog = new Stage();
        myDialog.initModality(Modality.WINDOW_MODAL);

        Scene myDialogScene = new Scene(VBoxBuilder.create()
            .children(new Text("Hello! it's My Dialog."))
            .alignment(Pos.CENTER)
            .padding(new Insets(10))
            .build());

        myDialog.setScene(myDialogScene);
        myDialog.show();
    }
});
Menu fileMenuButton = new Menu();
fileMenuButton.setGraphic(menuLabel);
menuBar.getMenus().add(fileMenuButton);

A drawback of this approach is that the label do not cover all spaces of the menu resulting clicking on edges of menu is not triggering the mouse event. See this by uncommenting menuLabel.setStyle line above. But this can be resolved by playing with CSS styles I think.
Code is partially taken from Create Dialog using Stage. You can also load an FXML file into the myDialog stage using the FXMLLoader. There are lots of examples about it on the net.

Hugo

Recently i had the same problem, this is what i did

@FXML private Menu myMenu;

@Override
public void initialize(URL url, ResourceBundle rb) {

    myMenu.setGraphic(
        ButtonBuilder.create()
            .text("btnText")
            .onAction(new EventHandler<ActionEvent>(){
                @Override public void handle(ActionEvent t) {
                    //TODO
             } })
            .build()
    );
}
Rogerio Souza

Combining with the answer from our friend @Dota2, i built a helper class to trigger the Menu's onAction(Menu menu) event even if it does not have any MenuItem inside. Here is the static helper method:

public static void onAction(Menu menu)
{
    final MenuItem menuItem = new MenuItem();

    menu.getItems().add(menuItem);
    menu.addEventHandler(Menu.ON_SHOWN, event -> menu.hide());
    menu.addEventHandler(Menu.ON_SHOWING, event -> menu.fire());
}

Then you call:

YourHelperClass.onAction(myMenu);

And ready! I hope this helps.

Dota2

Recently I faced the same issue, this was my way out:

I had a menuItem in the menu, which was to behave as if the menuItem is clicked (in your case File menu). So what you can do is have a menuItem Dummy_menuItem

final Menu fileMenu = new Menu("File");
fileMenu.getItems().add(new MenuItem("Dummy_menuItem"));
menuBar.getMenus().add(fileMenu);

and then on click of File menu, fire the Dummy_menuItem menuItem or any functionality you wish to have. To identify which menu should have this property, I used numberOfMenuItems to get the number of menuItems in the menus in menubar

if (numberOfMenuItems == 1) {
    menu.showingProperty().addListener(
        (observableValue, oldValue, newValue) -> {
            if (newValue) {
                // the first menuItem is triggered
                menu.getItems().get(0).fire();
            }
        }
    );
}

the outcome is that the Dummy_menuItem is triggered without the context displaying the menuItem on click of File menu or any menu that has one menuItem. So it appears as if you clicked the File menu and were redirected to another page or whatever.

Hope this helps!!

francois.robert

I think you can't allow any action on the main Menu label.

However, you can create a stackpane, and fill it with text and a menu bar.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!