Flash AS3 XML Tree组件

来源:互联网 发布:windows cmd ls 编辑:程序博客网 时间:2024/06/05 09:45

 

 

 

生成上面树的XML:

<root>
  <leafs mark="普通用户d">
    <ID>20120804071540</ID>
    <parentID/>
    <name>普通用户d</name>
    <leaf mark="用户组1">
      <ID>20120804071541</ID>
      <parentID>20120804071540</parentID>
      <name>用户组1</name>
    </leaf>
    <leaf mark="用户组2">
      <ID>20120804071542</ID>
      <parentID>20120804071540</parentID>
      <name>用户组2</name>
    </leaf>
  </leafs>
  <leaf mark="管理员">
    <ID>20120804072044</ID>
    <parentID/>
    <name>管理员</name>
  </leaf>
</root>

 

树节点组件代码:


package com.control
{
 import flash.display.MovieClip;
 import flash.display.Graphics;
 import flash.text.TextField;
 import flash.events.*;
 import flash.geom.Matrix;

 public class xmlTreeNode extends MovieClip
 {
  private var g:Graphics;
  private var gaps:Number=20;

  private var childNodes:Array=[];
  private var nodeCount:int=0;  
  private var txt:TextField=new TextField;
  
  //标记
  private var _mark:MovieClip=new MovieClip;
  public function get mark():MovieClip
  {
   return _mark;
  }
  
  //标签
  private var _nodeBody:MovieClip=new MovieClip;
  public function get body():MovieClip
  {
   return _nodeBody;
  }
  
  //数据
  private var _nodeData:XML=null;
  public function get nodeData():XML
  {
   return _nodeData;
  }
  public function set nodeData(v:XML):void
  {
   _nodeData=v;
   drawChart(_nodeData);
  }
    
  //多选
  private var _multipleSelect:Boolean=false;
  public function set multipleSelect(v:Boolean):void
  {
   _multipleSelect=v;
  }
  
  //是否展开
  private var _spread:Boolean=false;
  public function get spread():Boolean
  {
   return _spread;
  }
  public function set spread(v:Boolean):void
  {
   _spread=v;
   refreshMark();
  }
  
  //是否是复杂节点
  private var _hasChildren:Boolean=false;
  public function get hasChildren():Boolean
  {
   return _hasChildren;
  }
  public function set hasChildren(v:Boolean):void
  {
   _hasChildren=v;
   refreshMark();
  }
  
  //自己的ID
  private var _ID:int=0;
  public function get ID():int
  {
   return _ID;
  }
  public function set ID(v:int):void
  {
   _ID=v;
  }
  
  //父节点ID
  private var _parentId:int=-1;
  public function get parentId():int
  {
   return _parentId;
  }
  public function set parentId(v:int):void
  {
   _parentId=v;
  }
  
  //父节点
  private var _parentMc:MovieClip=null;
  public function get parentMc():MovieClip
  {
   return _parentMc;
  }
  public function set parentMc(v:MovieClip):void
  {
   _parentMc=v;
  }
  
  //是否选中
  private var _selected:Boolean=false;
  public function get selected():Boolean
  {
   return _selected;
  }
  public function set selected(v:Boolean):void
  {
   _selected=v;
   if(_selected)
   {
    txt.htmlText=""+txt.text+"";
   }
   else
   {
    txt.htmlText=""+txt.text+"";
   }
  }
  
  //构造函数
  public function xmlTreeNode(node:XML=null):void
  {
   addChild(_mark);
   addChild(_nodeBody);
   txt.;
   _nodeBody.addChild(txt);
   drawChart(node);
     
  
  //是否存在同名节点
  public function hasChildNode(nodeName:String):Boolean
  {
   //检查是否存在同名的叶子
   var len:int=_nodeData.leaf.length();
   for(var i:int=0;i
   {
    if(_nodeData.leaf[i].@mark==nodeName)
    {
     return true;
    }
   }
   
   //检查是否存在同名的枝干
   len=_nodeData.leafs.length();
   for(i=0;i
   {
    if(_nodeData.leafs[i].@mark==nodeName)
    {
     return true;
    }
   }
   return false;   
  }
  
  //画节点
  private function drawChart(node:XML=null):void
  {
   _nodeData=node;
   
   if(_nodeData==null) return;
   
   _hasChildren=(_nodeData.hasOwnProperty("leaf") || _nodeData.hasOwnProperty("leafs"));
   
   //展开标记
   refreshMark();

   _mark.y=4;   
   _mark.buttonMode=true;
   _mark.mouseChildren=false;
   
   //可以多选
   if (_multipleSelect)
   {

   }
   
   //标签   
   if(_selected)
   {
    txt.htmlText=""+node.@mark.toString()+">";
   }
   else
   {
    txt.htmlText=""+node.@mark.toString()+">";
   }
   g=_nodeBody.graphics;
   g.beginFill(0xFF0000,0);
   g.drawRoundRect(0,0,txt.width,20,10,10);
   g.endFill();


   _nodeBody.x=12;
   _nodeBody.buttonMode=true;
   _nodeBody.mouseChildren=false;     
  }
 
  //刷新前面的标记
  private function refreshMark():void
  {
   g=_mark.graphics;
   g.clear();
  
   if(_hasChildren)
   {  
    g.lineStyle(0,0xCCCCCC);
    g.beginFill(0xFFFFFF);
    g.drawRect(0,0,10,10);
    g.endFill();

    g.lineStyle(0,0x666666);
    g.moveTo(2,5);
    g.lineTo(9,5);

    if (!_spread)
    {
     g.moveTo(5,2);
     g.lineTo(5,9);
    }
   }
  }
  
  //代码结束
 }
}

 

XML树代码:


package com.control
{
 import flash.display.MovieClip;
 import flash.display.Graphics;
 import flash.text.TextField;
 import flash.events.*;
 import flash.geom.Matrix;

 public class xmlTree extends MovieClip
 {
  private var g:Graphics;
  private var gaps:Number=20;

  private var childNodes:Array=[];
  private var nodeCount:int=0;

  //数据
  private var _treeData:XML=null;
  public function get treeData():XML
  {
   return _treeData;
  }
  
  //节点容器
  private var _body:MovieClip=new MovieClip;

  //根节点
  private var _rootNode:MovieClip=new MovieClip;
  public function get rootNode():MovieClip
  {
   return _rootNode;
   

  //选定的节点
  private var _selectedNode:MovieClip=null;
  public function get selectedNode():MovieClip
  {
   return _selectedNode;
  }
  
  //鼠标按下的节点
  private var _pressNode:MovieClip=null;
  public function get pressNode():MovieClip
  {
   return _pressNode;
  }
  
  //多选
  private var _multipleSelect:Boolean=false;
  public function get multipleSelect():Boolean
  {
   return _multipleSelect;
  }
  
  //构造函数
  public function xmlTree():void
  {

  }
  
  //根据指定XML画基础树
  public function drawChart(node:XML,mSelect:Boolean=false):void
    
   _multipleSelect=mSelect;

   var len:int=_body.numChildren;
   for (var i:int=0; i
   {
    _body.removeChildAt(0);
   }
   _body=new MovieClip;

   childNodes=[];   
   var rootNode:XML=用户组;
   rootNode.a(node.children());
   
   _treeData=rootNode;
   _rootNode=new xmlTreeNode(_treeData);
   _rootNode.ID=0;
   _rootNode.spread=true;
   _rootNode.selected=true;
   _rootNode.mark.addEventListener(MouseEvent.CLICK,spreadNode);
   _rootNode.body.addEventListener(MouseEvent.CLICK,selecteNode);
   childNodes[0]=_rootNode;   

   _body.addChild(_rootNode);
   
   _selectedNode=_rootNode;
   getChild(_rootNode);
   
   //重新画线
   g=_body.graphics;
   g.clear();
   drawLine(_rootNode);

   addChild(_body);
  }
  
  //显示当前节点
  private function getChild(parentNode:MovieClip):void
    
   var childNode:MovieClip=new MovieClip;   
   var treeNode:XML=parentNode.nodeData;
   var len:int=treeNode.children().length();   
   
   //加入子节点
   for (var i:int=0; i
   {
    var node:XML=treeNode.children()[i];
    if(node.localName()=="leaf" || node.localName()=="leafs")
    {
     insertNodeInto(node,parentNode);                               
    }
   }
  }
  
  //添加新的节点
  public function addNode(node:XML):MovieClip
  {
   var newNode:MovieClip=new xmlTreeNode(node);
   var parentMc:MovieClip=(_selectedNode==null)?_rootNode:_selectedNode;
   var parentNode:XML=parentMc.nodeData;
   parentNode.a(node);   
   insertNodeInto(node,parentMc);
   
   //设置父节点为可展开
   parentMc.hasChildren=true;
   parentMc.spread=true;
   parentMc.mark.addEventListener(MouseEvent.CLICK,spreadNode);
   
   //重新画线
   g=_body.graphics;
   g.clear();
   drawLine(_rootNode);
   
   return newNode;
  }
  
  //删除选定的节点
  public function removeNode():void
    
   if(_selectedNode==null) return;
   
   //删除其所有子节点
   deleteChildNodes(_selectedNode);
   
   //删除数据中的节点信息
   delete(_selectedNode.nodeData.parent().children()[_selectedNode.nodeData.childIndex()]);
   
   //删除当前节点
   var nodeItem:MovieClip;
   var index:int=0;
   while (index
   {
    nodeItem=childNodes[index] as MovieClip;
    if (nodeItem==_selectedNode)
    {
     //后面节点位置排列
     var len:int=childNodes.length;
     var i:int=index;
     while (i
     {
      var otherItem:MovieClip=childNodes[i] as MovieClip;
      otherItem.y-=20;
      i++;
     }
     _body.removeChild(_selectedNode);

     //删除新节点
     childNodes.splice(index,1);
     
     _selectedNode=null;
     
     break;
    }
    else
    {
     index++;
    }
   }
   
   //重新画线
   g=_body.graphics;
   g.clear();
   drawLine(_rootNode);
  }
  
  //更新组的信息
  public function updateNode(node:XML):void
  {
   if(_selectedNode==null) return;
   _selectedNode.nodeData=node;
  }
  
  //插入子节点
  public function insertNodeInto(node:XML,parentMc:MovieClip=null):MovieClip
  {
   var nodeItem:MovieClip;
   var len:int=childNodes.length;
   var index:int=0;
   
   if(parentMc==null) parentMc=_rootNode;
   
   var newNode:MovieClip=new xmlTreeNode(node);
   newNode.parentId=parentMc.ID;      
   newNode.parentMc=parentMc;
   
   _body.addChild(newNode);
   
   //如果可以展开,则加入展开的事件响应
   if(newNode.hasChildren)
   {
    newNode.mark.addEventListener(MouseEvent.CLICK,spreadNode);
   }
    
   //加入标签点击的选择响应
   newNode.body.addEventListener(MouseEvent.CLICK,selecteNode);    
   
   nodeCount++;
   newNode.ID=nodeCount;
      
   //查找插入位置
   for (index=len-1; index>=0; index--)
   {
    nodeItem=childNodes[index] as MovieClip;
    
    //找到了最后一个子节点
    if (nodeItem.parentId==parentMc.ID)
        
     newNode.x=nodeItem.x;
     newNode.y=nodeItem.y+20;
     break;
    }
    
    //父节点不存在子节点
    if (nodeItem.ID==parentMc.ID)
    {
     newNode.x=nodeItem.x+gaps;
     newNode.y=nodeItem.y+20;
     break;
    }
   }
   
   //加入新节点
   childNodes.splice(index+1,0,newNode);      
   
   //后面节点位置排列
   len=childNodes.length;
   var i:int=index+2;
   while (i
   {
    nodeItem=childNodes[i] as MovieClip;    
    nodeItem.y+=20;
    i++;
   }
   
   return newNode;
  }
  
  //选定标签
  private function selecteNode(e:Event):void
  {
   var mc:MovieClip=e.target as MovieClip;
   var currentNode:MovieClip=mc.parent as MovieClip;

   if (_selectedNode!=currentNode)
   {
    _selectedNode=currentNode;

    if (!_multipleSelect)
    {
     clearAllSelected();
    }
    
    _selectedNode.selected=true;
    this.dispatchEvent(new Event("onChanged"));
   }
   
   this.dispatchEvent(new Event("onSelected"));
  }
  
  //清除选择
  public function clearAllSelected():void
  {
   var len:int=childNodes.length;
   for (var i:int=0; i
   {
    var nodeItem:MovieClip=childNodes[i] as MovieClip;    
    nodeItem.selected=false;
   }
  }
  
  //展开子节点
  private function spreadNode(e:Event):void
  {
   var mc:MovieClip=e.target as MovieClip;
   var currentNode:MovieClip=mc.parent as MovieClip;

   mc=currentNode.getChildByName("mark") as MovieClip;

   currentNode.spread=!currentNode.spread;   

   //如果是展开
   if (currentNode.spread)
   {
    getChild(currentNode);
    
    //发送事件   
    this.dispatchEvent(new Event("spreadNode"));
   }
   else
   {
    deleteChildNodes(currentNode);
   }
   
   //重新画线
   g=_body.graphics;
   g.clear();
   drawLine(_rootNode);
  }
  
  //删除指定节点的子节点
  public function deleteChildNodes(mc:MovieClip):void
  {
   var nodeItem:MovieClip;
   var index:int=0;

   //查找删除位置
   while (index
   {
    nodeItem=childNodes[index] as MovieClip;
    if (nodeItem.parentId==mc.ID)
    {
     deleteChildNodes(nodeItem);

     //后面节点位置排列
     var len:int=childNodes.length;
     var i:int=index;
     while (i
     {
      var otherItem:MovieClip=childNodes[i] as MovieClip;
      otherItem.y-=20;
      i++;
     }
     _body.removeChild(nodeItem);

     //删除新节点
     childNodes.splice(index,1);
    }
    else
    {
     index++;
    }
     
  }
    
  //画连线(递归)
  private function drawLine(node:MovieClip):void
  {
   var g:Graphics=_body.graphics;
   g.lineStyle(0,0xE1E1E1);

   var index:int=0;
   var y0:Number=node.y+10;
   var x0:Number=node.x+5;
   while (index
   {
    var nodeItem:MovieClip=childNodes[index] as MovieClip;
    if (nodeItem.parentId==node.ID)
    {
     drawLine(nodeItem);
     
     g.moveTo(x0,y0);
     g.lineTo(x0,nodeItem.y+10);
     g.lineTo(nodeItem.x+5,nodeItem.y+10);     
    }
    index++;
   }
  }
  
  //代码结束
 }
}

 

 

 

文章转自http://blog.sina.com.cn/s/blog_53cb817c01015lr6.html

 

原创粉丝点击