生成上面树的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