Issue
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();
}
}
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!
Solution
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);
Answered By - Uluk Biy