创建本地菜单
要创建一个菜单,先构造一个NativeMenu对象作为根菜单:
var root:NativeMenu = new NativeMenu();
作为窗体或应用程序的根菜单,所有的菜单项必须为子菜单(上下文菜单的根菜单可包含所有三种类型的菜单项),AIR提供了两种方法创建子菜单。你可以通过菜单的addSubmenu()方法添加菜单项:
var editMenu:NativeMenuItem = root.addSubmenu(new NativeMenu(), "Edit");
你也可以创建菜单项然后再赋值给子菜单:
var editMenu:NativeMenuItem = root.addItem("Edit");
editMenu.submenu = new NativeMenu();
菜单创建好后,再赋值给应用程序,窗体或上下文菜单:
Shell.shell.menu = root;
nativeWindowObject.menu = root;
interactiveObject.contextMenu = root;
DockIcon(Shell.shell.icon).menu = root;
SystemTrayIcon(Shell.shell.icon).menu = root;
定义菜单项,子菜单和分隔符
一个菜单项可以是一个命令项,一个子菜单或一个分隔符。一个菜单项如果设置构造函数的isSeparator参数为true这变成一个分隔符。一个菜单项如果赋值给NativeMenu对象的submenu属性则变成一个子菜单(或使用addSubmenu() 方法),否则菜单项就是一个命令项,只有命令项可以发出select事件。
菜单中的菜单项顺序就是其加入的先后顺序,除非你自己修改了其索引值,如通过addItemAt()方法在指定位置加入菜单项。
var copy:NativeMenuItem = new NativeMenuItem("Copy",false);
copy.addEventListener(Event.SELECT,onCopyCommand);
editMenu.addItem(copy);
var editMenu:NativeMenuItem = new NativeMenuItem("Edit", false);
editMenu.submenu = new NativeMenu();
也可以使用菜单的addSubmenu()方法添加菜单项:
var editMenu:NativeMenuItem = root.addSubmenu(new NativeMenu(), "Edit");
var separatorA:NativeMenuItem = new NativeMenuItem("A", true);
editMenu.addItem(separatorA);
创建一个上下文菜单
在AIR,ContextMenu API 类继承自NativeMenu类。ContextMenu提供了一个事件属性,ContextMenuEvent.mouseTarget,其确定打开该菜单的对象。
上下文菜单(Context menus)可赋值给任何继承自InteractiveObject 类的Flash对象。通过设置对象的contextMenu属性进行赋值。
上下文菜单仍可以包含命令项及分隔符,在AIR上下文菜单中没有默认的菜单项。
下面的例子创建了一个简单的edit 菜单:
var editContextMenu:ContextMenu = new ContextMenu();
var item:NativeMenuItem;
item = editContextMenu.addItem(new ContextMenuItem("Cut"));
item.name="Cut";
editContextMenu.addItem(new ContextMenuItem("Copy"));
item.name="Copy";
editContextMenu.addItem(new ContextMenuItem("Paste"));
item.name="Paste";
editContextMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(event:ContextMenuEvent):void{
var command:NativeMenuItem = event.target as NativeMenuItem;
switch (command.name){
case "Cut" :
doCutCommand(event.mouseTarget);
break;
case "Copy" :
doCopyCommand(event.mouseTarget);
break;
case "Paste" :
doPasteCommand(event.mouseTarget);
break;
}
});
this.contextMenu = editContextMenu; //Where "this" is an InteractiveObject
显示弹出式菜单
通过调用菜单的display()方法可以随时在窗体的任意位置显示弹出式菜单。
下面的方法显示一个定义弹出式对象的菜单:
private function onMouseClick(event:MouseEvent):void{
popupMenu.display(event.target.stage, event.stageX, event.stageY);
}
注意:实际上没有必要在事件处理函数中显示菜单,任何方法都可以调用display()方法。
处理菜单事件
当一个菜单项被点击时,事件就会被触发,AIR程序会对此作出反应。
下面的代码输出被激活的菜单名称:
var submenu:NativeMenu = new NativeMenu();
var red:NativeMenuItem = new NativeMenuItem("Red");
red.addEventListener(Event.SELECT,announceSelection)
var green:NativeMenuItem = new NativeMenuItem("Green");
green.addEventListener(Event.SELECT,announceSelection)
var blue:NativeMenuItem = new NativeMenuItem("Blue");
blue.addEventListener(Event.SELECT,announceSelection)
var menuItem:NativeMenuItem = new NativeMenuItem("Change Color");
submenu.addItem(red);
submenu.addItem(green);
submenu.addItem(blue);
menuItem.submenu = submenu;
Shell.shell.menu.addItem(menuItem);
function announceSelection(e:Event):void {
var menuItem:NativeMenuItem = e.target as NativeMenuItem;
trace(menuItem.label + " has been selected")
}
声明式定义菜单
输入菜单和菜单项的属性是一件很枯燥的事情,不过菜单是一个有规律的层级结构,可以使用XML格式定义直接写在函数里。
下面的类继承自NativeMenu,在构造函数里传入XML对象,像这样:
{
import flash.display.NativeMenu;
import flash.display.NativeMenuItem;
import flash.events.Event;
public class DeclarativeMenu extends NativeMenu
{
public function DeclarativeMenu(XMLMenuDefinition:XML):void{
super();
addChildrenToMenu(this, XMLMenuDefinition.children());
}
private function addChildrenToMenu(menu:NativeMenu,
children:XMLList):NativeMenuItem{
var menuItem:NativeMenuItem;
var submenu:NativeMenu;
for each (var child:XML in children){
if(String(child.@label).length > 0){
menuItem = new NativeMenuItem(child.@label);
menuItem.name = child.name();
} else {
menuItem = new NativeMenuItem(child.name());
menuItem.name = child.name();
}
menu.addItem(menuItem);
if(child.children().length() > 0){
menuItem.submenu = new NativeMenu();
addChildrenToMenu(menuItem.submenu,child.children());
}
}
return menuItem;
}
}//End class
}//End package
要使用这个类创建菜单,只需要传入一个XML格式的菜单定义即可:
var menuDefinition:String =
"<root>" +
"<FileMenu label='File'>" +
"<NewMenu label='New'>" +
"<NewTextFile label='Text file'/>" +
"<NewFolder label='Folder'/>" +
"<NewProject label='Project'/>" +
"</NewMenu>" +
"<OpenCommand label='Open'/>" +
"<SaveCommand label='Save'/>" +
"</FileMenu>" +
"<EditMenu label='Edit'/>" +
"<CutCommand label='Cut'/>" +
"<CopyCommand label='Copy'/>" +
"<PasteCommand label='Paste'/>" +
"<EditMenu/>" +
"<FoodItems label='Food Items'>" +
"<Jellyfish/>" +
"<Tripe/>" +
"<Gizzard/>" +
"</FoodItems>" +
"</root>";
var test:DeclarativeMenu = new DeclarativeMenu(new XML(menuDefinition));
要监听菜单事件,你可以直接监听根菜单即可,通过event.target.name属性判定哪个命令项被触发,你也可以根据菜单名称搜索菜单项并添加独立的事件监听器。
例子:窗体和应用程序菜单
下面的例子使用菜单结构创建菜单,该例子也演示了事件处理过程:
import flash.display.NativeMenu;
import flash.display.NativeMenuItem;
import flash.display.NativeWindow;
import flash.display.Sprite;
import flash.events.Event;
import flash.filesystem.File;
import flash.system.Shell;
public class MenuExample extends Sprite
{
private