Javafx 2 使用FXML在窗格中创建上下文菜单

Javafx 2 使用FXML在窗格中创建上下文菜单,javafx-2,javafx,fxml,Javafx 2,Javafx,Fxml,我有一个在JavaFXML中的窗格上定义ContextMenu的工作示例,但我不确定它是否是最佳的。目前,只有JavaFX标准控件(例如按钮、文本字段)定义用于指定弹出式上下文菜单的属性。然而,我想让弹出菜单出现在窗格中的任何位置,在我的例子中是VBox 我采用了扩展VBox的方法来支持上下文菜单。这是一个“笨重”的解决方案,但有效。有更好的方法吗?我是否遗漏了一些基本概念 这是我的解决方案 FXML: 控制器 package custommenu.controller; import jav

我有一个在JavaFXML中的窗格上定义ContextMenu的工作示例,但我不确定它是否是最佳的。目前,只有JavaFX标准控件(例如按钮、文本字段)定义用于指定弹出式上下文菜单的属性。然而,我想让弹出菜单出现在窗格中的任何位置,在我的例子中是VBox

我采用了扩展VBox的方法来支持上下文菜单。这是一个“笨重”的解决方案,但有效。有更好的方法吗?我是否遗漏了一些基本概念

这是我的解决方案

FXML:

控制器

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();
    }
}
主应用程序

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

是否尝试在弹出窗口中执行此操作?捕获MouseButton.SECONDARY的MouseEvent检查,并在弹出窗口中显示您的VBox

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);
}
private void showContextMenu()//showContextMenu(MouseEvent事件)
{
Popup Popup=新的Popup();
VBox内容=新的VBox();
按钮b=新按钮(“单击我!”);
b、 setOnAction(新的EventHandler(){});
content.getChildren().addAll(b);
popup.getContent().add(内容);
popup.setX(0);//或获取鼠标事件x和y
popup.setY(0);//event.getY()
popup.setAutoHide(true);
显示(您的弹出窗口所有者);
}

在本例中,当单击左/右按钮时,有一个按钮具有上下文菜单。当您单击除按钮之外的其他区域时,它将打开弹出窗口。它将隐藏弹出窗口上下文菜单

公共类主扩展应用程序{

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();
        }
    });
  }
publicstaticvoidmain(字符串[]args){
发射(args);
}
@凌驾
公众假期开始(阶段){
场景=新场景(新组(),450,250);
按钮通知=新按钮();
MenuItem1=新MenuItem(“关于”);
item1.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent e){
System.out.println(“关于”);
}
});
MenuItem2=新MenuItem(“首选项”);
item2.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent e){
System.out.println(“首选项”);
}
});
MenuItem3=新MenuItem(“关于”);
item1.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent e){
System.out.println(“关于”);
}
});
MenuItem4=新MenuItem(“首选项”);
item2.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent e){
System.out.println(“首选项”);
}
});
MenuItem5=新MenuItem(“关于”);
item1.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent e){
System.out.println(“关于”);
}
});
MenuItem6=新MenuItem(“首选项”);
item2.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent e){
System.out.println(“首选项”);
}
});
MenuItem7=新MenuItem(“关于”);
item1.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent e){
System.out.println(“关于”);
}
});
MenuItem8=新MenuItem(“首选项”);
item2.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent e){
System.out.println(“首选项”);
}
});
最终上下文菜单上下文菜单=新上下文菜单(项目1、项目2、项目3、项目4、项目5、项目6、项目7、项目8);
setMaxSize(50,50);
setOnShowing(新的EventHandler()){
公共无效句柄(WindowEvent e){
系统输出打印(“显示”);
}
});
setOnShown(新的EventHandler()){
公共无效句柄(WindowEvent e){
系统输出打印项次(“显示”);
}
});
//contextMenu.hide();
通知.setContextMenu(contextMenu);
GridPane grid=新建GridPane();
网格设置间隙(4);
网格。setHgap(10);
网格设置填充(新的插图(5,5,5,5));
添加(新标签(“到”)、0、0;
添加(通知,1,0);
组根=(组)scene.getRoot();
root.getChildren().add(网格);
舞台场景;
stage.show();
notification.addEventHandler(MouseEvent.MOUSE_单击,(MouseEvent me)->{
if(me.getButton()==MouseButton.PRIMARY){
System.out.println(“鼠标左键按下”);
System.out.println(notification.getScaleX());
System.out.println(notification.getScaleY());
System.out.println(me.getScreenX());
System.out.println(me.getScreenY());
show(通知,me.getScreenX(),me.getScreenY());
}否则{
contextMenu.hide();
}
});
}

}

似乎非常错误,限制了对VBox的扩展,所以我修改了这个示例以扩展窗格。这使得在任何布局下都可以将该类作为自定义菜单移动。我认为它可以正常工作,我正在尝试它。但当我们调整场景大小时,会出现某些问题。如果你有一个修复窗格,我认为它工作得很好。@NaderNader如果你只是想减少文件,那么你可以使用
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);
}
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();
        }
    });
  }