【问题标题】:How an action can be performed when clicking on a menu item?单击菜单项时如何执行操作?
【发布时间】:2014-02-26 15:12:38
【问题描述】:

我正在使用 Netbeans IDE 在 javafx 中做一个项目。我是 javafx 的新手。我的项目中有一个菜单栏。单击每个菜单项(不是新场景)时,我需要在同一窗口上打开一个新页面。代码如下:

private VBox addVBox1() {

    final VBox vbox = new VBox();
    vbox.setPadding(new Insets(20,40,30,4)); 
    vbox.setSpacing(10);

    MenuBar menuBar = new MenuBar();

    Menu menuFile1 = new Menu("ADD");
    Menu menuFile2 = new Menu("EDIT");
    Menu menuFile3 = new Menu("VIEW");
    Menu menuFile4 = new Menu("HELP");

    MenuItem add1 = new MenuItem("ENTER STUDENT DETAILS");
    MenuItem add2 = new MenuItem("ENTER C-MARK");
    MenuItem add3 = new MenuItem("ENTER ATTENDANCE");

    MenuItem add4 = new MenuItem("EDIT STUDENT DETAILS");
    MenuItem add6 = new MenuItem("EDIT C-MARK");
    MenuItem add8 = new MenuItem("EDIT ATTENDANCE");

    MenuItem add10 = new MenuItem("STUDENT DETAILS");
    MenuItem add11 = new MenuItem("C-MARK");
    MenuItem add12 = new MenuItem("ATTENDANCE");

    MenuItem add13 = new MenuItem("VIEW HELP"); 

    add1.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent t) {
            //...WHAT TO INCLUDE HERE ?
        }
    });

    menuFile1.getItems().addAll(add1,add2,add3);
    menuFile2.getItems().addAll(add4,add6,add8);
    menuFile3.getItems().addAll(add10,add11,add12);
    menuFile4.getItems().addAll(add13);
    menuBar.getMenus().addAll(menuFile1,menuFile2,menuFile3,menuFile4);

    vbox.getChildren().addAll(menuBar);

    return vbox;
   }

在我的项目中,单击按钮时会打开新页面。它的代码是:

btn2.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent e) {
    ((Stage)btn2.getScene().getWindow()).setScene(new Scene(new Login()));
     }
    });

是否可以在菜单项的情况下实现此代码?单击菜单项时,我应该如何编辑此代码以执行操作?

【问题讨论】:

  • 你做得对(如果奇怪的话)。尝试在 ActionEvent 中添加 `System.out.println("hi from add1 in vbox")'。您只是将 vbox 设置为可见,它已经是。
  • @brian 我想在单击菜单项时在同一窗口中打开一个新页面。我不知道该怎么做。这就是为什么我在 setVisible() 上方留下一行。我该怎么做?
  • 新页面还是新场景?我想你的意思是一个弹出窗口,这是一个新场景。您应该编辑问题,以便说明您想要做什么。

标签: javafx javafx-2 menuitem


【解决方案1】:

我不知道您所说的新页面到底是什么意思。有一个Pagination control,但我认为你不是那个意思。以下是添加 TextArea 的方法,但您必须设计 UI 并选择自己的控件。

add1.setOnAction(new EventHandler<ActionEvent>() {
    public void handle(ActionEvent t) {
        vbox.getChildren().add(new TextArea());
    }
});

这是创建新窗口的方法,但您可能想询问有关设计对话框的问题。这是一个很好的答案https://stackoverflow.com/a/14168238/2855515

add1.setOnAction(new EventHandler<ActionEvent>() {
    public void handle(ActionEvent t) {
        Stage stage = new Stage();
        Scene scene = new Scene(new VBox());
        stage.setTitle("popup");
        stage.setScene(scene);
        stage.show();
    }
});

【讨论】:

  • 嘿...只需发布以前的代码。我需要它。我会尝试新的场景。我觉得会更好。
【解决方案2】:

我认为这个问题没有得到正确回答,问题被误解了。

TomJ 问:

是否可以在菜单项的情况下实现此代码?

当他说“菜单项”时,他是指Menu 还是MenuItem?他正在清除显示如何为MenuItem 执行此操作的正确代码。我想他在问如何为Menu 做同样的事情。我尝试为Menu 执行此操作,在Menu 上调用处理程序的代码与为MenuItem 执行此操作略有不同。

这是一个简单的代码示例,其中单击执行菜单时调用执行方法:

Menu viewMenu = new Menu("View");
MenuItem viewJobs = new MenuItem("Jobs");
viewJobs.setOnAction(viewJobsAction);
MenuItem viewFileSelection = new MenuItem("File Selection");
viewFileSelection.setOnAction(e->{viewFileSelection());
viewMenu.getItems().addAll(viewJobs, viewFileSelection);

Menu execute = new Menu("Execute");
execute.onShownProperty().setValue(e->{execute());
// if the following line is not added, the onShownProperty event handler
// will never be called!
execute.getItems().addAll(new MenuItem());


Menu help = new Menu("Help");
MenuItem helpItem = new MenuItem("Help");
helpItem.setOnAction(e->{showHelp()}
MenuItem aboutItem = new MenuItem("About");
aboutItem.setOnAction(e->{showAbout()}
help.getItems().addAll(helpItem,aboutItem);
menubar.getMenus().addAll(viewMenu, execute, help);

必须将伪造的MenuItem 添加到执行菜单中才能正常工作。对于菜单,最好使用onShownPropertyonShowingProperty 而不是使用setOnAction。它们中的任何一个都可以工作,但setOnAction 需要在调用处理程序之前再次单击。

onShowingProperty 的 JavaDoc for Menu 说:

在 ContextMenu 显示之前调用,即使菜单有 没有要显示的项目。但是请注意,如果菜单 没有有效的锚节点。

听起来代码应该可以在不添加任何MenuItems 的情况下工作,但事实并非如此。但是它说如果菜单没有有效的锚节点,则不会进行调用。我不确定锚节点是什么,也找不到任何有关如何将锚节点添加到菜单的文档。添加伪造的空MenuItem 显然使执行菜单具有有效的锚节点。如果有人对锚节点了解更多,请回复并解释,但我给出的代码示例可以接受。

【讨论】:

  • 仅供参考,anchors 可以在 ContextMenus 为 shown 时设置
  • 我不太明白Menu或MenuItem与ContextMenu的关系。 ContextMenu 既不是 Menu 也不是 MenuItem 的子类或超类。它们之间是否存在某种关联。最大的问题是,如果 Menu 已经没有锚,事件就不会发生!
  • 好的,我查看了 Menu 和 MenuItem 的实现,发现 MenuItem 有一个父级,它是一个 ContextMenu。 Menu 是 MenuItem 的子类,因此它也有一个父类 ContextMenu。这两个类都只是包装 ContentMenu 是有道理的。 Menu 和 MenuItem 将用户从有关 ContextMenu 定位位置的细节中解脱出来。谢谢jewelsea,那是我需要的指针!
  • 是的,菜单内容相当复杂,尤其是当您开始查看实现时。但是很多复杂性在于实现而不是公共 API,因此其中相当一部分是隐藏的。与许多其他 JavaFX 控件不同,菜单不是 JavaFX 节点(我认为是因为有时它们需要使用弹出窗口来显示,而窗口不是节点)。在内部,它们有一个到节点的桥梁(有时还有弹出窗口)。
  • 我玩过它,它只是菜单栏中的顶级菜单,您必须至少有一个 MenuItem 才能拥有 ContextMenu。让顶级菜单包含子菜单并且这些菜单不需要任何 MenuItems 是非常好的。那是因为它们的父级是 ContextMenu。 MenuBar 不充当 ContextMenu,这就是为什么您必须添加至少一个虚拟 MenuItem 的技巧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多