[Flex] 组件Tree系列 —— 实现右键拓展功能
主程序mxml:
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <!--功能描述:结合tree拓展右键功能 必须在index.template.html设置params.wmode = "opaque"以屏蔽flash右键;--> 4 5 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 6 xmlns:s="library://ns.adobe.com/flex/spark" 7 xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" 8 initialize="init()"> 9 <fx:Script> 10 <![CDATA[ 11 import com.render.TreeRightClickManager; 12 13 import mx.controls.Alert; 14 import mx.controls.Menu; 15 import mx.controls.listClasses.IListItemRenderer; 16 import mx.events.MenuEvent; 17 18 [Event(name="rightClick",type="flash.events.ContextMenuEvent")] 19 20 private var rightClickRegisted:Boolean = false; 21 private var menu:Menu; 22 [Bindable] 23 private var data:XML; 24 25 private function init():void{ 26 data= 27 <actor label="周星驰" level="0"> 28 <year label="1988" level="1"> 29 <item label="《霹雳先锋》香港票房8916612 " level="2"/> 30 <item label="《捕风汉子》香港票房3149395" level="2"/> 31 <item label="《最佳女婿》香港票房5807710" level="2"/> 32 </year> 33 </actor>; 34 if (!rightClickRegisted){ 35 TreeRightClickManager.regist(); 36 rightClickRegisted = true; 37 } 38 //加载右击事件 39 tree.addEventListener(TreeRightClickManager.RIGHT_CLICK,treeRightClickHandler); 40 } 41 42 /** 43 *树右击事件 44 **/ 45 private function treeRightClickHandler(event:ContextMenuEvent):void 46 { 47 tree_onRightClicked(event); 48 tree_removeMenu(); 49 tree_InitMenu(); 50 } 51 52 53 private function tree_onRightClicked(e:ContextMenuEvent):void 54 { 55 var rightClickItemRender:IListItemRenderer; 56 var rightClickIndex:int; 57 if(e.mouseTarget is IListItemRenderer) 58 { 59 rightClickItemRender = IListItemRenderer(e.mouseTarget); } 60 61 else if(e.mouseTarget.parent is IListItemRenderer) 62 { 63 rightClickItemRender = IListItemRenderer(e.mouseTarget.parent); 64 } 65 if(rightClickItemRender != null) 66 { 67 rightClickIndex = tree.itemRendererToIndex(rightClickItemRender); 68 if(tree.selectedIndex != rightClickIndex) 69 { 70 tree.selectedIndex = rightClickIndex; 71 } 72 } 73 } 74 75 /** 76 * 删除右键菜单 77 **/ 78 private function tree_removeMenu():void 79 { 80 if(menu!=null) 81 { 82 menu.hide(); 83 menu.removeEventListener(MenuEvent.ITEM_CLICK,tree_MenuItemSelected); 84 menu=null; 85 } 86 } 87 88 /** 89 * 生成右键菜单 90 **/ 91 private var selectedId:String=""; 92 private var selectedLabel:String=""; 93 private function tree_InitMenu():void 94 { 95 var currentItem:XML=tree.selectedItem as XML; 96 selectedId=currentItem.@id; 97 selectedLabel=currentItem.@label; 98 var level:String=currentItem.@level; 99 100 menu = Menu.createMenu(this, tree_createMenuItems(level), false); 101 menu.iconField="itemIcon";//右键菜单的图标 102 menu.labelField="label"; //右键菜单的名称 103 menu.variableRowHeight = true; 104 menu.addEventListener(MenuEvent.ITEM_CLICK, tree_MenuItemSelected); //右键菜单的事件 105 var point:Point = new Point(mouseX,mouseY); 106 point = localToGlobal(point); 107 menu.show(point.x,point.y); //显示右键菜单 108 } 109 110 111 /** 112 * 根据节点不同,生成不同的菜单 113 **/ 114 private function tree_createMenuItems(level:String):Array 115 116 { 117 var menuItems:Array = new Array(); 118 var menuXs:Object= new Object; 119 menuXs.label = '刷新'; 120 //menuXs.itemIcon = this.menu_TZ_add; //给菜单加图标 121 menuItems.push(menuXs); 122 var menuExpand:Object=new Object(); 123 menuExpand.label="展开当前节点"; 124 menuItems.push(menuExpand); 125 var menuClose:Object=new Object(); 126 menuClose.label="关闭当前节点"; 127 menuItems.push(menuClose); 128 var menuExpandAll:Object=new Object(); 129 menuExpandAll.label="展开所有节点"; 130 menuItems.push(menuExpandAll); 131 var menuCloseAll:Object=new Object(); 132 menuCloseAll.label="关闭所有节点"; 133 menuItems.push(menuCloseAll); 134 switch(level){ 135 case "0": 136 var menuAddNj:Object = new Object; 137 menuAddNj.label = "添加明星"; 138 menuItems.push(menuAddNj); 139 var menuDelNj:Object=new Object(); 140 menuDelNj.label="删除明星"; 141 menuItems.push(menuDelNj); 142 break; 143 case "1": 144 var menuAddBj:Object=new Object(); 145 menuAddBj.label="添加年份"; 146 menuItems.push(menuAddBj); 147 var menuDelBj:Object=new Object(); 148 menuDelBj.label="删除年份"; 149 menuItems.push(menuDelBj); 150 var menuAddStu:Object=new Object(); 151 menuAddStu.label="添加影片"; 152 menuItems.push(menuAddStu); 153 break; 154 case "2": 155 var menuEditStu:Object=new Object(); 156 menuEditStu.label="修改影片"; 157 menuItems.push(menuEditStu); 158 var menuDelStu:Object=new Object(); 159 menuDelStu.label="删除影片"; 160 menuItems.push(menuDelStu); 161 break; 162 } 163 164 return menuItems; 165 166 } 167 /** 168 * 点击菜单,相应方法 169 **/ 170 private function tree_MenuItemSelected(event:MenuEvent):void 171 172 { 173 var menuItem:Object = event.menu.selectedItem as Object; 174 switch(menuItem.label) 175 { 176 case "展开当前节点": 177 nodeExpand(); 178 break; 179 case "关闭当前节点": 180 nodeClose(); 181 break; 182 case "展开所有节点": 183 nodeExpandAll(); 184 break; 185 case "关闭所有节点": 186 nodeCloseAll(); 187 break; 188 case "删除影片": 189 delStuNode(); 190 break; 191 case "添加影片": 192 addStuNode(); 193 break; 194 195 } 196 } 197 198 199 private function treeChanged(event:Event):void{ 200 var selectedTreeNode:XML; 201 selectedTreeNode=Tree(event.target).selectedItem as XML; 202 //Alert.show("您点击了:"+selectedTreeNode.@label,"提示"); 203 204 } 205 206 /** 207 * 展开当前节点 208 **/ 209 private function nodeExpand():void{ 210 tree.expandItem(tree.selectedItem,true); 211 } 212 213 /** 214 * 关闭当前节点 215 **/ 216 private function nodeClose():void{ 217 tree.expandItem(tree.selectedItem,false); 218 219 } 220 221 /** 222 * 展开所有节点 223 **/ 224 private function nodeExpandAll():void{ 225 for each(var item:XML in tree.dataProvider) { 226 tree.expandChildrenOf(item,true); 227 } 228 } 229 230 /** 231 * 关闭所有节点 232 **/ 233 private function nodeCloseAll():void{ 234 //方法1:studentTree.openItems = []; 235 //方法2: 236 for each(var item:XML in tree.dataProvider) { 237 tree.expandChildrenOf(item,false); 238 } 239 } 240 241 /** 242 * 删除节点 243 **/ 244 private function delStuNode():void{ 245 Alert.show("删除影片 ID="+selectedId+" 名称="+selectedLabel,"提示",4,null,ok); 246 function ok():void 247 { 248 var delStuItemPar:Object=new Object(); 249 delStuItemPar=tree.selectedItem.parent(); 250 var delStuInx:int=tree.selectedItem.childIndex(); 251 tree.dataDescriptor.removeChildAt(delStuItemPar,tree.selectedItem,delStuInx,tree.dataProvider); 252 } 253 254 } 255 256 /** 257 * 添加影片 258 **/ 259 private function addStuNode():void{ 260 var node:XML=<item label="新影片" level="2"/>; 261 (tree.selectedItem as XML).appendChild(node); 262 } 263 264 ]]> 265 </fx:Script> 266 <fx:Declarations> 267 <!-- 将非可视元素(例如服务、值对象)放在此处 --> 268 </fx:Declarations> 269 <s:Panel x="25" y="23" width="250" height="448" title="喜剧之王"> 270 <mx:Tree id="tree" left="0" top="0" width="100%" height="100%" labelField="@label" change="treeChanged(event)" dataProvider="{data}" allowMultipleSelection ="true"/> 271 </s:Panel> 272 </s:Application>
com.render.TreeRightClickManager类:
1 package com.render 2 { 3 import flash.display.InteractiveObject; 4 import flash.events.ContextMenuEvent; 5 import flash.events.MouseEvent; 6 import flash.external.ExternalInterface; 7 8 import mx.core.Application; 9 import mx.core.FlexGlobals; 10 11 public class TreeRightClickManager 12 { 13 static private var rightClickTarget:*; 14 static public const RIGHT_CLICK:String = "rightClick"; 15 static private const javascript:XML = 16 <script> 17 <![CDATA[ 18 function(flashObjectId) 19 { 20 var RightClick = { 21 init: function (flashObjectId) { 22 this.FlashObjectID = flashObjectId; 23 this.Cache = this.FlashObjectID; 24 if(window.addEventListener){ 25 window.addEventListener("mousedown", this.onGeckoMouse(), true); 26 } else { 27 document.getElementById(this.FlashObjectID).parentNode.onmouseup = function() { document.getElementById(RightClick.FlashObjectID).parentNode.releaseCapture(); } 28 document.oncontextmenu = function(){ if(window.event.srcElement.id == RightClick.FlashObjectID) { return false; } else { RightClick.Cache = "nan"; }} 29 document.getElementById(this.FlashObjectID).parentNode.onmousedown = RightClick.onIEMouse; 30 } 31 }, 32 /** 33 * GECKO / WEBKIT event overkill 34 * @param {Object} eventObject 35 */ 36 killEvents: function(eventObject) { 37 if(eventObject) { 38 if (eventObject.stopPropagation) eventObject.stopPropagation(); 39 if (eventObject.preventDefault) eventObject.preventDefault(); 40 if (eventObject.preventCapture) eventObject.preventCapture(); 41 if (eventObject.preventBubble) eventObject.preventBubble(); 42 } 43 }, 44 /** 45 * GECKO / WEBKIT call right click 46 * @param {Object} ev 47 */ 48 onGeckoMouse: function(ev) { 49 return function(ev) { 50 if (ev.button != 0) { 51 RightClick.killEvents(ev); 52 if(ev.target.id == RightClick.FlashObjectID && RightClick.Cache == RightClick.FlashObjectID) { 53 RightClick.call(); 54 } 55 RightClick.Cache = ev.target.id; 56 } 57 } 58 }, 59 /** 60 * IE call right click 61 * @param {Object} ev 62 */ 63 onIEMouse: function() { 64 if (event.button > 1) { 65 if(window.event.srcElement.id == RightClick.FlashObjectID && RightClick.Cache == RightClick.FlashObjectID) { 66 RightClick.call(); 67 } 68 document.getElementById(RightClick.FlashObjectID).parentNode.setCapture(); 69 if(window.event.srcElement.id) 70 RightClick.Cache = window.event.srcElement.id; 71 } 72 }, 73 /** 74 * Main call to Flash External Interface 75 */ 76 call: function() { 77 document.getElementById(this.FlashObjectID).rightClick(); 78 } 79 } 80 81 RightClick.init(flashObjectId); 82 } 83 ]]> 84 </script>; 85 86 public function TreeRightClickManager() 87 { 88 return; 89 } 90 91 static public function regist() : Boolean 92 { 93 if (ExternalInterface.available) 94 { 95 ExternalInterface.call(javascript, ExternalInterface.objectID); 96 ExternalInterface.addCallback("rightClick", dispatchRightClickEvent); 97 //Application.application.addEventListener(MouseEvent.MOUSE_OVER,mouseOverHandler); 98 FlexGlobals.topLevelApplication.addEventListener(MouseEvent.MOUSE_OVER,mouseOverHandler); 99 100 } 101 return true; 102 } 103 104 static private function mouseOverHandler(event:MouseEvent) : void 105 { 106 rightClickTarget = InteractiveObject(event.target); 107 return; 108 } 109 110 static private function dispatchRightClickEvent() : void 111 { 112 var event:ContextMenuEvent; 113 if(rightClickTarget !=null) 114 { 115 event =new ContextMenuEvent(RIGHT_CLICK,true,false, rightClickTarget as InteractiveObject, rightClickTarget as InteractiveObject); 116 rightClickTarget.dispatchEvent(event); 117 } 118 return; 119 } 120 121 } 122 }
注:必须在index.template.html设置params.wmode = "opaque"以屏蔽flash右键
------------------------------------------------------------------
Always put yourself in the other's shoes.If you feel that it hurts you,it probably hurts others,too.------------------------------------------------------------------