JavaFX菜单栏

时间:2020-01-09 10:36:38  来源:igfitidea点击:

JavaFX MenuBar为JavaFX应用程序提供了一个可视的下拉菜单,类似于大多数桌面应用程序在其应用程序窗口顶部所具有的菜单。 JavaFX的MenuBar由类javafx.scene.control.MenuBar表示。这是一个JavaFXMenuBar的示例屏幕截图:

创建一个MenuBar实例

必须先创建MenuBar实例,然后才能使用JavaFXMenuBar。这是创建JavaFXMenuBar实例的示例:

MenuBar menuBar = new MenuBar();

将MenuBar添加到场景图

一个MenuBar可见之前,你必须把它添加到JavaFX的场景图。这是向场景图添加JavaFXMenuBar的示例:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class JavaFXApp extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("JavaFX App");

        MenuBar menuBar = new MenuBar();

        VBox vBox = new VBox(menuBar);

        Scene scene = new Scene(vBox, 960, 600);

        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

注意如何将" MenuBar"添加到JavaFX场景的根布局(" VBox")中。这会将MenuBar放置在应用程序窗口的顶部。

注意,上面的示例没有向MenuBar添加任何菜单或者菜单项,因此,如果我们运行该示例,则实际上不会看到MenuBar。在以下各节中,我们将看到如何添加菜单和菜单项。

创建菜单实例

一旦创建了MenuBar实例,我们就可以向其中添加Menu实例(javafx.scene.control.Menu。Menu实例代表具有嵌套菜单项的单个垂直菜单。因此,我们可以添加多个将MenuBar实例添加到MenuBar中,以添加多个垂直下拉菜单。

这是在MenuBar中添加Menu的示例:

Menu menu1 = new Menu("Menu 1");

MenuBar menuBar = new MenuBar();

menuBar.getMenus().add(menu1);

这是一个截图,显示了由上面的示例代码配置的JavaFXMenuBar

如我们所见,MenuBar中只有一个菜单名为" Menu 1"。此菜单下没有嵌套的菜单项。在以下各节中,我们将了解如何将菜单项添加到Menu中。

菜单图形

我们可以通过调用" setGraphic()"方法为"菜单"设置图形图标。图形图标将显示在菜单的文本标签旁边。这是为JavaFXMenu实例设置图形图标的示例:

Menu menu = new Menu("Menu 1");
menu.setGraphic(new ImageView("file:volleyball.png"));

这是结果菜单在JavaFX应用程序中的外观:

菜单事件

一个JavaFXMenu实例可以触发几个事件,我们可以在应用程序中侦听这些事件。最常用的事件是:

  • onShowing
  • onShown
  • onHiding
  • onHidden

用鼠标单击"菜单"时,将显示其内容。这个动作会在Menu开始显示其菜单项之前触发onShowing事件。一旦菜单完全可见,就会触发" onShown"事件。

用鼠标单击显示的(打开的)"菜单"时,它再次隐藏其内容。此动作会在"菜单"开始隐藏其菜单项之前触发" onHiding"事件。菜单完全隐藏后,将触发" onHidden"事件。

我们可以使用setOnShowing(),setOnShown(),setOnHiding()和setOnHidden()方法来为上述事件设置" Menu"事件监听器。这是在JavaFXMenu上为这些事件设置事件侦听器的示例:

Menu menu = new Menu("Menu 1");

menu.setOnShowing(e -> { System.out.println("Showing Menu 1"); });
menu.setOnShown  (e -> { System.out.println("Shown Menu 1"); });
menu.setOnHiding (e -> { System.out.println("Hiding Menu 1"); });
menu.setOnHidden (e -> { System.out.println("Hidden Menu 1"); });

上面设置的"菜单"事件监听器仅在事件触发时向控制台输出一条消息。我们可以做一些更高级的操作,以备不时之需。

添加菜单项

创建Menu实例后,必须向其添加一个或者多个MenuItem实例。每个" MenuItem"对应于添加到菜单中的菜单项。这是将两个MenuItem实例添加到Menu的示例,然后将其添加到MenuBar:

Menu menu = new Menu("Menu 1");
MenuItem menuItem1 = new MenuItem("Item 1");
MenuItem menuItem2 = new MenuItem("Item 2");

menu.getItems().add(menuItem1);
menu.getItems().add(menuItem2);

MenuBar menuBar = new MenuBar();
menuBar.getMenus().add(menu);

如果在JavaFX应用程序中使用,则生成的JavaFXMenuBar如下所示:

MenuItem图形

我们可以将图标添加到菜单项。我们可以通过调用菜单项setGraphic()方法向菜单项中添加图形图标,并将要用于给定菜单项的图形作为参数传递给参数。这是一个将图像添加到上一节中的示例中创建的菜单项中的示例:

Menu menu = new Menu("Menu 1");

MenuItem menuItem1 = new MenuItem("Item 1");
menuItem1.setGraphic(new ImageView("file:soccer.png"));

MenuItem menuItem2 = new MenuItem("Item 2");
menuItem1.setGraphic(new ImageView("file:basketball.png"));

menu.getItems().add(menuItem1);
menu.getItems().add(menuItem2);

MenuBar menuBar = new MenuBar();
menuBar.getMenus().add(menu);

这是JavaFXMenuBar的外观,其中在其菜单项中添加了图形图标:

MenuItem事件

如果选择任何菜单项,则在前面的示例中创建的MenuBar配置将不起作用。为了响应对" MenuItem"的选择,我们必须在" MenuItem"上设置事件监听器。这是将事件侦听器添加到JavaFXMenuItem的示例:

MenuItem menuItem1 = new MenuItem("Item 1");

menuItem1.setOnAction(e -> {
    System.out.println("Menu Item 1 Selected");
});

注意,将Java Lambda作为参数添加到MenuItem的setOnAction()方法中。在选择了菜单项时,将执行此λ表达式。

子菜单

JavaFXMenuBar支持多层菜单。嵌套在另一个菜单中的菜单称为子菜单。 Menu类扩展了MenuItem类,因此可以用作另一个Menu实例内的菜单项。这是一个创建带有单个子菜单的JavaFX菜单的示例:

Menu menu = new Menu("Menu 1");

Menu subMenu = new Menu("Menu 1.1");
MenuItem menuItem11 = new MenuItem("Item 1.1.1");
subMenu.getItems().add(menuItem11);
menu.getItems().add(subMenu);

MenuItem menuItem1 = new MenuItem("Item 1");
menu.getItems().add(menuItem1);

MenuItem menuItem2 = new MenuItem("Item 2");
menu.getItems().add(menuItem2);

MenuBar menuBar = new MenuBar();
menuBar.getMenus().add(menu);

上面示例产生的JavaFXMenuBar看起来类似于:

检查菜单项

JavaFXMenuBar支持在菜单中使用检查菜单项。检查菜单项是可以"选择"并保持选中状态直到以后未选择的菜单项。只要选中菜单项,它旁边就会显示一个小的选中标记。

检查菜单项由CheckMenuItem(javafx.scene.control.CheckMenuItem)类表示。这是一个JavaFX菜单的示例,其中带有CheckMenuItem

CheckMenuItem checkMenuItem = new CheckMenuItem("Check this!");

menu.getItems().add(checkMenuItem);

如我们在前面的示例中所看到的,然后需要将Menu实例添加到MenuBar中以使其可见。选中了检查菜单菜单项的结果菜单如下所示:

单选菜单项

JavaFXMenuBar也支持单选菜单项。单选菜单项是与标准JavaFX单选按钮一样只能选择一组菜单项中的一个的菜单项。

单选菜单项由" RadioMenuItem"表示。必须将RadioMenuItem实例添加到ToggleGroup中,以使它们互斥。这就是JavaFX如何知道哪个RadioMenuItem实例属于一起的情况。这是使用一组单选菜单项的JavaFx菜单的示例:

Menu menu = new Menu("Menu 1");

RadioMenuItem choice1Item = new RadioMenuItem("Choice 1");
RadioMenuItem choice2Item = new RadioMenuItem("Choice 2");
RadioMenuItem choice3Item = new RadioMenuItem("Choice 3");

ToggleGroup toggleGroup = new ToggleGroup();
toggleGroup.getToggles().add(choice1Item);
toggleGroup.getToggles().add(choice2Item);
toggleGroup.getToggles().add(choice3Item);

menu.getItems().add(choice1Item);
menu.getItems().add(choice2Item);
menu.getItems().add(choice3Item);

MenuBar menuBar = new MenuBar();
menuBar.getMenus().add(menu);

以下是此示例代码生成的JavaFx菜单的外观:

菜单项分隔符

MenuBar支持菜单项分隔符。分隔符是一条水平线,用于分隔菜单项组。分隔符通常用于向用户发信号通知哪些菜单项相互关联。

菜单项分隔符由SeparatorMenuItem类表示。这是一个菜单示例,其中两个菜单项由SeparatorMenu分隔:

MenuItem item1 = new MenuItem("Item 1");
MenuItem item2 = new MenuItem("Item 2");
SeparatorMenuItem separator = new SeparatorMenuItem();

menu.getItems().add(item1);
menu.getItems().add(separator);
menu.getItems().add(item2);

MenuBar menuBar = new MenuBar();
menuBar.getMenus().add(menu);

生成的JavaFX菜单如下所示:

自定义控制菜单项

JavaFXMenuBar还支持将自定义JavaFX控件用作菜单项。为此,我们需要使用" CustomMenuItem"(javafx.scene.control.CustomMenuItem)类。

" CustomMenuItem"类具有" setContent()"方法,可用于设置要在菜单中显示的自定义JavaFX控件。这是一个示例,它同时显示JavaFX Button和JavaFXSlider作为自定义菜单项:

Menu menu = new Menu("Menu 1");

Slider slider = new Slider(0, 100, 50);

CustomMenuItem customMenuItem = new CustomMenuItem();
customMenuItem.setContent(slider);
customMenuItem.setHideOnClick(false);
menu.getItems().add(customMenuItem);

Button button = new Button("Custom Menu Item Button");
CustomMenuItem customMenuItem2 = new CustomMenuItem();
customMenuItem2.setContent(button);
customMenuItem2.setHideOnClick(false);
menu.getItems().add(customMenuItem2);

MenuBar menuBar = new MenuBar();
menuBar.getMenus().add(menu);

请注意以值false为参数的对CustomMenuItem setHideOnClick()的调用。这样做是为了在用户与自定义菜单项控件交互时使菜单保持打开状态。如果我们将值设置为" true",则该菜单将在用户第一次单击该控件时立即关闭,从而无法进行进一步的交互。对于普通菜单项,我们实际上确实希望菜单立即关闭,但是对于某些自定义菜单项,我们可能不希望这样做。仍然可以通过再次单击菜单标题来关闭菜单。

这是结果菜单的外观: