[Flex] 组件Tree系列 —— 实现右键拓展功能

主程序mxml:

<?xml version="1.0" encoding="utf-8"?>
<!--功能描述:结合tree拓展右键功能 必须在index.template.html设置params.wmode = "opaque"以屏蔽flash右键;-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
      xmlns:s="library://ns.adobe.com/flex/spark"
      xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
      initialize="init()">
 <fx:Script>
  <![CDATA[
   import com.render.TreeRightClickManager;

   import mx.controls.Alert;
   import mx.controls.Menu;
   import mx.controls.listClasses.IListItemRenderer;
   import mx.events.MenuEvent;

   [Event(name="rightClick",type="flash.events.ContextMenuEvent")]

   private var rightClickRegisted:Boolean = false;
   private var menu:Menu;
   [Bindable]
   private var data:XML;

   private function init():void{
    data=
     <actor label="周星驰" level="0">
      <year label="1988" level="1">
       <item label="《霹雳先锋》香港票房8916612 " level="2"/>
       <item label="《捕风汉子》香港票房3149395" level="2"/>
        <item label="《最佳女婿》香港票房5807710" level="2"/>
      </year>
     </actor>;
    if (!rightClickRegisted){
     TreeRightClickManager.regist();
     rightClickRegisted = true;
    }
    //加载右击事件
    tree.addEventListener(TreeRightClickManager.RIGHT_CLICK,treeRightClickHandler);
   }

   /**
    *树右击事件
    **/
   private function treeRightClickHandler(event:ContextMenuEvent):void
   {
    tree_onRightClicked(event);
    tree_removeMenu();
    tree_InitMenu();
   }

   private function tree_onRightClicked(e:ContextMenuEvent):void
   {
    var rightClickItemRender:IListItemRenderer;
    var rightClickIndex:int;
    if(e.mouseTarget is IListItemRenderer)
    {
     rightClickItemRender = IListItemRenderer(e.mouseTarget);         }

    else if(e.mouseTarget.parent is IListItemRenderer)
    {
     rightClickItemRender = IListItemRenderer(e.mouseTarget.parent);
    }
    if(rightClickItemRender != null)
    {
     rightClickIndex = tree.itemRendererToIndex(rightClickItemRender);
     if(tree.selectedIndex != rightClickIndex)
     {
      tree.selectedIndex = rightClickIndex;
     }
    }
   }

   /**
    * 删除右键菜单
    **/
   private function tree_removeMenu():void
   {
    if(menu!=null)
    {
     menu.hide();
     menu.removeEventListener(MenuEvent.ITEM_CLICK,tree_MenuItemSelected);
     menu=null;
    }
   }

   /**
    * 生成右键菜单
    **/
   private var selectedId:String="";
   private var selectedLabel:String="";
   private function tree_InitMenu():void
   {
    var currentItem:XML=tree.selectedItem as XML;
    selectedId=[email protected];
    selectedLabel=[email protected];
    var level:String=[email protected];

    menu = Menu.createMenu(this, tree_createMenuItems(level), false);
    menu.iconField="itemIcon";//右键菜单的图标
    menu.labelField="label";  //右键菜单的名称
    menu.variableRowHeight = true;
    menu.addEventListener(MenuEvent.ITEM_CLICK, tree_MenuItemSelected);  //右键菜单的事件
    var point:Point = new Point(mouseX,mouseY);
    point = localToGlobal(point);
    menu.show(point.x,point.y);  //显示右键菜单
   }

   /**
    * 根据节点不同,生成不同的菜单
    **/
   private function tree_createMenuItems(level:String):Array  

   {
    var menuItems:Array = new Array();
    var menuXs:Object= new Object;
    menuXs.label = ‘刷新‘;
    //menuXs.itemIcon = this.menu_TZ_add;  //给菜单加图标
    menuItems.push(menuXs);
    var menuExpand:Object=new Object();
    menuExpand.label="展开当前节点";
    menuItems.push(menuExpand);
    var menuClose:Object=new Object();
    menuClose.label="关闭当前节点";
    menuItems.push(menuClose);
    var menuExpandAll:Object=new Object();
    menuExpandAll.label="展开所有节点";
    menuItems.push(menuExpandAll);
    var menuCloseAll:Object=new Object();
    menuCloseAll.label="关闭所有节点";
    menuItems.push(menuCloseAll);
    switch(level){
     case "0":
      var menuAddNj:Object = new Object;
      menuAddNj.label = "添加明星";
      menuItems.push(menuAddNj);
      var menuDelNj:Object=new Object();
      menuDelNj.label="删除明星";
      menuItems.push(menuDelNj);
      break;
     case "1":
      var menuAddBj:Object=new Object();
      menuAddBj.label="添加年份";
      menuItems.push(menuAddBj);
      var menuDelBj:Object=new Object();
      menuDelBj.label="删除年份";
      menuItems.push(menuDelBj);
      var menuAddStu:Object=new Object();
      menuAddStu.label="添加影片";
      menuItems.push(menuAddStu);
      break;
     case "2":
      var menuEditStu:Object=new Object();
      menuEditStu.label="修改影片";
      menuItems.push(menuEditStu);
      var menuDelStu:Object=new Object();
      menuDelStu.label="删除影片";
      menuItems.push(menuDelStu);
      break;
    }            

    return menuItems;

   }
   /**
    * 点击菜单,相应方法
    **/
   private function tree_MenuItemSelected(event:MenuEvent):void

   {
    var menuItem:Object = event.menu.selectedItem as Object;
    switch(menuItem.label)
    {
     case "展开当前节点":
      nodeExpand();
      break;
     case "关闭当前节点":
      nodeClose();
      break;
     case "展开所有节点":
      nodeExpandAll();
      break;
     case "关闭所有节点":
      nodeCloseAll();
      break;
     case "删除影片":
      delStuNode();
      break;
     case "添加影片":
      addStuNode();
      break;

    }
   }

   private function treeChanged(event:Event):void{
    var selectedTreeNode:XML;
    selectedTreeNode=Tree(event.target).selectedItem as XML;
    //Alert.show("您点击了:"[email protected],"提示");

   }
   /**
    * 展开当前节点
    **/
   private function nodeExpand():void{
    tree.expandItem(tree.selectedItem,true);
   }

   /**
    * 关闭当前节点
    **/
   private function nodeClose():void{
    tree.expandItem(tree.selectedItem,false);

   } 

   /**
    * 展开所有节点
    **/
   private function nodeExpandAll():void{
    for each(var item:XML in tree.dataProvider) {
     tree.expandChildrenOf(item,true);
    }
   }

   /**
    * 关闭所有节点
    **/
   private function nodeCloseAll():void{
    //方法1:studentTree.openItems = [];
    //方法2:
    for each(var item:XML in tree.dataProvider) {
     tree.expandChildrenOf(item,false);
    }
   }

   /**
    * 删除节点
    **/
   private function delStuNode():void{
    Alert.show("删除影片 ID="+selectedId+"  名称="+selectedLabel,"提示",4,null,ok);
    function ok():void
    {
     var delStuItemPar:Object=new Object();
     delStuItemPar=tree.selectedItem.parent();
     var delStuInx:int=tree.selectedItem.childIndex();
     tree.dataDescriptor.removeChildAt(delStuItemPar,tree.selectedItem,delStuInx,tree.dataProvider);
    }

   }

   /**
    * 添加影片
    **/
   private function addStuNode():void{
    var node:XML=<item label="新影片" level="2"/>;
    (tree.selectedItem as XML).appendChild(node);
   }

  ]]>
 </fx:Script>
 <fx:Declarations>
  <!-- 将非可视元素(例如服务、值对象)放在此处 -->
 </fx:Declarations>
 <s:Panel x="25" y="23" width="250" height="448" title="喜剧之王">
  <mx:Tree id="tree" left="0" top="0" width="100%" height="100%" labelField="@label" change="treeChanged(event)" dataProvider="{data}" allowMultipleSelection ="true"/>
 </s:Panel>
</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右键

时间: 2024-08-01 09:10:44

[Flex] 组件Tree系列 —— 实现右键拓展功能的相关文章

[flex] 组件Tree系列 —— 将数组作为dataProvider

mxml: <?xml version="1.0" encoding="utf-8"?> <!--功能描述:将数组作为dataProvider--> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://

[Flex] 组件Tree系列 —— 运用openItems获取打开节点

mxml: 1 <?xml version="1.0" encoding="utf-8"?> 2 <!--功能描述:运用openItems获取打开节点--> 3 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 4 xmlns:s="library://ns.adobe.com/flex/spark" 5 xmlns:mx="

[Flex] 组件Tree系列 —— 作为PopUpButton的弹出菜单

mxml: 1 <?xml version="1.0" encoding="utf-8"?> 2 <!--功能描述:Tree作为PopUpButton的弹出菜单--> 3 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 4 xmlns:s="library://ns.adobe.com/flex/spark" 5 xmlns:mx=&

[Flex] 组件Tree系列 —— 支持CheckBox组件

主程序mxml: 1 <?xml version="1.0" encoding="utf-8"?> 2 3 <!--功能描述:支持CheckBox--> 4 5 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 6 xmlns:s="library://ns.adobe.com/flex/spark" 7 xmlns:mx="

[Flex] 组件Tree系列 —— 阻止用户点击选中Tree中任何节点

mxml: 1 <?xml version="1.0" encoding="utf-8"?> 2 <!--功能描述:阻止用户点击选中Tree中任何节点--> 3 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 4 xmlns:s="library://ns.adobe.com/flex/spark" 5 xmlns:mx="

[Flex] 组件Tree系列 —— 支持元素的拖放排序

mxml: 1 <?xml version="1.0" encoding="utf-8"?> 2 3 <!--功能描述:支持元素拖放排序--> 4 5 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 6 xmlns:s="library://ns.adobe.com/flex/spark" 7 xmlns:mx="libra

[Flex] 组件Tree系列 —— 运用variableRowHeight和wordWrap设置可变行高

mxml: 1 <?xml version="1.0" encoding="utf-8"?> 2 <!--功能描述:运用variableRowHeight和wordWrap设置可变行高--> 3 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 4 xmlns:s="library://ns.adobe.com/flex/spark"

[Flex] 组件Tree系列 —— 运用LabelFunction hasChildren getChildren设置Tree包含节点个数

mxml: 1 <?xml version="1.0" encoding="utf-8"?> 2 3 <!--功能描述:运用LabelFunction hasChildren getChildren设置Tree包含节点个数--> 4 5 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 6 xmlns:s="library://ns.adobe.

[Flex] 组件Tree系列 —— 打开和关闭节点

mxm: 1 <?xml version="1.0" encoding="utf-8"?> 2 <!--功能描述:打开和关闭节点--> 3 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 4 xmlns:s="library://ns.adobe.com/flex/spark" 5 xmlns:mx="library://n