10.8 创建本地菜单

本文介绍如何在Adobe AIR应用中创建和管理本地菜单,包括根菜单、子菜单、分隔符及上下文菜单等,并展示了如何使用XML声明式定义菜单结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建本地菜单

要创建一个菜单,先构造一个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; 

设置dock icon菜单

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

        }
 

    }
 

}
 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值