Pages

Tuesday, February 13, 2007

sprites in mxml

While adding a sprite to mxml base application it produces a error like :

cannot convert flash.display::Sprite@3d2a191 to mx.core.IUIComponent.


Sprite is nothing but a new object introduce which is similar to movieClip. We can draw inside it and place it on to the stage by using its graphic object


The reason for error is mailny because sprite is the superclass of UIComponent , where as to add any object in mxml base container we need it to be a type of UIComponent. As the UIComponent class is the base class for all visual components. addChild method in UIcompoent Overrides the addChild method DisplayObjectContainer’saddChild method and adds a new object to mxml base container. (DisplayObjectContainer’ is a super class of sprite class ) Hence when we do addChild(newObject) we get a error , if newObject is of type sprite, as addChild which is invoked is of UIComponent class's method.

Hence we need to add a sprite to UIcompoent first and then the UIcomponent to mxml base container as follows :


<?xml:namespace prefix = mx /><mx:application initialize="drawStuff()" layout="absolute" mx="http://www.adobe.com/2006/mxml">

</mx:script>

<![CDATA[
import mx.core.UIComponent;
var bgColor:uint = 0xFFCC00;
public function drawStuff() : void
{
var ref : UIComponent = new UIComponent(); // creating a UI compoent Object
var circle1 : Sprite = new Sprite();
circle1.graphics.beginFill(bgColor);

circle1.graphics.drawCircle( 40, 40, 40 );
circle1.buttonMode = true;
addChild( ref ); // add UI component to mxml base container
ref.addChild( circle1 );// adding sprite to UIcompoent
}

]]>

</mx:Script>
</mx:Application>

16 comments:

Chris said...

Thank you for posting this! I've been looking everywhere for a simple example of how to draw shapes inside MXML, and no one seems to know how to do it! Thank you for clarifying this so simply!

Mayur said...

I am glad.. that it helped somebody :)

Chris said...

On a similar note, how can children of the UIComponent capture user input like KeyboardEvents? For example, if I instantiate a class that inherits Sprite, I can draw to it just fine like in your example. However, doing something like:

addEventListener(KeyboardEvent.KEY_DOWN, mySprite.onKeyHandler, false, 0, true);

doesn't seem to ever get called.

Mayur said...

hi chris...
you have to set focus to component to invoke event handlers on it...
this works..
ref.setFocus(); // ref is the ui component in which u are adding sprite..

and then

ref.addEventListener(KeyboardEvent.KEY_DOWN,onKeyHandnler,false,0,true);


function onKeyHandnler(e){
mx.controls.Alert.show("Sprite clicked");
trace("dfgdf");
}

there is a "KeyboardEventExample" class given in flex help..
that does exactly what u are trying to do...

let me know if this helps you

Chris said...

Again, thanks! I also found that the UIComponent won't regain focus if the browser loses focus, so I also need to bind it to Event.ACTIVATE.

Mayur said...

thats correct!
I am glad that you got it :)

Chris said...

Another thing I've noticed is that when drawing to the sprite, you can draw outside the parent container. For instance, if you create the UIComponent inside a Panel, you can draw outside the panel. Is there a way to mask drawing to the parent container? I tried things like ref.mask = ref, but it has no effect.

Anonymous said...

Thanks a lot, at last a useful example for people that for people that come from Flash and are trying Flex!

Anonymous said...

You save me (^.^)^ !!

Paul said...

Thanks for this. The API documentation and code complete are very misleading when they indicate the following;
addChild(child:DisplayObject)
Sprite descends from DisplayObject so you would think that you could add it without having to use a UIComponent

Mayur said...

Yes you are right..everything like.. flexloader.. etc things can not be added directly ..we need a uicomponent.. to actually add it to our any other visual component..

and also.. the properties like height and width.. needs to be set for both..for sprite that is added and the uicomponent that is holding this sprite

michelek said...

or You could just define Your circle as ui component

var circle1: UIComponent = new UIComponent();
circle1.graphics.beginFill(bgColor);
...

Mayur said...

Correct! you are right..
But sprite more at a lower level then UIComponent..and this is just a example.. how to make use of your sprite extending custom components in your mxmls'.
(Just a demo to solve problem.. adding circle to mxml was not a actual problem)

Anonymous said...

Thanks a lot!!!!!!!!!!! you just ended more than 2 hours of researching.

Michael said...

Thanks a lot for the example and explanation.

It took me a lot of time finding a real and easy solution.

Asmi said...

Thank you soo much!! I've been trying to get something like this to work for hours..and I just couldn't figure out why. And the examples in the docs were not helping.
This was a great help!