views:

2139

answers:

6

Hey I am trying to duplicate a flex component at run time.

For example if i have this

mx:Button label="btn" id="btn" click="handleClick(event)"/>

i should be able to call a function called DuplicateComponent() and it should return me a UI component thts exactly same as above button including the event listeners with it.

Can some one help me please?? Thanks in advance

A: 

You can't take a deep copy of UIComponents natively. You're best bet would be to create a new one and analyse the one you have to add a duplicate setup. To be honest this does sound like a bit of a code smell. I wonder if there may be a better solution to the problem with a bit of a rethink..

James Hay
Thanx James for the help, but What i am trying to achieve is that i have a canvas that is acting as a layout design which has some editable textareas, Images, Dynamic shapes that is drawn over there, so after completing the designing process I need to preview the whole layout in a seperate popup window . So for that i need to clone or copy that whole layout canvas including its child into a new canvas in the pop window. So how i can achieve that. Is there any way around to do the same. Thanx in advance
Piyush Giri
I get ya. If i was going to create a preview, under the assumption that this preview isn't interactive in any way, a much better way would be to create a BitmapData object containing a drawn image of your component. It will miles more efficient and a much cleaner approach.
James Hay
Thanx james .. this is exactly what i wanted !!!I 've created the object copy through the BitmapData method you've suggested like: var bd:BitmapData = new BitmapData(layout_cnv.width,layout_cnv.height); bd.draw(layout_cnv); var ba:ByteArray; ba = (new PNGEncoder()).encode(bd); //this below method should be called at the initialisation of pop up window. Img_new.load(parentApplication.ba), where Img_new is the image file in pop up window.Thanx once again.
Piyush Giri
A: 

Same question as: http://www.flexforum.org/viewtopic.php?f=4&t=1421

Showing up in a google search for the same thing. So you've cut&pasted the same question a month later. No luck eh?

There is no easy way to do this that I know of. Many of a component's settings are dependent on the container/context/etc... and get instantiated during the creation process, so there's no reason to clone from that perspective.

You can clone key settings in actionscript and use those when creating new elements.

For instance, assuming you only care about properties, you might have an array ["styleName","width","height",...], and you can maybe use the array like this:

var newUI:UIComponent = new UIComponent();
for each(var s:String in propArray) {
   newUI[s] = clonedUI[s];
}

If you want more bites on your question (rather than waiting a month), tell us what you are trying to achieve.

Glenn
yes Glenn dats true that i've posted the same question as the requirement is all of similar to that one.What i am trying to achieve is that i have a canvas that is acting as a layout design which has some editable textareas, Images, Dynamic shapes that is drawn over there, so after completing the designing process I need to preview the whole layout in a seperate popup window .So for that i need to clone or copy that whole layout canvas including its child into a new canvas in the pop window.So how i can achieve that.Is there any way around to do the same.Thanx in advance.
Piyush Giri
You'll basically need to do an advanced form of what I suggested. You'll have to track all the layout element types, positions, and relevant properties/styles, and replicate it all when you put it in the popup. The only other thing I can think of that might be helpful in this case is "describeType" (http://www.scottgmorgan.com/blog/index.php/2007/10/22/say-hello-to-my-little-friend-describetype/). But I think you'll still end up with some form a parsing or property matching.
Glenn
+1  A: 

To solve that problem you should use actionscript and create the buttons dynamically.

Lets say you want the button(s) to go in a VBox called 'someVbox'

for (var i:uint = 0; i< 10; i++){
    var but:Button = new Button();
    but.label = 'some_id_'+i;
    but.id = 'some_id_'+i;
    but.addEventListener(MouseEvent.CLICK, 'handleClick');
    someVbox.addChild(but);
}

I haven't tested it, but that should add 10 buttons to a vbox with a bit of luck.

ae
Thanx the help, but What i am trying to achieve is that i have a canvas that is acting as a layout design which has some editable textareas, Images, Dynamic shapes that is drawn over there, so after completing the designing process I need to preview the whole layout in a seperate popup window . So for that i need to clone or copy that whole layout canvas including its child into a new canvas in the pop window. So how i can achieve that. Is there any way around to do the same. Thanx in advance
Piyush Giri
+4  A: 

Do a Byte Array Copy. This code segment should do it for you:

// ActionScript file
import flash.utils.ByteArray;

private function clone(source:Object):*
{
    var myBA:ByteArray = new ByteArray();
    myBA.writeObject(source);
    myBA.position = 0;
    return(myBA.readObject());
}

One note, I did not write this code myself, I'm pretty sure I got it from a post on the Flex Coder's list.

www.Flextras.com
This will copy the rendered object's pixels. This won't clone Flex objects so they can be duplicated, functionality and all.
Glenn
I've used this on ArrayCollections, run this snippet in debug mode import flash.utils.ByteArray;private function clone(source:Object):* var myBA:ByteArray = new ByteArray(); myBA.writeObject(source); myBA.position = 0; return(myBA.readObject());}public var foo : ArrayCollection = new ArrayCollection([ {name:'Jeffry', id:1}]);public function init():void{ var bar : ArrayCollection = clone(foo); }]]></mx:Script>
www.Flextras.com
A: 

mx.utils.ObjectUtil often comes in handy, however for complex object types, it's typically good practice to implement an interface that requires a .clone() method, similar to how Events are cloned.

For example:

class MyClass implements ICanvasObject
{
    ...

    public function clone():ICanvasObject
    {
         var obj:MyClass = new MyClass(parameters...);
         return obj;
    }
}

This gives your code more clarity and properly encapsulates concerns in the context of how the object is being used / cloned.

A: 

Hi lukesh,

You are right but as per my understanding UI Components are not cloned by mx.utils.ObjectUtil.

from : http://livedocs.adobe.com/flex/201/langref/mx/utils/ObjectUtil.html#copy()

copy () method

public static function copy(value:Object):Object Copies the specified Object and returns a reference to the copy. The copy is made using a native serialization technique. This means that custom serialization will be respected during the copy.

This method is designed for copying data objects, such as elements of a collection. It is not intended for copying a UIComponent object, such as a TextInput control. If you want to create copies of specific UIComponent objects, you can create a subclass of the component and implement a clone() method, or other method to perform the copy.

Parameters value:Object — Object that should be copied.

Returns Object — Copy of the specified Object

Nikhil Sidhaye