選單的基本概念

Flash Player 9 以及更新的版本,Adobe AIR 1.0 以及更新的版本

如需在 AIR 應用程式中建立原生功能表的快速說明與程式碼範例,請到 Adobe Developer Connection 參閱下列快速入門文章:

原生選單類別可以讓您存取執行應用程式之作業系統的原生選單功能。NativeMenu 物件可以用於應用程式選單 (可在 Mac OS X 中使用)、視窗選單 (可在 Windows 和 Linux 中使用)、快顯選單和彈出式選單。

在 AIR 外部,您可使用快顯選單類別,修改您應用程式中使用者對某物件按下右鍵或 Command+按一下時,Flash Player 要自動顯示的快顯選單。(AIR 應用程式不會顯示自動快顯選單。)

選單類別

選單類別包括:

各種選單

AIR 支援下列選單類型:

快顯選單
當使用者以滑鼠右鍵按一下或按 Command+按一下 SWF 內容中的互動式物件或 HTML 內容中的 document 元素時,會開啟快顯選單做為回應。

在 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 選單組件的另一個優點,就是您可以透過宣告的方式,將選單指定為 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 事件能讓您在使用者看到選單之前,更新選單內容或項目的外觀。例如,在「Open Recent」選單之 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 類別中加以定義。

所指定的對等按鍵字串會自動在選單項目名稱旁顯示,其格式則視使用者的作業系統和系統偏好設定而異。

備註: 如果您將 Keyboard.COMMAND 值指定給 Windows 作業系統中的輔助按鍵陣列,則選單中不會顯示任何對等按鍵。不過,Control 鍵必須用來啟動選單命令。

下列範例會指定 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;