as3 生态树

直接上代码:

 

package cn.ndl.ui {
    import flash.display.GradientType;
    import flash.display.Shape;
    import flash.display.SpreadMethod;
    import flash.display.Sprite;
    import flash.geom.Matrix;
    import flash.text.TextField;

    public class EcoRect extends Sprite {

        private var ttf:TextField;

        private var text:String;

        public function EcoRect(text:String="") {
            super();
            this.text=text;
            this.init();
        }

        private function init():void {
            this.addChild(this.getBgRect());

            this.ttf=new TextField();
            this.ttf.width=80;
            this.ttf.height=20;
            this.ttf.mouseEnabled=false;

            this.addChild(this.ttf);
        }

        public function setText(v:String):void {
            this.ttf.text=v;
        }

        public function getText():String {
            return this.ttf.text;
        }

        private function getBgRect():Shape {

            var matr:Matrix=new Matrix();
            matr.createGradientBox(80, 20, 0, 0, 0);

            var sp:Shape=new Shape();
            sp.graphics.beginGradientFill(GradientType.LINEAR, [0xaab00d, 0xffffff], [1, 1], [0, 255], matr);
            sp.graphics.lineStyle(1, 0x7a7e16);
            sp.graphics.drawRoundRect(0, 0, 80, 20, 10, 10);
            sp.graphics.endFill();

            return sp;
        }

        public function clone():EcoRect {
            var r:EcoRect=new EcoRect();
            r.setText(this.getText());
            r.x=this.x;
            r.y=this.y;
            
            return r;
        }

    }
}

 

package cn.ndl.ui {
    import flash.display.DisplayObject;
    import flash.display.SpreadMethod;
    import flash.display.Sprite;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.geom.Point;

    public class EcoNode extends Sprite {

        private static var shiftkey:Boolean=false;

        private var rec:EcoRect;

        public var childSpr:Sprite;

        private var _treeItem:EcoTreeItem;

        public var id:int=0;
        public var type:uint=0x00ff00;

        private var oldP:Point;
        private var newP:Point;

        private var move:Boolean=false;
        private var cpdata:EcoNode;

        public function EcoNode() {
            super();
            this.init();
        }

        private function init():void {

            rec=new EcoRect();
            this.addChild(this.rec);

            this.childSpr=new Sprite();
            this.addChild(this.childSpr);

            this.childSpr.x=this.rec.x + this.rec.width + 10;
            this.childSpr.y=0;

            this.rec.addEventListener(MouseEvent.CLICK, onClick);
            this.rec.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            this.rec.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);

            this.rec.buttonMode=true;

        }

        private function onMouseMove(e:MouseEvent):void {
            move=true;
            e.stopImmediatePropagation();
        }

        private function onMouseDown(e:MouseEvent):void {
            move=false;

            shiftkey=e.shiftKey;

            DrageManager.getInstance().startDrag(this);
            e.stopImmediatePropagation();
        }

        private function onMouseUp(e:MouseEvent):void {
            if (!move)
                return;

            if (e.target is EcoRect) {

                var data:EcoNode=DrageManager.getInstance().data as EcoNode;

                var item:EcoTreeItem;
                if (this.childSpr.numChildren == 0) {
                    item=new EcoTreeItem(this);
                } else {
                    item=EcoNode(this.childSpr.getChildAt(this.childSpr.numChildren - 1)).treeItem;
                }

                item.addItem(data.getMainRect().getText(), data.type);

                //副本
                cpdata=item.getItem(item.getItems().length - 1);

                //递归添加
                forAdd(data, EcoNode(this.childSpr.getChildAt(this.childSpr.numChildren - 1)));

//                trace(data.getMainRect().getText(), "success");

                //是否按下shift
                if (!shiftkey) {
                    data.parent.removeChild(data);
                    data.treeItem.updatePs();
                }

                shiftkey=false;

            }

            move=false;

        }


        private function forAdd(e:EcoNode, target:EcoNode):void {
//            trace("--------------------------");
            if (e == cpdata)
                return;

            if (e.childSpr.numChildren > 0) {

                var item:EcoTreeItem=new EcoTreeItem(target);
                var node:EcoNode;
                var i:int=0;

//                trace("1111111111111");
                for (; i < e.childSpr.numChildren; i++) {

                    if (i == 0) {
                        item=new EcoTreeItem(target);
                    } else {
                        item=EcoNode(target.childSpr.getChildAt(target.childSpr.numChildren - 1)).treeItem;
                    }

                    node=e.childSpr.getChildAt(i) as EcoNode;
                    item.addItem(node.getMainRect().getText(), node.type);

                    //trace(node.getMainRect().getText(), "===");

                    forAdd(node, item.getItem(item.getItems().length - 1));
                }
            }

        }

        private function onClick(e:MouseEvent):void {

            if (this.childSpr.numChildren > 0) {

                if (this.childSpr.parent != null) {
                    this.removeChild(this.childSpr);
                } else {
                    this.addChild(this.childSpr);
                }

                this.updateRectPosition();

                if (EcoNode(this.childSpr.getChildAt(0))._treeItem != null)
                    EcoNode(this.childSpr.getChildAt(0))._treeItem.updatePs();

            }

        }

        public function getHeight():Number {
            if (this.childSpr.parent == null)
                return this.rec.height;

            return this.height;
        }

        public function set treeItem(v:EcoTreeItem):void {
            this._treeItem=v;
        }

        public function get treeItem():EcoTreeItem {
            return this._treeItem;
        }

        public function setText(v:String):void {
            this.rec.setText(v);
        }

        public function getMainRect():EcoRect {
            return this.rec;
        }

        public function mainRectPos(p:Number):void {
            this.rec.y=p;
            this.updateRectPosition();
        }

        public function updateRectPosition():void {

            var sp:Number=this.rec.height / 2;

            var sx:Number=this.rec.x + this.rec.width;
            var sy:Number=this.rec.y + sp;

            var dio:EcoRect;
            var node:EcoNode;
            var tP:Point;

            this.graphics.clear();

            if (this.childSpr.stage != null) {
                for (var i:int=0; i < this.childSpr.numChildren; i++) {

                    node=EcoNode(this.childSpr.getChildAt(i));
                    dio=node.getMainRect();
                    tP=this.globalToLocal(this.childSpr.getChildAt(i).localToGlobal(new Point(dio.x, dio.y + sp)));

                    this.graphics.lineStyle(0, EcoEnum["ECOLINE_TYPE" + node.type]);

                    this.graphics.moveTo(sx, sy);
                    this.graphics.cubicCurveTo(sx + 20, sy, tP.x - 30, tP.y, tP.x, tP.y);

                }
            }

        }



        public function clone():EcoNode {

            var node:EcoNode=new EcoNode();
            node.rec=this.rec;
            node._treeItem=this._treeItem;
            node.childSpr=this.childSpr;
            node.id=this.id;

            return node;
        }

    }
}

 

package cn.ndl.ui {

    import flash.display.Sprite;



    public class EcoTreeItem extends Sprite {

        private var space:Number=30;
        private var items:Vector.<EcoNode>;

        private var parentItem:EcoNode;

        private var id:int=0;

        public function EcoTreeItem(parent:EcoNode) {
            super();
            this.init();
            this.parentItem=parent;
        }

        private function init():void {
            this.items=new Vector.<EcoNode>();
        }

        /**
         * 
         * @param str
         * @param type 颜色
         * @return 
         * 
         */        
        public function addItem(str:String, type:int=0):EcoNode {

            if (str == null)
                return null;

            var item:EcoNode=new EcoNode();
            this.parentItem.childSpr.addChild(item);

            item.setText(str);
            item.treeItem=this;
            item.type=type;

            item.x=space;
            item.y=this.items.length * (item.height + 10);
            item.id=this.items.length;

            this.items.push(item);

            updatePs();

            return item;
        }

        /**
         *  
         * @param str
         * @param i index
         * 
         */        
        public function addItemAt(str:String, i:int=-1):void {

            if (str == null)
                return;

            var item:EcoNode=new EcoNode();
            this.parentItem.childSpr.addChild(item);

            item.setText(str);
            item.treeItem=this;

            item.x=space;
            item.y=this.items.length * (item.height + 10);
            item.id=i + 1;

            this.items.splice(i, 0, item);

            updatePs();
        }

        /**
         * 更新位置 
         * 
         */        
        public function updatePs():void {

            this.parentItem.mainRectPos((this.parentItem.getHeight() - this.parentItem.getMainRect().height) / 2);

            if (this.parentItem.treeItem == null)
                return;

            var hh:Number=0;

            var rec:EcoNode;
            var pit:Vector.<EcoNode>=this.parentItem.treeItem.getItems();

            for each (rec in pit) {
                rec.y=hh;
                rec.updateRectPosition();
                hh+=rec.getHeight() + 15;
            }

            this.parentItem.treeItem.updatePs();
        }

        public function getItem(i:int):EcoNode {
            return this.items[i];
        }

        public function getItems():Vector.<EcoNode> {
            return this.items;
        }


    }
}

 

package cn.ndl.ui {

    import flash.display.Sprite;
    import flash.events.Event;
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.utils.Dictionary;




    public class EcoTree extends Sprite {


        public var items:Dictionary;
        public var nodes:Dictionary;

        private var tree:EcoTreeItem;

        private var node:EcoNode;

        private var txtXML:String;
        private var forindex:int=0;

        public function EcoTree() {
            super();
            this.init();
        }

        private function init():void {
            node=new EcoNode();
            this.addChild(node);

            this.items=new Dictionary();
            this.nodes=new Dictionary();

            this.addEventListener(Event.ADDED_TO_STAGE, onAddstage);
        }

        private function onAddstage(e:Event):void {

            DrageManager.getInstance().setup(this.stage);
        }

        public function setText(v:String):void {
            node.setText(v);
        }

        public function getEcoRect():EcoNode {
            return this.node;
        }

        public function add(id:int, pid:int, str:String):void {

            var _node:EcoNode;

            if (pid == -1) {
                _node=this.node;
            } else {
                _node=this.nodes[pid];
            }

            var item:EcoTreeItem;

            if (pid == -1) {
                item=new EcoTreeItem(_node);
                this.items[id]=item;
            } else if ((this.items[id] == null && this.items[pid] == null)) {
                item=new EcoTreeItem(_node);
                this.items[id]=item;
            } else if (this.items[pid] != null) {
                item=this.items[pid];
            }

            if (pid == -1)
                this.nodes[pid]=item.addItem(str);
            else
                this.nodes[id]=item.addItem(str);
        }

        /**
         * 导出xml
         */
        public function exportXML(path:String):void {

            txtXML="<Root>";
            txtXML+="<Node id='" + forindex + "' name='" + this.node.getMainRect().getText() + "' type='2' owner='0' fun='0' parameters='' des='描述信息'>";

            forAdd(this.node);

            txtXML+="</Node>";
            txtXML+="</Root>";

            var xml:XML=XML(txtXML);

            trace(xml.toString())

            var fs:FileStream=new FileStream();
            fs.openAsync(new File(path), FileMode.WRITE);

            fs.writeUTFBytes("<?xml version='1.0'?>\n" + xml.toString());
            fs.close();
        }

        private function forAdd(n:EcoNode):void {

            if (n.childSpr.numChildren > 0) {

                var nd:EcoNode;
                for (var i:int=0; i < n.childSpr.numChildren; i++) {
                    nd=EcoNode(n.childSpr.getChildAt(i));
                    txtXML+="<Node id='" + forindex + "' name='" + nd.getMainRect().getText() + "' type='" + nd.type + "' owner='0' fun='0' parameters='' des='描述信息'>";
                    forindex++;
                    forAdd(nd);

                    txtXML+="</Node>";
                }
            }
        }

        public function importXML(filepath:String):void {
            var urlLoader:URLLoader=new URLLoader(new URLRequest(filepath));
            urlLoader.addEventListener(Event.COMPLETE, onComplete);
        }

        private function onComplete(e:Event):void {
            var xml:XML=XML(e.target.data);

//            trace(xml,xml.Node, "----");
            while (this.node.childSpr.numChildren)
                this.node.childSpr.removeChildAt(0);

            xml=XML(xml.Node);
            this.node.setText(xml.@name);

            parseXML(xml.Node as XMLList, this.node);

        }

        private function parseXML(xmllist:XMLList, target:EcoNode):void {

            var item:EcoTreeItem=new EcoTreeItem(target);
            var xml:XML;
            for each (xml in xmllist) {
                item.addItem(xml.@name, xml.@type);
                parseXML(xml.Node as XMLList, item.getItem(item.getItems().length - 1));
            }

        }



    }
}

 

package cn.ndl.ui {
    import flash.display.DisplayObject;
    import flash.display.DisplayObjectContainer;
    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.utils.ByteArray;

    public class DrageManager {

        private static var _instance:DrageManager;

        public var data:*;
        private var _data:Sprite;

        private var _stg:Stage;

        public function DrageManager() {

        }

        public static function getInstance():DrageManager {
            if (_instance == null)
                _instance=new DrageManager();

            return _instance;
        }

        public function setup(stg:Stage):void {
            _stg=stg;
            _data=new Sprite();
            _data.mouseChildren=false;
            _data.mouseEnabled=false;

            _stg.addChild(_data);
            _stg.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        }

        public function startDrag(d:*):void {

            var p:Point=_stg.globalToLocal(d.parent.localToGlobal(new Point(d.x, d.y)));
            data=null;

            data=d;
            _data.addChild(data.clone().getMainRect().clone());

            _data.x=p.x;
            _data.y=p.y;

            _data.startDrag();
        }

        private function onMouseUp(e:MouseEvent):void {
            
            _data.stopDrag();
            if (_data.numChildren > 0)
                _data.removeChildAt(0);
            
            data=null;
        }

        private function copyObj(d:*):* {
            var by:ByteArray=new ByteArray();
            by.writeObject(d);

            by.position=0;

            return by.readObject();
        }

    }
}

 

package cn.ndl.ui {

    public class EcoEnum {

        public static const ECOLINE_TYPE1:uint=0xffff00;
        public static const ECOLINE_TYPE2:uint=0xff0000;
        public static const ECOLINE_TYPE3:uint=0x000000;
        public static const ECOLINE_TYPE4:uint=0x00ff00;
        public static const ECOLINE_TYPE5:uint=0x00ffff;
        public static const ECOLINE_TYPE6:uint=0x0000ff;
        public static const ECOLINE_TYPE7:uint=0xffff00;
        public static const ECOLINE_TYPE8:uint=0x0f0f0f;
        public static const ECOLINE_TYPE9:uint=0xf0f0f0;
        public static const ECOLINE_TYPE10:uint=0xf0f000;

        public function EcoEnum() {
        }
        
        
    }
}

 


测试代码:

 

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       xmlns:mx="library://ns.adobe.com/flex/mx"
                       creationComplete="windowedapplication1_creationCompleteHandler(event)">

    <fx:Script>
        <![CDATA[
            import cn.ndl.ui.EcoTree;
            
            import mx.core.UIComponent;
            import mx.events.FlexEvent;

            private var tree:cn.ndl.ui.EcoTree

            protected function button1_clickHandler(event:MouseEvent):void {
                // TODO Auto-generated method stub

                var f:File=new File();
                f.addEventListener(Event.SELECT, onSaveSelect);
                f.browseForSave("select a file");
            }

            private function onSaveSelect(e:Event):void {
                var f:File=File(e.target);
//                trace(f.nativePath);
                var path:String=f.nativePath.replace(/\\+/g, "/");
//                trace(path);
                tree.exportXML(path+".xml");
            }

            protected function button2_clickHandler(event:MouseEvent):void {
                // TODO Auto-generated method stub
                var f:File=new File();
                f.addEventListener(Event.SELECT, onOpenSelect);
                f.browseForOpen("select a file",[new FileFilter("xml","*.xml")]);

            }

            private function onOpenSelect(e:Event):void {
                var f:File=File(e.target);
//                trace(f.nativePath);
                var path:String=f.nativePath.replace(/\\+/g, "/");
//                trace(path);
                tree.importXML(path);
            }

            protected function windowedapplication1_creationCompleteHandler(event:FlexEvent):void {
                // TODO Auto-generated method stub
                tree=new cn.ndl.ui.EcoTree();
                tree.y=50;
                var ui:UIComponent=new UIComponent();
                ui.addChild(tree);
                this.addElement(ui);
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <!-- 将非可视元素(例如服务、值对象)放在此处 -->
    </fx:Declarations>
    <s:Button x="220"
              y="10"
              label="导出"
              click="button1_clickHandler(event)"/>
    <s:Button x="320"
              y="10"
              label="导入"
              click="button2_clickHandler(event)"/>
</s:WindowedApplication>

 


运行结果:

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2013-08-27 10:25  ndljava  阅读(561)  评论(0编辑  收藏  举报