JavaFX ContextMenu doesn't auto-hide


Question

I have a JavaFX ContextMenu assigned to the right mouse button click of a scrollpane. It opens, but it doesn't close when you click outside the scrollpane. I could add another mouse event to the scrollpane in order to hide it, but that solves only 1 problem. The main problem is that when I click on any component of the scrollpane, then the context menu remains open.

Example: Open popup via right mouse button click, then click on the button. The popup menu is still open.

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        final ContextMenu contextMenu = new ContextMenu();

        MenuItem item1 = new MenuItem("About");
        MenuItem item2 = new MenuItem("Preferences");

        contextMenu.getItems().addAll(item1, item2);


        Rectangle rect = new Rectangle( 100,100,150,150);
        Button button = new Button( "Button Text");

        // create nodes
        Group root = new Group();
        root.getChildren().add( rect);
        root.getChildren().add( button);

        // create scrollpane
        ScrollPane sp = new ScrollPane( root);
        sp.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {

                if (event.isSecondaryButtonDown()) {
                    contextMenu.show( sp, event.getScreenX(), event.getScreenY());
                } 
            }
        });



        // create scene
        Scene scene = new Scene(sp, 400, 400, Color.WHITE);

        // add scene to primary stage
        primaryStage.setScene( scene);
        primaryStage.show();
    }
}

enter image description here

The documentation says that there's a setAutoHide method, but it doesn't work in my case:

Specifies whether Popups should auto hide. If a popup loses focus and autoHide is true, then the popup will be hidden automatically. The only exception is when owner Node is specified using show(javafx.scene.Node, double, double). Focusing owner Node will not hide the PopupWindow.

@defaultValue false

Thank you very much!

1
5
11/8/2014 12:42:08 PM

Accepted Answer

Interacting with child elements of the parent, will get a focus to that parent. So the context menu will not hide when the button in your code is clicked.

Try these two approaches:
1) Manually manage the visibility of context menu, i.e. hide it on button click:

button.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent arg0) {
        contextMenu.hide();
    }
});

2) Use setContextMenu() instead of showing the context menu on mouse press event:

sp.setContextMenu(contextMenu);
10
11/8/2014 12:38:27 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon