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:

  1. 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!

    ReplyDelete
  2. I am glad.. that it helped somebody :)

    ReplyDelete
  3. 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.

    ReplyDelete
  4. 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

    ReplyDelete
  5. 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.

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

    ReplyDelete
  7. 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.

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

    ReplyDelete
  9. You save me (^.^)^ !!

    ReplyDelete
  10. 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

    ReplyDelete
  11. 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

    ReplyDelete
  12. or You could just define Your circle as ui component

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

    ReplyDelete
  13. 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)

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

    ReplyDelete
  15. Thanks a lot for the example and explanation.

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

    ReplyDelete
  16. 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!

    ReplyDelete