usar tutorial style propiedades graficas font family create javafx-2 javafx fxml

javafx 2 - tutorial - Usar FXML para crear ContextMenu dentro de un panel



propiedades css javafx (2)

En este ejemplo, hay un botón que tiene un menú contextual al hacer clic a la izquierda / derecha. Se abrirá la ventana emergente al hacer clic en otra área, excepto en el botón, se ocultará el menú contextual emergente.

clase pública 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(); } }); }

}

Tengo un ejemplo práctico para definir un ContextMenu en un Panel en JavaFX FXML, pero no estoy seguro de que sea óptimo. Actualmente, solo los controles estándar de JavaFX (por ejemplo, Button, TextField) definen una propiedad para especificar un ContextMenu emergente. Sin embargo, quería que apareciera un menú emergente en cualquier parte de un Panel, en mi caso un VBox.

Tomé el enfoque de extender VBox para admitir un menú contextual. Es una solución ''torpe'' pero funciona. ¿Hay un mejor enfoque? ¿Me estoy perdiendo algún concepto fundamental?

Aquí está mi solución ...

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; } }

Controlador...

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(); } }

Aplicación Principal ...

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); } }


Trató de hacerlo dentro de una ventana emergente? Capture la comprobación de MouseEvent para MouseButton.SECONDARY y visualice su VBox en la ventana emergente.

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); }