Using FXML to Create a ContextMenu Inside a Panel

I have a working example for defining ContextMenu in a panel in JavaFX FXML, but I'm not sure if it is optimal. Currently, only standard JavaFX controls (such as Button, TextField) define a property to specify the ContextMenu popup. However, I wanted the popup menu to appear anywhere on the panel, in my case VBox.

I used the VBox approach to support the context menu. This is a "clumsy" solution, but it works. Is there a better approach? Is any fundamental concept missing?

Here is my solution ...

FXML:

<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?import custommenu.view.ContextMenuPane?> <AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="custommenu.controller.CustomMenuController"> <children> <VBox fx:id="vbox" onContextMenuRequested="#showMenu" onMousePressed="#hideMenu" prefHeight="200" prefWidth="200"> </VBox> <ContextMenuPane> <contextMenu> <ContextMenu fx:id="menu"> <items> <MenuItem text="add" onAction="#add" /> </items> </ContextMenu> </contextMenu> </ContextMenuPane> </children> </AnchorPane> 

CustomMenuPane ...

 package custommenu.view; import javafx.scene.control.ContextMenu; import javafx.scene.layout.Pane; public class ContextMenuPane extends Pane { private ContextMenu contextMenu; public void setContextMenu(ContextMenu contextMenu) { this.contextMenu = contextMenu; } public ContextMenu getContextMenu() { return contextMenu; } } 

controller...

 package custommenu.controller; import javafx.fxml.FXML; import javafx.scene.control.ContextMenu; import javafx.scene.input.ContextMenuEvent; import javafx.scene.layout.VBox; public class CustomMenuController { @FXML private VBox vbox; @FXML private ContextMenu menu; @FXML public void add() { System.out.println("add"); } @FXML public void showMenu(ContextMenuEvent event) { System.out.println("showMenu"); menu.show(vbox, event.getScreenX(), event.getScreenY()); event.consume(); } @FXML public void hideMenu() { menu.hide(); } } 

The main application ...

 package custommenu; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.stage.Stage; public class CustomMenuApplication extends Application { @Override public void start(Stage primaryStage) throws Exception { Pane myPane = (Pane)FXMLLoader.load(getClass().getResource("/custommenu/custom_menu_main.fxml")); Scene scene = new Scene(myPane); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } } 
+6
source share
2 answers

Tried to do it in Popup? Catch MouseEvent for MouseButton.SECONDARY and show your VBox in a popup.

 private void showContextMenu() // showContextMenu(MouseEvent event) { Popup popup = new Popup(); VBox content = new VBox(); Button b = new Button("Click Me!"); b.setOnAction(new EventHandler<ActionEvent>() { }); content.getChildren().addAll(b); popup.getContent().add(content); popup.setX(0); // or get mouse event x and y popup.setY(0); // event.getY() popup.setAutoHide(true); popup.show(your popup owner); } 
0
source

In this example, there is a button that has a context menu, when it presses left / right, it will open a pop-up window, when you click on another area, except for a button, it will hide the pop-up context menu

public class Main extends application {

 public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { Scene scene = new Scene(new Group(), 450, 250); Button notification = new Button(); MenuItem item1 = new MenuItem("About"); item1.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent e) { System.out.println("About"); } }); MenuItem item2 = new MenuItem("Preferences"); item2.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent e) { System.out.println("Preferences"); } }); MenuItem item3 = new MenuItem("About"); item1.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent e) { System.out.println("About"); } }); MenuItem item4 = new MenuItem("Preferences"); item2.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent e) { System.out.println("Preferences"); } }); MenuItem item5 = new MenuItem("About"); item1.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent e) { System.out.println("About"); } }); MenuItem item6 = new MenuItem("Preferences"); item2.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent e) { System.out.println("Preferences"); } }); MenuItem item7 = new MenuItem("About"); item1.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent e) { System.out.println("About"); } }); MenuItem item8 = new MenuItem("Preferences"); item2.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent e) { System.out.println("Preferences"); } }); final ContextMenu contextMenu = new ContextMenu(item1, item2,item3, item4,item5, item6,item7, item8); contextMenu.setMaxSize(50, 50); contextMenu.setOnShowing(new EventHandler<WindowEvent>() { public void handle(WindowEvent e) { System.out.println("showing"); } }); contextMenu.setOnShown(new EventHandler<WindowEvent>() { public void handle(WindowEvent e) { System.out.println("shown"); } }); // contextMenu.hide(); notification.setContextMenu(contextMenu); GridPane grid = new GridPane(); grid.setVgap(4); grid.setHgap(10); grid.setPadding(new Insets(5, 5, 5, 5)); grid.add(new Label("To: "), 0, 0); grid.add(notification, 1, 0); Group root = (Group) scene.getRoot(); root.getChildren().add(grid); stage.setScene(scene); stage.show(); notification.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent me)->{ if(me.getButton()==MouseButton.PRIMARY ){ System.out.println("Mouse Left Pressed"); System.out.println(notification.getScaleX()); System.out.println(notification.getScaleY()); System.out.println(me.getScreenX()); System.out.println(me.getScreenY()); contextMenu.show(notification,me.getScreenX(),me.getScreenY()); }else{ contextMenu.hide(); } }); } 

}

0
source

Source: https://habr.com/ru/post/948794/


All Articles