如何创建弹出菜单

San*_*til 11 popupmenu javafx-2

我是javafx的新手.我想在鼠标右键单击时显示弹出菜单.我找到一个教程在这里这里,但不明白.我想创建弹出菜单,在此链接上显示图像.

现在我正在创造舞台,但我不想舞台.我需要显示右键单击显示的弹出菜单,单击任意位置时关闭.

这是我的代码,我正在使用舞台,但我需要打开上面链接的弹出菜单.

 public void MouseClickedOnTree(MouseEvent event) {
if (event.isSecondaryButtonDown()) {

        System.out.println("secondary press");
        final Stage optionstage = new Stage();

        VBox vBox = new VBox(5);
        vBox.setMinHeight(50);
        vBox.setMinWidth(50);
        Button btnNewTestBed = new Button("New Testbed");
        btnNewTestBed.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                try {
                     optionstage.close();
                    stage.show();
                } catch (IOException ex) {
                    Exceptions.printStackTrace(ex);
                }
            }
        });
        Button btnOpenTestbed = new Button("Open Testbed");
        btnOpenTestbed.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                optionstage.close();

            }
        });
        optionstage.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent t) {
                if (t.getCode() == KeyCode.ESCAPE) {
                    System.out.println("click on escape");
                    //Stage sb = (Stage) label.getScene().getWindow();//use any one object
                    if(optionstage.isShowing())
                        optionstage.close();
                }
            }
        });

        vBox.getChildren().addAll(btnNewTestBed, btnOpenTestbed);
        optionstage.setScene(new Scene(vBox, 100, 100));
        //stage.setScene(new Scene(new Group(new Text(50,50, "my second window")))); 
        optionstage.setX(event.getSceneX());
        optionstage.setY(event.getScreenY());
        optionstage.initStyle(StageStyle.UNDECORATED);
        optionstage.show();

    }
Run Code Online (Sandbox Code Playgroud)

请提供任何链接或参考.

Jam*_*s_D 24

代码的上下文不是很清楚:这是在事件处理程序中吗?如果是这样,它的事件处理程序是什么?如果没有,event开幕词中的内容是什么if

您提供的两个链接非常复杂; 在JavaFX中(与Swing不同),您应该只考虑将现有Node类子类化为非常高级的用例.只需创建一个弹出菜单,您就不需要这种复杂程度.

创建弹出菜单的最简单方法是Control(或子类); 你只需要创建一个ContextMenu,添加MenuItems,并将其设置为contextMenu你的控件:

TextField textField = new TextField("Type Something"); // we will add a popup menu to this text field
final ContextMenu contextMenu = new ContextMenu();
MenuItem cut = new MenuItem("Cut");
MenuItem copy = new MenuItem("Copy");
MenuItem paste = new MenuItem("Paste");
contextMenu.getItems().addAll(cut, copy, paste);
cut.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        System.out.println("Cut...");
    }
});
// ...
textField.setContextMenu(contextMenu);
Run Code Online (Sandbox Code Playgroud)

如果你想ContextMenu在一个非Control(a Pane或a Shape)的节点上使用a ,你就没有setContextMenu(...)方法,所以你只需要做一些工作:

final AnchorPane pane = new AnchorPane();
// fill pane with nodes, etc
// create context menu and menu items as above
pane.setOnMousePressed(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent event) {
        if (event.isSecondaryButtonDown()) {
            contextMenu.show(pane, event.getScreenX(), event.getScreenY());
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

看到的JavadocContextMenu教程了解更多详情.


fuz*_*BSc 14

James_D已经提供了一个与教程一致的工作示例,但我遇到了问题.James说的是,对于任何类型Control的节点,打开上下文菜单的正确方法是使用Control.setContextMenu().但是与本教程相反,在非控制节点上注册上下文菜单的正确方法如下(Java 8):

    pane.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, event -> {
        contextMenu.show(pane, event.getScreenX(), event.getScreenY());
        event.consume();
    });
    pane.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
        contextMenu.hide();
    });
Run Code Online (Sandbox Code Playgroud)

这与setContextMenu在幕后所做的一致.该setContextMenu实施控制使用和消耗的ContextMenuEvent但并没有消耗鼠标事件.这意味着如果您在窗格上为MouseEvent注册一个侦听器并在窗格中的Control上使用setContextMenu,则右键单击该控件将实际打开两个上下文菜单:当Pane侦听时,Control将侦听并使用ContextMenuEvent并使用MouseEvent.我在openddk-8的代码中发现,在Pane上注册ContextMenuEvent监听器解决了这个重复的上下文菜单问题.

我还发现,当用户点击其他地方时,默认情况下,在窗格上注册的菜单不会被忽略.不使用其事件的MOUSE_PRESSED侦听器确保在应该的时候关闭菜单.

  • Node中还有一个setOnContextMenuRequested()方法 (2认同)