菜单基础知识

Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本

有关在 AIR 应用程序中创建本机菜单的快速介绍和代码示例,请参阅 Adobe Developer Connection 上的以下快速入门文章:

通过本机菜单类,可以访问运行您的应用程序的操作系统的本机菜单功能。NativeMenu 对象可用于应用程序菜单(Mac OS X 中提供)、窗口菜单(Windows 和 Linux 中提供)、上下文菜单和弹出菜单。

在 AIR 外,您可以使用上下文菜单类修改上下文菜单,当用户右键单击或按住 Cmd 键单击应用程序的中的对象时,Flash Player 会自动显示上下文菜单。(AIR 应用程序不会自动显示上下文菜单。)

菜单类

菜单类包括:

菜单类型

AIR 支持以下类型的菜单:

上下文菜单
右键单击或按住 Command 键单击 SWF 内容中的交互式对象或 HTML 内容中的文档元素时,作为响应,上下文菜单会打开。

在 Flash Player 运行时中,上下文菜单自动显示。您可以使用 ContextMenu 类和 ContextMenuItem 类向此菜单中添加您自己的命令。您也可以删除一些(非全部)内置命令。

在 AIR 运行时中,可以使用 NativeMenu 类或 ContextMenu 类创建上下文菜单。在 AIR 中的 HTML 内容中,您可以使用 Webkit HTML 和 JavaScript API 向 HTML 元素添加上下文菜单。

应用程序菜单(仅限 AIR)
应用程序菜单是应用于整个应用程序的全局菜单。Mac OS X 支持应用程序菜单,但 Windows 或 Linux 不支持。 在 Mac OS X 上,操作系统自动创建应用程序菜单。可以使用 AIR 菜单 API 将项目和子菜单添加到标准菜单中。可以添加用于处理现有菜单命令的侦听器。还可以删除现有项目。

窗口菜单(仅限 AIR)
窗口菜单与单个窗口关联,并显示在标题栏的下方。通过创建 NativeMenu 对象并将它分配给 NativeWindow 对象的 menu 属性,可以向窗口添加菜单。Windows 和 Linux 操作系统支持窗口菜单,但 Mac OS X 不支持。本机窗口菜单只能与有系统镶边的窗口一起使用。

停靠栏和系统任务栏图标菜单(仅限 AIR)
这些图标菜单类似于上下文菜单,分配给 Mac OS X 停靠栏或 Windows 和 Linux 任务栏上通知区域中的应用程序图标。 停靠栏图标菜单和系统任务栏图标菜单使用 NativeMenu 类。在 Mac OS X 上,菜单中的项目添加到标准操作系统项目的上方。Windows 或 Linux 中没有标准菜单。

弹出菜单(仅限 AIR)
AIR 弹出菜单类似于上下文菜单,但不一定与特定应用程序对象或组件关联。通过调用任何 NativeMenu 对象的 display() 方法,可以使弹出菜单在窗口中的任何位置显示。

自定义菜单
本机菜单完全由操作系统调出,因此存在于 Flash 和 HTML 呈现模型以外。您可以不使用本机菜单,而总是使用 MXML、ActionScript 或 JavaScript 创建自己的自定义非本机菜单(仅 AIR)。这些菜单必须在应用程序内容中完全呈现。

Flex 菜单
Adobe® Flex™ 框架提供了一组 Flex 菜单组件。Flex 菜单都是由运行时调出,而不是操作系统来调出,而且 Flex 菜单不是 本机 菜单。Flex 菜单组件可用于没有系统镶边的 Flex 窗口。使用 Flex 菜单组件的另一个好处是能够以声明方式指定 MXML 格式的菜单。如果您使用的是 Flex 框架,请对窗口菜单使用 Flex 菜单类,非不要使用本机类。

默认菜单(仅 AIR)

以下默认菜单由操作系统或内置 AIR 类提供:

  • Mac OS X 上的应用程序菜单

  • Mac OS X 上的停靠栏图标菜单

  • HTML 内容中的所选文本和图像的上下文菜单

  • TextField 对象(或扩展 TextField 的对象)中的所选文本的上下文菜单

关于上下文菜单

在 SWF 内容中,对于从 InteractiveObject 继承的任何对象,通过将菜单对象分配给该对象的 contextMenu 属性,可以为该对象指定上下文菜单。默认情况下包含的几个命令有:“前进”、“后退”、“打印”、“品质”和“缩放”。在 AIR 运行时中,指定给 contextMenu 的菜单对象的类型可以是 NativeMenu 或 ContextMenu。在 Flash Player 运行时中,仅 ContextMenu 类可用。

可以在使用 ContextMenu 和 ContextMenuItem 类时侦听本机菜单事件或上下文菜单事件;两者都已调度。ContextMenuEvent 对象属性所具有的一个优势为:contextMenuOwner 可识别与菜单关联的对象,而 mouseTarget 可识别为打开菜单曾单击的对象。NativeMenuEvent 对象中无此信息。

以下示例创建一个 Sprite,并添加一个简单的编辑上下文菜单:

var sprite:Sprite = new Sprite(); 
sprite.contextMenu = createContextMenu() 
private function createContextMenu():ContextMenu{ 
    var editContextMenu:ContextMenu = new ContextMenu(); 
    var cutItem:ContextMenuItem = new ContextMenuItem("Cut") 
    cutItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, doCutCommand); 
    editContextMenu.customItems.push(cutItem); 
     
    var copyItem:ContextMenuItem = new ContextMenuItem("Copy") 
    copyItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, doCopyCommand);             
    editContextMenu.customItems.push(copyItem); 
     
    var pasteItem:ContextMenuItem = new ContextMenuItem("Paste") 
    pasteItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, doPasteCommand); 
    editContextMenu.customItems.push(pasteItem); 
         
    return editContextMenu 
} 
private function doCutCommand(event:ContextMenuEvent):void{trace("cut");} 
private function doCopyCommand(event:ContextMenuEvent):void{trace("copy");} 
private function doPasteCommand(event:ContextMenuEvent):void{trace("paste");}
注: 与在浏览器环境中显示的 SWF 内容相比,AIR 中的上下文菜单没有任何内置命令。

自定义 Flash Player 上下文菜单

在浏览器或放映文件中,SWF 内容中的上下文菜单总包含内置项。您可以删除菜单中“设置”和“关于”命令外的所有这些默认命令。如果将 Stage 属性 showDefaultContextMenu 设置为 false ,则会从上下文菜单中删除这些命令。

要为特定显示对象创建自定义的上下文菜单,请创建 ContextMenu 类的一个新实例,调用 hideBuiltInItems() 方法,并将该实例分配给该 DisplayObject 实例的 contextMenu 属性。下面的示例为一个动态绘制的正方形提供了一个上下文菜单命令,用于将其更改为随机颜色:

var square:Sprite = new Sprite(); 
square.graphics.beginFill(0x000000); 
square.graphics.drawRect(0,0,100,100); 
square.graphics.endFill(); 
square.x = 
square.y = 10; 
addChild(square); 
 
var menuItem:ContextMenuItem = new ContextMenuItem("Change Color"); 
menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,changeColor); 
var customContextMenu:ContextMenu = new ContextMenu(); 
customContextMenu.hideBuiltInItems(); 
customContextMenu.customItems.push(menuItem); 
square.contextMenu = customContextMenu; 
 
function changeColor(event:ContextMenuEvent):void 
{ 
    square.transform.colorTransform = getRandomColor(); 
} 
function getRandomColor():ColorTransform 
{ 
    return new ColorTransform(Math.random(), Math.random(),         Math.random(),1,(Math.random() * 512) - 255,         (Math.random() * 512) -255, (Math.random() * 512) - 255, 0); 
}

本机菜单结构 (AIR)

本机菜单本质上是分层的。NativeMenu 对象包含子级 NativeMenuItem 对象。表示子菜单的 NativeMenuItem 对象又可以包含 NativeMenu 对象。结构中的顶级或根级的菜单对象表示应用程序菜单和窗口菜单的菜单栏。(上下文、图标和弹出菜单没有菜单栏)。

下图说明了一个典型菜单的结构。根菜单表示菜单栏,它包含的两个菜单项引用“File”(文件)子菜单和“Edit”(编辑)子菜单。在此结构中,“File”(文件)子菜单包含两个命令项和一个引用项,该引用项引用“Open Recent”(打开最近的项目)子菜单,而该子菜单本身又包含三个项目。“Edit”(编辑)子菜单包含三个命令和一个分隔符。

定义子菜单同时需要 NativeMenu 和 NativeMenuItem 对象。NativeMenuItem 对象定义在父菜单中显示的标签,并允许用户打开子菜单。NativeMenu 对象充当子菜单中的项目的容器。NativeMenuItem 对象通过 NativeMenuItem 的 submenu 属性引用 NativeMenu 对象。

若要查看创建此菜单的代码示例,请参阅 本机菜单示例:窗口和应用程序菜单 (AIR)

菜单的事件

NativeMenu 和 NativeMenuItem 对象均调度 preparing displaying select 事件:

Preparing: 每当对象即将开始用户交互时,该菜单及其菜单项会将 preparing 事件调度到任何注册的侦听器。交互包括打开菜单或使用键盘快捷键选择项目。
注: preparing 事件仅适用于 Adobe AIR 2.6 和更高版本。
Displaying:
在显示菜单的前一刻,菜单及其菜单项将 displaying 事件调度到任何注册的侦听器。

preparing displaying 事件允许您在向用户显示菜单内容或项目外观之前对其进行更新。例如,在“打开最近的文件”菜单的 displaying 事件的侦听器中,可以更改菜单项以反映最近查看过的文档的当前列表。

如果您删除了一个其键盘快捷键会触发 preparing 事件的菜单项,则将实际取消菜单交互,并且将不会调度 select 事件。

该事件的 target currentTarget 属性均为在其上注册了侦听器的对象:菜单本身或其中的一个项目。

preparing 事件将在 displaying 事件之前调度。通常,您只会侦听这两个事件中的一个,而不会同时侦听二者。

Select:
当用户选择命令项时,项目会将 select 事件调度到任何注册的侦听器。不能选择子菜单和分隔符项,因此永远不会调度 select 事件。

select 事件从菜单项上升到它的包含菜单,然后上升到根菜单。可以直接在项目上侦听 select 事件,也可以在菜单结构的更高位置侦听。在菜单上侦听 select 事件时,可以使用该事件的 target 属性识别所选项。当事件沿菜单层次结构上升时,该事件对象的 currentTarget 属性可识别当前菜单对象。

注: ContextMenu 和 ContextMenuItem 对象调度 menuItemSelect menuSelect 事件以及 select preparing displaying 事件。

本机菜单命令的等效键 (AIR)

可以为菜单命令分配等效键(有时称为快捷键)。当按下键或组合键时,菜单项会将 select 事件调度到任何注册的侦听器。包含该项目的菜单必须是应用程序菜单的一部分,或者是要调用的命令的活动窗口菜单的一部分。

等效键有两部分,一部分是表示主键的字符串,另一部分是一组必须同时按下的功能键。若要分配主键,请将菜单项 keyEquivalent 属性设置为该键的单字符字符串。如果使用大写字母,则 Shift 键会自动添加到功能键组中。

在 Mac OS X 上,默认功能键是 Command 键 ( Keyboard.COMMAND )。在 Windows 和 Linux 中,是 Control 键 ( Keyboard.CONTROL )。这些默认键会自动添加到功能键组中。若要分配其他功能键,请将包含所需键代码的新键组分配给 keyEquivalentModifiers 属性。默认键组将被覆盖。无论使用默认功能键还是分配自己的功能键组,如果分配给 keyEquivalent 属性的字符串是大写字母,则会添加 Shift 键。用于功能键的键代码的常量在 Keyboard 类中定义。

所分配的等效键字符串将自动显示在菜单项名称的旁边。格式取决于用户的操作系统和系统首选项。

注: 在 Windows 操作系统上,如果将 Keyboard.COMMAND 值分配给功能键组,则菜单中不显示等效键。但是,必须使用 Ctrl 键才能激活菜单命令。

以下示例分配 Ctrl+Shift+G 作为菜单项的等效键:

var item:NativeMenuItem = new NativeMenuItem("Ungroup"); 
item.keyEquivalent = "G"; 

此示例通过直接设置功能键组将 Ctrl+Shift+G 分配为等效键:

var item:NativeMenuItem = new NativeMenuItem("Ungroup"); 
item.keyEquivalent = "G"; 
item.keyEquivalentModifiers = [Keyboard.CONTROL]; 
注: 等效键仅为应用程序菜单和窗口菜单触发。如果将等效键添加到上下文或弹出菜单,则等效键将显示在菜单标签中,但永远不会调用关联的菜单命令。

助记键 (AIR)

助记键是菜单的操作系统键盘接口的一部分。Linux、Mac OS X 和 Windows 都允许用户通过键盘打开菜单并选择命令,但有一些细微的区别。

在 Mac OS X 中,用户键入菜单或命令的第一个或前两个字母,然后按 Return 键。 mnemonicIndex 属性将被忽略。

在 Windows 上,仅一个字母是有效的。默认情况下,有效字母是标签中的第一个字符,但是,如果将助记键分配给菜单项,则有效字符将成为所指定的字母。如果一个菜单中的两个项有相同的有效字符(无论是否分配了助记键),则用户的键盘与菜单的交互稍有改变。用户必须将该字母按下所需的次数来突出显示所需项,然后按 Enter 完成选择,而不是仅按单个字母就能选择菜单或命令。为了保持一致的行为,应向窗口菜单中的每个菜单项都分配一个唯一的助记键。

在 Linux 中不提供默认的助记键。 必须指定菜单项的 mnemonicIndex 属性的值才能提供助记键。

指定助记键字符作为标签字符串中的索引。标签中第一个字符的索引是 0。因此,若要使用“r”作为带“Format”标签的菜单项的助记键,可以将 mnemonicIndex 属性设置为等于 2。

var item:NativeMenuItem = new NativeMenuItem("Format"); 
item.mnemonicIndex = 2; 

菜单项状态

菜单项有两个状态属性: checked enabled

checked
设置为 true 将在项目标签旁边显示选中标记。
var item:NativeMenuItem = new NativeMenuItem("Format"); 
item.checked = true; 

enabled
true false 之间切换值可以控制是否启用命令。禁用的项目将在视觉上“灰显”,并且不调度 select 事件。
var item:NativeMenuItem = new NativeMenuItem("Format"); 
item.enabled = false; 

将对象附加到菜单项

使用 NativeMenuItem 类的 data 属性可以引用每个项目中的任意对象。例如,在“Open Recent”(打开最近的项目)菜单中,可以将每个文档的 File 对象分配给每个菜单项。

var file:File = File.applicationStorageDirectory.resolvePath("GreatGatsby.pdf") 
var menuItem:NativeMenuItem = docMenu.addItem(new NativeMenuItem(file.name)); 
menuItem.data = file;