Archive for August, 2007

Resizing CS3 Components in Flex

Friday, August 24th, 2007

So the problem today was getting a component created in CS3 and exported as a Flex UI component to resize gracefully in Flex. I wanted the component to show a nice grid beneath an object, and when resized, the grid should expand but the object should stay the same size.

My component should go from this:

Component in small stage

To this:

Component in expanded state

Writing the code for drawing the grid was no problem. The difficulty centered around knowing when the component was resized.

The first approach was to add listeners to stage resizes within my “ZoneSelector” CS3 component:

[code lang="actionscript"]
public function ZoneSelector(){
    stage.scaleMode = StageScaleMode.NO_SCALE
    stage.align = StageAlign.TOP_LEFT
    stage.addEventListener(Event.RESIZE, resizeHandler)
}
public function resizeHandler(event:Event)
{
    //do stuff with the stageWidth and stageHeight info
    mcBG.width = stage.stageWidth
    mcBG.height = stage.stageHeight
}
[/code]

The component tested fine within CS3. But when I embedded my component in flex…

[code lang="html4strict"]

[/code]

… I started getting an insidious “null reference” error. It turns out that the .swc component doesn’t have a reference to the Stage even after the Flex container has launched a creationComplete event.

So, I switched things around and added a listener to the ZoneSelector constructor so I knew when the stage was available…

[code lang="actionscript"]
public function ZoneSelector()
{
    addEventListener("addedToStage", onAddedToStage);
}
public function onAddedToStage(event:Event):void
{
    //now I'll get stageWidth and stageHeight and do something with it
}
[/code]

But OH NO things are not that easy. In doing this I discovered that the Stage is really the stage for the entire Flex application, not the immediate parent container of my component. To the chorus of voices snickering “read the API” I say to you “BAH!”

So, my final solution was to add a function within my component that handled size updates, and then called that function whenever the Flex container object received a size event

In the component I have the function

[code lang="actionscript"]
public function setComponentSize(w:Number, h:Number):void
{
    //do something with the width and height sent in from outside
}
[/code]

and in my Flex .mxml I have..

[code lang="html4strict"]

[/code]

When the Flex application is resized, the zsCanvas has a resize event, which calls the setComponentSize function in the component.

There are probably much better ways to do this and no better way to tell the world than to describe them in a comment below.

I’m gonna get that frog.

(Not!) casting to ArrayCollection

Wednesday, August 8th, 2007

This one tripped me up a few times, so maybe I’ll save some of you a little time.

If you have an Array that you’re transforming to an ArrayCollection, don’t forget the new statement! Often I’ll forget I’m creating an ArrayCollection from an Array and not just casting, so I’ll try something like

var powerfulArrColl:ArrayCollection = ArrayCollection(boringArray)

This, of course, yields a Type Coercion failed: cannot convert (gobblygook) to mx.collections.ArrayCollection.

When you’re bleary-eyed day is at and end, very practical and simple error messages like get caught in the gaps opening between your brain folds. “WTF?! What do you mean you can’t cast fricking array to arraycoll…fricking, filth foul….oh….yeah, I’m not casting. I’m creating a new ArrayCollection with the old array as a parameter.”

So don’t forget your new statement.