问题描述
我有一个工作示例,用于在JavaFX FXML中的窗格上定义ContextMenu,但我不确定它是否是最佳的。目前,只有JavaFX标准控件(例如Button,TextField)定义用于指定弹出ContextMenu的属性。然而,我想在一个窗格中出现一个弹出菜单,在我的例子中是一个VBox。
I've got a working example for defining a ContextMenu on a Pane in JavaFX FXML, but am not sure it is optimal. Currently, only JavaFX standard controls (e.g. Button, TextField) define a property for specifying a popup ContextMenu. Yet I wanted to have a popup menu appear anywhere in a Pane, in my case a VBox.
我采用扩展VBox的方法来支持上下文菜单。这是一个'笨重'的解决方案,但有效。有更好的方法吗?我错过了一些基本概念吗?
I took the approach of extending VBox to support a context menu. It is a 'clunky' solution but works. Is there a better approach? Am I missing some fundamental concept?
这是我的解决方案......
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 ...
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;
}
}
控制器......
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();
}
}
主要应用......
Main App...
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);
}
}
推荐答案
In这个例子有一个按钮,当点击左/右时有上下文菜单当你点击除按钮之外的其他区域它会打开弹出窗口它将隐藏弹出上下文菜单
In This example there is button which has context menu when click on left/right it will open the popup when you click on other area except button it will hide the popup context menu
公共类Main扩展Application {
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();
}
});
}
}
这篇关于使用FXML在窗格内创建ContextMenu的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!