'ContextMenu and programmatically selecting an item

There does not seem to be API for programmatically "selecting" ContextMenu items? By selecting I mean the equivalent of tapping up and down keys (or hovering the mouse over an item). I really only need to select the first item, when a ContextMenu is shown. I attempted to fire a down keyevent upon showing the menu, but nothing happened.. perhaps I constructed the event wrongly.



Solution 1:[1]

To get this working, we could use some private API. ContextMenu skin (ContextMenuSkin) uses a ContextMenuContent object, as a container with all the items.

We just need to request the focus for the first of these items.

But for this we could just use some lookups to find the first menu-item CSS selector. This has to be done after the stage has been shown.

This example will show a context menu with focus on the first item:

@Override
public void start(Stage primaryStage) {

    MenuItem cmItem1 = new MenuItem("Item 1");
    cmItem1.setOnAction(e->System.out.println("Item 1"));
    MenuItem cmItem2 = new MenuItem("Item 2");
    cmItem2.setOnAction(e->System.out.println("Item 2"));

    final ContextMenu cm = new ContextMenu(cmItem1,cmItem2);

    Scene scene = new Scene(new StackPane(), 300, 250);

    primaryStage.setScene(scene);
    primaryStage.show();

    scene.setOnMouseClicked(t -> {
        if(t.getButton()==MouseButton.SECONDARY){
            cm.show(scene.getWindow(),t.getScreenX(),t.getScreenY());

            // Request focus on first item
            cm.getSkin().getNode().lookup(".menu-item").requestFocus();
        }
    });        
}

Solution 2:[2]

For me solution provided in accepted answer didn't work correctly as item was only highlighted but not really selected (<Enter> was not accepting a value).

Instead of that constructing a proper KeyEvent did the work except a bug that only after first letter popup was working correctly.

Finally I combined both and got what I'd wanted:

    // 'this' is related to parent component of ContextMenu    

    popup.show(this, x, y);

    // Request focus on first item (sort of hack)
    popup.getSkin().getNode().lookup(".menu-item").requestFocus();
    this.fireEvent(new KeyEvent(
        KeyEvent.KEY_PRESSED, "", "",
        KeyCode.DOWN, false, false, false, false));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 José Pereda
Solution 2 BitLord