创建本地菜单
要创建一个菜单,先构造一个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对象,像这样:
package 
{ 
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属性判定哪个命令项被触发,你也可以根据菜单名称搜索菜单项并添加独立的事件监听器。
例子:窗体和应用程序菜单
下面的例子使用菜单结构创建菜单,该例子也演示了事件处理过程:
package { 
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 var recentDocuments:Array = new Array(new File("c:/GreatGatsby.pdf"), 
new File("c:/WarAndPeace.pdf"), 
new File("c:/Iliad.pdf")); 
public function MenuExample() 
{ 
var fileMenu:NativeMenuItem; 
var editMenu:NativeMenuItem; 
if(NativeWindow.supportsMenu){ 
stage.nativeWindow.menu = new NativeMenu(); 
stage.nativeWindow.menu.addEventListener(Event.SELECT, selectCommandMenu); 
fileMenu = stage.nativeWindow.menu.addItem(new NativeMenuItem("File")); 
fileMenu.submenu = createFileMenu(); 
editMenu = stage.nativeWindow.menu.addItem(new NativeMenuItem("Edit")); 
editMenu.submenu = createEditMenu(); 
} 

if(Shell.supportsMenu){ 
Shell.shell.menu.addEventListener(Event.SELECT, selectCommandMenu); 
fileMenu = Shell.shell.menu.addItem(new NativeMenuItem("File")); 
fileMenu.submenu = createFileMenu(); 
editMenu = Shell.shell.menu.addItem(new NativeMenuItem("Edit")); 
editMenu.submenu = createEditMenu(); 
} 
} 

public function createFileMenu():NativeMenu{ 
var fileMenu:NativeMenu = new NativeMenu(); 
fileMenu.addEventListener(Event.SELECT,selectCommandMenu); 

var newCommand:NativeMenuItem = fileMenu.addItem(new NativeMenuItem("New")); 
newCommand.addEventListener(Event.SELECT,selectCommand); 
var saveCommand:NativeMenuItem = fileMenu.addItem(new NativeMenuItem("Save")); 
saveCommand.addEventListener(Event.SELECT,selectCommand); 
var openRecentMenu:NativeMenuItem = 
fileMenu.addItem(new NativeMenuItem("Open Recent")); 
openRecentMenu.submenu = new NativeMenu(); 
openRecentMenu.submenu.addEventListener(Event.DISPLAYING, 
updateRecentDocumentMenu); 
openRecentMenu.submenu.addEventListener(Event.SELECT,selectCommandMenu); 

return fileMenu; 
} 

public function createEditMenu():NativeMenu{ 
var editMenu:NativeMenu = new NativeMenu(); 
editMenu.addEventListener(Event.SELECT,selectCommandMenu); 

var copyCommand:NativeMenuItem = editMenu.addItem(new NativeMenuItem("Copy")); 
copyCommand.addEventListener(Event.SELECT,selectCommand); 
var pasteCommand:NativeMenuItem = 
editMenu.addItem(new NativeMenuItem("Paste")); 
pasteCommand.addEventListener(Event.SELECT,selectCommand); 
editMenu.addItem(new NativeMenuItem("",true)); 
var preferencesCommand:NativeMenuItem = 
editMenu.addItem(new NativeMenuItem("Preferences")); 
preferencesCommand.addEventListener(Event.SELECT,selectCommand); 

return editMenu; 
} 

private function updateRecentDocumentMenu(event:Event):void{ 
trace("Updating recent document menu."); 
var docMenu:NativeMenu = NativeMenu(event.target); 

for each(var item:NativeMenuItem in docMenu.items){ 
docMenu.removeItem(item); 
} 

for each(var file:File in recentDocuments){ 
var menuItem:NativeMenuItem = 
docMenu.addItem(new NativeMenuItem(file.name)); 
menuItem.data = file; 
menuItem.addEventListener(Event.SELECT, selectRecentDocument); 
} 
} 

private function selectRecentDocument(event:Event):void{ 
trace("Selected recent document: " + event.target.data.name); 
} 

private function selectCommand(event:Event):void{ 
trace("Selected command: " + event.target.label); 
} 

private function selectCommandMenu(event:Event):void{ 
if(event.currentTarget.parent){ 
var menuItem:NativeMenuItem = 
findItemForMenu(NativeMenu(event.currentTarget)); 
if(menuItem){ 
trace("Select event for "" + 
event.target.label + 
"" command handled by menu: " + 
menuItem.label); 
} 
} else { 
trace("Select event for "" + 
event.target.label + 
"" command handled by root menu."); 
} 
} 

private function findItemForMenu(menu:NativeMenu):NativeMenuItem{ 
for each(var item:NativeMenuItem in menu.parent.items){ 
if(item){ 
if(item.submenu == menu){ 
return item; 
} 
} 
} 
return null; 
} 
} 
}
本文介绍如何在Adobe AIR应用中创建和管理本地菜单,包括根菜单、子菜单、分隔符及上下文菜单等,并展示了如何使用XML声明式定义菜单结构。

5万+

被折叠的 条评论
为什么被折叠?



