Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable mnemonic for JavaFX MenuBar?

In my stage I have inserted a menubar at the top like usual for programs. I want to give the ALT key (together with arrow keys) some logic in another context within the stage. But everytime I press ALT and arrows I unintentionally navigate through the menus of the menubar, too.

I want to avoid that or better completely disable this mnemonic behavior. Setting the mnemonicParsing properties of all menus to false failed. I also tried this approach without success:

menubar.addEventFilter(KeyEvent.ANY, e -> e.consume());
like image 630
Arceus Avatar asked Mar 15 '16 11:03

Arceus


People also ask

How to disable a menu item in JavaFX?

The MenuItem class contains a property named visible (boolean), which specifies whether to display the current MenuItem. You can set the value to this property using the setVisible() method. To disable a particular menu item invoke the setVisible() method on its object by passing the boolean value “false”.


1 Answers

When ALT is pressed first menu gets focus and when menus have focus, arrow keys cause navigation among them whether ALT is pressed or not. So in order to prevent this behavior you need to prevent first menu getting focus when ALT is pressed.

Looking at the MenuBarSkin class' constructor source code, gives us the solution:

public MenuBarSkin(final MenuBar control) {
    ...
    Utils.executeOnceWhenPropertyIsNonNull(control.sceneProperty(), (Scene scene) -> {
        scene.getAccelerators().put(acceleratorKeyCombo, firstMenuRunnable);

        // put focus on the first menu when the alt key is pressed
        scene.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
            if (e.isAltDown()  && !e.isConsumed()) {
                firstMenuRunnable.run();
            }
        });
    });
    ...
}

Solution:

As you had already guessed, solution is to consume the event when ALT is down but you need to add the EventHandler to the scene not menubar:

scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent event) {
        // your desired behavior
        if(event.isAltDown())
            event.consume();
    }
});
like image 173
Omid Avatar answered Oct 20 '22 19:10

Omid