1

I have flex mxml custom component(Graphic).According to requirement a need to copy them as copy or cut operation.but problem in the registerClassAlias() method,how it will work for custom graphic or Group(or UIComponents) components.

var className:String = getQualifiedClassName(zorder.getItemAt(0));
            _saveIn.clear();

            registerClassAlias(className, zorder.getItemAt(0) as Class);
            _saveIn   =     SharedObject.getLocal("save");
            _saveIn.data.value1 = new ByteArray();
            _saveIn.data.value1.writeObject(zorder.getItemAt(0));
            _saveIn.data.value1.position = 0;
            _saveIn.flush();
ketan
  • 19,129
  • 42
  • 60
  • 98
Devendra
  • 1,864
  • 6
  • 29
  • 49
  • MXML components are classes just like Actionscript classes. Shouldn't that then work the same? Have you tried it? Maybe you could show some code to further explain what you're trying to do. – Sunil D. Jan 29 '13 at 08:15
  • @SunilD. just check this code... – Devendra Jan 29 '13 at 08:17
  • On the surface that seems ok. Can you describe what happens when you try to encode/decode the object? What is the length of the byte array after calling write object? What is in the shared object when you try to decode it, null an empty byte array, etc? – Sunil D. Jan 29 '13 at 08:32
  • when i call this code,In registerClassAlias() method give execption. TypeError: Error #2007: Parameter classObject must be non-null. – Devendra Jan 29 '13 at 08:34
  • Ok, the problem is you are trying to cast a DisplayObject (whatever is returned by `zorder.getItemAt(0)` to a Class ... when that cast fails the `as` operator returns `null`. At the moment, the proper way to get the class name for an object is escaping me... I'll look it up and respond, or one of the geniuses here will explain :) – Sunil D. Jan 29 '13 at 08:38

2 Answers2

2

It's not possible to make a full copy of any display object via ByteArray with registerClassAlias->writeObject->readObject approach. It works only with simple objects, for example data objects (like TextFormat, value objects and so). In any case you have to test the copy method for each type of your object to be sure it works properly.

Example of coping Shape, the simplest display object:

package
{
import avmplus.getQualifiedClassName;

import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.Shape;
import flash.net.registerClassAlias;
import flash.utils.ByteArray;
import flash.utils.getDefinitionByName;


public class astest extends MovieClip
{
    public function astest()
    {
        init();
    }

    private function init():void
    {
        var sh:Shape = new Shape();

        sh.graphics.beginFill(0xFF0000);
        sh.graphics.drawEllipse(100, 100, 100, 70);
        sh.graphics.endFill();

        addChild(sh);

        registerObject(sh);

        var ba:ByteArray = new ByteArray();
        ba.writeObject(sh);
        ba.position = 0;
        var obj:Object = ba.readObject();
        var shCopy:DisplayObject = obj as DisplayObject;

        if(shCopy)
        {
            shCopy.x = shCopy.y = 100;
            addChild(shCopy);
        }

    }

    private function registerObject(obj:Object):void
    {
        try
        {
            var qname:String = getQualifiedClassName(obj);
            var cname:String = qname.split("::").join(".");
            var classs:Class = getDefinitionByName(cname) as Class;
            registerClassAlias(qname, classs);
        }catch(error:Error)
        {
            trace(error.message);
        }
    }
}
}

Output:

   TypeError: Error #1034: Type Coercion failed: cannot convert Object@eae09b9 to flash.geom.Transform.

So, you can try to register the flash.geom.Transform before coping:

registerObject(sh.transform);

but this lead to another error:

ArgumentError: Error #1063: Argument count mismatch on flash.geom::Transform(). Expected 1, got 0

Actually, DisplayObject coping is the old topic and you can google for lots of posts about this by errors I mentioned above (especially the last one), but the answer is: You can't copy display objects in via ByteArray, you need to write custom methods for creating a copy of given TextField, Sprite or VBox and copy all the properties manually.

fsbmain
  • 5,267
  • 2
  • 16
  • 23
0

Ok, this blog post has a simple solution... you use getDefinitionByName():

So something like this in your code:

var className:String = getQualifiedClassName(zorder.getItemAt(0));
            _saveIn.clear();

            registerClassAlias(className, getDefinitionByName(className) as Class);
            _saveIn   =     SharedObject.getLocal("save");
            _saveIn.data.value1 = new ByteArray();
            _saveIn.data.value1.writeObject(zorder.getItemAt(0));
            _saveIn.data.value1.position = 0;
            _saveIn.flush();
Sunil D.
  • 17,983
  • 6
  • 53
  • 65
  • it makes compiler error..Multiple markers at this line: -1118: Implicit coercion of a value with static type Object to a possibly unrelated type Class. -1 changed line, 1 added – Devendra Jan 29 '13 at 09:10
  • Sorry, getDefinitionByName() returns an Object, you have to cast that to a Class (like in the blog post I linked to). But, alas, fsbmain says this won't work for DiaplayObject's anyway. – Sunil D. Jan 29 '13 at 09:31