在有关JavaFX的最新文章中 ,我集中讨论了不使用JavaFX 1.x的JavaFXScript和不使用JavaFX 2.0的新FXML来使用JavaFX 2.0的新Java API 。 所有这些示例均已使用标准Java编译器进行了编译,并使用标准Java启动 器执行。 在本文中,我将继续演示使用JavaFX 2.0支持的纯Java API的主题,同时演示JavaFX 2.0菜单的开发。

在本文的后面,我将列出此示例的整个代码清单,但首先显示代码片段,以使您更轻松地专注于每一部分。 使用JavaFX 2.0菜单的一个很好的起点是实例化MenuBar的实例。 如下所示,这很简单。

实例化javafx.scene.control.MenuBar

final MenuBar menuBar = new MenuBar();

MenuBar可以包含Menu实例作为其子级,并且每个Menu实例都可以具有MenuItem的实例作为其子级。 下一个代码清单演示了Menu实例化,将MenuItem实例(或SeparatorMenuItem的实例)添加到该Menu实例,然后将Menu实例添加到MenuBar的实例。

将新实例化的Menu和MenuItem实例添加到MenuBar

// Prepare left-most 'File' drop-down menu
final Menu fileMenu = new Menu('File');
fileMenu.getItems().add(new MenuItem('New'));
fileMenu.getItems().add(new MenuItem('Open'));
fileMenu.getItems().add(new MenuItem('Save'));
fileMenu.getItems().add(new MenuItem('Save As'));
fileMenu.getItems().add(new SeparatorMenuItem());
fileMenu.getItems().add(new MenuItem('Exit'));
menuBar.getMenus().add(fileMenu);

上面的示例对于实际使用而言过于简化。 没有任何与单击任何菜单项相关联的事件处理程序或操作,并且没有通过击键而不是通过鼠标单击来选择菜单项的方法。 下一个代码清单演示了MenuItem实例的实例化,这些实例不仅包含文本字符串,还包含更多内容。 在此代码清单中,有一个使用MenuItemBuilder构建更复杂的MenuItem的示例,该MenuItem包括与按键组合的关联以及与动作处理程序的关联。

具有击键和事件关联的更复杂的MenuItem实例化

// Prepare 'Help' drop-down menu
final Menu helpMenu = new Menu('Help');
final MenuItem searchMenuItem = new MenuItem('Search');
searchMenuItem.setDisable(true);
helpMenu.getItems().add(searchMenuItem);
final MenuItem onlineManualMenuItem = new MenuItem('Online Manual');
onlineManualMenuItem.setVisible(false);
helpMenu.getItems().add(onlineManualMenuItem);
helpMenu.getItems().add(new SeparatorMenuItem());
final MenuItem aboutMenuItem =
   MenuItemBuilder.create()
                  .text('About')
                  .onAction(
                      new EventHandler<ActionEvent>()
                      {
                         @Override public void handle(ActionEvent e)
                         {
                            out.println('You clicked on About!');
                         }
                      })
                  .accelerator(
                      new KeyCodeCombination(
                         KeyCode.A, KeyCombination.CONTROL_DOWN))
                  .build();             
helpMenu.getItems().add(aboutMenuItem);
menuBar.getMenus().add(helpMenu);

除了演示MenuItemBuilder ,将按键组合(在这种情况下为CTRL-A)与菜单项相关联,以及将动作与菜单项相关联之外,此代码示例还演示了使用setDisable(boolean)或禁用菜单项(显示为灰色或使用setVisible(boolean)使其完全不显示。 尽管我可以指定禁用菜单项或使用MenuItemBuilder使菜单项不可见,但在此示例中,我有意在MenuItem上使用了“ set”方法来与使用MenuItemBuilder进行对比。

为了完整起见,这是我的示例的完整代码清单。

JavaFxMenus.java(完整清单)

package dustin.examples;

import static java.lang.System.out;

import javafx.application.Application;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 * Example of creating menus in JavaFX.
 * 
 * @author Dustin
 */
public class JavaFxMenus extends Application
{
   /**
    * Build menu bar with included menus for this demonstration.
    * 
    * @param menuWidthProperty Width to be bound to menu bar width.
    * @return Menu Bar with menus included.
    */
   private MenuBar buildMenuBarWithMenus(final ReadOnlyDoubleProperty menuWidthProperty)
   {
      final MenuBar menuBar = new MenuBar();

      // Prepare left-most 'File' drop-down menu
      final Menu fileMenu = new Menu('File');
      fileMenu.getItems().add(new MenuItem('New'));
      fileMenu.getItems().add(new MenuItem('Open'));
      fileMenu.getItems().add(new MenuItem('Save'));
      fileMenu.getItems().add(new MenuItem('Save As'));
      fileMenu.getItems().add(new SeparatorMenuItem());
      fileMenu.getItems().add(new MenuItem('Exit'));
      menuBar.getMenus().add(fileMenu);

      // Prepare 'Examples' drop-down menu
      final Menu examplesMenu = new Menu('JavaFX 2.0 Examples');
      examplesMenu.getItems().add(new MenuItem('Text Example'));
      examplesMenu.getItems().add(new MenuItem('Objects Example'));
      examplesMenu.getItems().add(new MenuItem('Animation Example'));
      menuBar.getMenus().add(examplesMenu);

      // Prepare 'Help' drop-down menu
      final Menu helpMenu = new Menu('Help');
      final MenuItem searchMenuItem = new MenuItem('Search');
      searchMenuItem.setDisable(true);
      helpMenu.getItems().add(searchMenuItem);
      final MenuItem onlineManualMenuItem = new MenuItem('Online Manual');
      onlineManualMenuItem.setVisible(false);
      helpMenu.getItems().add(onlineManualMenuItem);
      helpMenu.getItems().add(new SeparatorMenuItem());
      final MenuItem aboutMenuItem =
         MenuItemBuilder.create()
                        .text('About')
                        .onAction(
                            new EventHandler<ActionEvent>()
                            {
                               @Override public void handle(ActionEvent e)
                               {
                                  out.println('You clicked on About!');
                               }
                            })
                        .accelerator(
                            new KeyCodeCombination(
                               KeyCode.A, KeyCombination.CONTROL_DOWN))
                        .build();             
      helpMenu.getItems().add(aboutMenuItem);
      menuBar.getMenus().add(helpMenu);

      // bind width of menu bar to width of associated stage
      menuBar.prefWidthProperty().bind(menuWidthProperty);

      return menuBar;
   }

   /**
    * Start of JavaFX application demonstrating menu support.
    * 
    * @param stage Primary stage.
    */
   @Override
   public void start(final Stage stage)
   {
      stage.setTitle('Creating Menus with JavaFX 2.0');
      final Group rootGroup = new Group();
      final Scene scene = new Scene(rootGroup, 800, 400, Color.WHEAT);
      final MenuBar menuBar = buildMenuBarWithMenus(stage.widthProperty());
      rootGroup.getChildren().add(menuBar);
      stage.setScene(scene);
      stage.show();
   }

   /**
    * Main executable function for running examples.
    * 
    * @param arguments Command-line arguments: none expected.
    */
   public static void main(final String[] arguments)
   {
      Application.launch(arguments);
   }
}

下一系列屏幕快照将尝试演示使用java启动器执行时该应用程序的外观。 图像显示了应用程序的初始外观,单击了“文件”菜单时显示了下拉菜单,单击了“帮助”菜单时显示了下拉菜单,最后显示了已写消息的图像单击“帮助”菜单下的“关于”菜单项时,输出到标准输出。

本文中示例中的代码具有许多语法功能,Swing开发人员应该对此感到熟悉。 实际上,上面使用的许多JavaFX类的名称与AWT类的名称相同,因此在使用IDE的自动导入建议时,必须小心导入正确的类。

上面的示例还提供了JavaFX绑定的示例。 特别是,菜单栏的宽度绑定到舞台宽度的宽度。 这很有用,因为使菜单栏跨越视觉的整个顶部看起来更好,而不是宽度足以容纳菜单标签看起来更好。

构建菜单在JavaFX 2.0中非常简单,可以使用基本Java工具和JavaFX 2.0 JAR来实现。

祝您编程愉快,别忘了分享!