Flash ActionScript 3.0 實現的樹形菜單
這是我初學ActionScript 3.0時實現的treeMenu類, 貼出來分享,或許對ActionScript 3.0的初學者有一定的幫助,但不建議在應用程序開發中使用。
各位博友可以就此發表自己的觀點,謝謝各位指教。
下面是treeMenu類的定義:

/**//**
* treeMenu類
*
* 構造一個樹形菜單
*
* @author twzheng (twzheng@msn.cn)
* @date 20070903
* @version 1.0.070903
*
*/

////////////////////////////////////////////////////////////////////////////////////////////
// 在這里添加修改說明:
//
//
////////////////////////////////////////////////////////////////////////////////////////////

package com.components


{
import flash.display.MovieClip;
public class treeMenu extends MovieClip

{
public var rootMenu:menuItem;
function treeMenu()

{
}
public function newTreeMenu()

{
if(rootMenu != null)

{
trace(" 錯誤:根菜單已存在,根菜單只能有一個!");
return;
}
rootMenu = new menuItem("rootMenu","rootMenu");
if(rootMenu == null)

{
trace(" 創建根菜單失敗!");
return;
}
rootMenu.removeChild(rootMenu.menuLabel);
rootMenu.childMenu.x = 0;
rootMenu.childMenu.y = 0;
this.addChild(rootMenu);
}
public function addChildMenu(bMenu:menuItem, mName:String, mLabel:String)

{
var mItem = new menuItem(mName,mLabel);
if(mItem == null) return;
var index:int = bMenu.childItem.length;
mItem.y = menuItemLocalizer(bMenu.childItem);
bMenu.childItem[index] = mItem;
bMenu.childMenu.addChild(mItem);
}
private function menuItemLocalizer(bMenu:Array):int

{
var num:int = 0;
for each (var item in bMenu)
num = num + item.getHeight();
return num;
}
}
}


/**//**
* 菜單項節點類
*
* @author twzheng (http://www.ugocn.com)
* @date 20070903
* @version 1.0.070903
*/

import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.ui.Mouse;

internal class menuItem extends MovieClip


{
public var menuName:String; // 菜單項名稱
public var menuLabel:TextField; // 菜單項標簽(即顯示給用戶的菜單標簽)
public var childMenu:DisplayObjectContainer; // 子菜單項容器
public var childItem:Array; // 子菜單項數組
private var h:Number; // 菜單項高度屬性,記錄的是實際高度(包含隱藏菜單高度)
function menuItem(mName:String, mLabel:String)

{
if(mName == "" || mName == null || mLabel == null)

{
trace(" 菜單名或者菜單標簽為空,添加菜單項失敗!");
return;
}
menuName = mName;
menuLabel = new TextField();
menuLabel.text = mLabel;
menuLabel.height = 22;
menuLabel.textColor = 0x000000;
menuLabel.background = false;
menuLabel.addEventListener(MouseEvent.MOUSE_MOVE,itemMouseMove);
menuLabel.addEventListener(MouseEvent.MOUSE_OUT,itemMouseOut);
this.addChild(menuLabel);
childMenu = new MovieClip();
childMenu.addEventListener(Event.ADDED,mcAddedEvent);
childMenu.addEventListener(Event.REMOVED,mcRemovedEvent);
this.childMenu.x = this.menuLabel.x + 8;
this.childMenu.y = this.menuLabel.y + this.menuLabel.height;
this.addChild(childMenu);
childItem = new Array();
this.h = menuLabel.height;
// 菜單項單擊事件應留給外部使用者實現
//this.menuLabel.addEventListener(MouseEvent.CLICK,itemClick);
}
// 返回菜單項顯示的真實高度,即菜單項的實際高度減去隱藏菜單項的高度
public function getHeight():Number

{
return h - getHideMenu(this);
}

/**//**
* 獲取item的childMenu中所有隱藏子菜單項的高度和
*
* @item 主菜單項,此函數即計算它的子菜單中隱藏菜單的高度
* @return 返回item的childMenu中visible屬性為false的子菜單高度和
*
* 注:如果item.childMenu的visible屬性為false即返回childMenu的高度,如果item.childMenu為空則返回0。
*/
private function getHideMenu(item:menuItem):Number

{
var sumHeight = 0;
if(item.childMenu.visible)

{
if(item.childItem == null)
return 0;
for(var i = 0; i < item.childItem.length; i++)

{
// 對每個子菜單項遞歸
sumHeight = sumHeight + getHideMenu(item.childItem[i]);
}
return sumHeight;
}
else
return item.childMenu.height;
}

/**//**
* 獲取名字為mName菜單項的對象
*
* @mName 菜單項名字字符串
* @return 返回調用此函數的菜單項的子菜單中名字為mName的子菜單項對象
*/
public function getMenu(mName:String):menuItem

{
for each(var item in childItem)

{
if(item.menuName == mName)
return item;
}
trace(" 錯誤:不存在名為 " + mName + " 的子菜單項!");
return null;
}

/**//**
* 接收TextField的單擊事件,更改TextField對應item的子菜單顯示狀態
*
* @item 接收到單擊事件的menuLabel對應的菜單項(menuItem)
*/
public function chgChildItemVisible(item:menuItem)

{
var chgHeight = 0;
if(item.childMenu.visible)

{
chgHeight = item.getHeight() - item.menuLabel.height;
item.childMenu.visible = false;
updateMenu(item,0 - chgHeight);
}
else

{
item.childMenu.visible = true;
chgHeight = item.childMenu.height - getHideMenu(item);
updateMenu(item,chgHeight);
}
}

/**//**
* 更新各菜單項位置
* 注:由于參數item的子菜單容器childMenu高度發生變化而需要改變其同級別的菜單項以及所有的父菜單項的y坐標
*
* @item 引發調用此函數的菜單項(即由于item的childMenu高度改變而需要調用此函數)
* @chgHeight 需要改變的y坐標高度,正值即增加y坐標值,負值減小y坐標值
*/
private function updateMenu(item:menuItem, chgHeight:Number)

{
if(item == null) return;
// item.parent為父菜單的子菜單容器,item.parent.paren才是對應的父菜單項
var parentItem = item.parent.parent;

var i,index:int = 0;
if(parentItem == null || ! (parentItem is menuItem))
return;
// 搜索item在父菜單的子菜單數組childItem中的索引
index = parentItem.childItem.indexOf(item);
// 改變item同級別的并且位于其后的菜單項的顯示位置
for(i = index + 1; i < parentItem.childItem.length; i++)

{
parentItem.childItem[i].y = parentItem.childItem[i].y + chgHeight;
}
// 對父菜單項遞歸
updateMenu(parentItem,chgHeight);
}
// private function itemClick(e:MouseEvent)
// {
// var item = e.currentTarget;
// chgChildItemVisible(item.parent);
// }
private function itemMouseMove(e:MouseEvent)

{
var item = e.currentTarget;
item.background = true;
item.backgroundColor = 0x66ccFF;
item.textColor = 0x0000FF;
}
private function itemMouseOut(e:MouseEvent)

{
var item = e.currentTarget;
item.background = false;
item.backgroundColor = 0xFFFFFF;
item.textColor = 0x000000;
}
// 向子菜單容器加入子菜單項事件,增加當前菜單的高度
private function mcAddedEvent(e:Event)

{// 此事件響應函數還需要更改。。。
var mc = e.currentTarget;
h = h + 22;//mc.height;///2
}
// 從子菜單容器移除子菜單項事件,減小當前菜單的高度
private function mcRemovedEvent(e:Event)

{// 此事件響應函數還需要更改。。。
var mc = e.currentTarget;
h = h - 22;//mc.height/2;
}
}


treeMenu類簡單應用
package


{
import flash.display.MovieClip;
import flash.events.*;

import com.library.treeMenu;
public class menu extends MovieClip

{
function menu()

{
var tm = new treeMenu();
tm.newTreeMenu(); // 創建根菜單
tm.addChildMenu(tm.rootMenu,"基菜單-01","基菜單-01");
tm.rootMenu.getMenu("基菜單-01").menuLabel.addEventListener(MouseEvent.CLICK,eventClick);
tm.addChildMenu(tm.rootMenu.getMenu("基菜單-01"),"一級菜單-011","一級菜單-011");
tm.addChildMenu(tm.rootMenu,"基菜單-02","基菜單-02");
tm.rootMenu.getMenu("基菜單-02").menuLabel.addEventListener(MouseEvent.CLICK,eventClick);
tm.addChildMenu(tm.rootMenu.getMenu("基菜單-02"),"一級菜單-021","一級菜單-021");
tm.rootMenu.getMenu("基菜單-02").getMenu("一級菜單-021").menuLabel.addEventListener(MouseEvent.CLICK,eventClick);
tm.addChildMenu(tm.rootMenu.getMenu("基菜單-02").getMenu("一級菜單-021"),"二級菜單-0211","二級菜單-0211");
tm.rootMenu.getMenu("基菜單-02").getMenu("一級菜單-021").getMenu("二級菜單-0211").menuLabel.addEventListener(MouseEvent.CLICK,eventClick);
tm.addChildMenu(tm.rootMenu.getMenu("基菜單-02").getMenu("一級菜單-021").getMenu("二級菜單-0211"),"三級菜單-02111","三級菜單-02111");
tm.addChildMenu(tm.rootMenu,"基菜單-03","基菜單-03");
// 菜單坐標 默認坐標(0,0)
//tm.x = 50;
//tm.y = 50;
this.addChild(tm);
}
private function eventClick(e:MouseEvent)

{
var item = e.currentTarget;
item.parent.chgChildItemVisible(item.parent); // 隱藏或顯示子菜單項
}
}
}
