Monthly Archives: July 2008

Bug when creating CS3 UIComponents in Document Class constructor

Under one specific condition, a Flash CS3 component will not draw for the first time until after it has been displayed to the user. Generally, that’s not a problem, but there are times when it becomes noticeable. The following report demonstrates an obscure bug that most component developers working with the CS3 UIComponent architecture won’t encounter. However, it becomes more visible with specific types of components, such the the Layout Containers in the Yahoo! Astra components for Flash CS3.

A quick background explanation to get everyone up to speed. The CS3 UIComponents rely on the stage’s “render” event as part of the validation model. Basically, a component will wait until just before Flash Player displays something new to screen before running its main drawing code. This ensures that developers can set many properties at once without redrawing every single time. The render event provides a “last chance” place for code to run.

The Bug: No Event.RENDER for first frame

When a SWF first starts up, the document class constructor is run. Imagine that you want to create an application with a layout container, like the Astra VBoxPane, to arrange your controls. You insantiate the VBoxPane and add it to the display list. Next, you create several controls and add them to the VBoxPane. Very standard stuff, and you put all this code into the document class constructor.

When you run your SWF, sometimes you notice a very strange issue on the edge of your vision. For a very brief moment (if you blink, you’ll miss it), all the controls in the VBoxPane are stuck in the top-left corner at x=0, y=0. You don’t see it happen every time, though. Maybe it’s your monitor’s refresh rate. Maybe the browser just doesn’t allow Flash Player to draw itself right away, but it definitely happens sometimes.

The problem I discovered is this: Event.RENDER doesn’t get fired before the very first frame is drawn when you start up your SWF. The first time you can receive Event.RENDER is after the first time Event.ENTER_FRAME is fired. For reference, the enterFrame event is a lot like RENDER. It’s the very first code that gets run after Flash Player draws to screen. When the SWF starts up, the document class constructor code gets run, then Flash Player draws itself, Event.ENTER_FRAME is fired, and then Event.RENDER is finally fired the first time before frame two. In the case of our VBoxPane, all of its children are on the display list and visible to the user when the first frame is drawn because we added them to the display list, but the component never had a chance to position them!

The Workaround: A simple drawNow()

If you’re using any of the Astra layout containers, and you encounter this problem, there’s an easy fix. In your document class constructor, after you create the layout container and add its children, call drawNow(). This will force the container to draw immediately. Since we’re still in the constructor, it’s before the first frame is displayed to the user, and all the controls should be laid out properly.

I should note, most developers using the CS3 components never have to touch drawNow(). It’s most useful to custom component developers who want to put components inside other components. It ensures that the child components draw properly. While a bit of a pain, that’s a very different thing than the bug I’m reporting here.

Test case: Some simple code to see this problem.

As part of my investigation, I created some simple code to demonstrate the bug. This is code I’m submitting to Adobe in a bug report. It contains trace() statements that show the difference between the expected order of operations and the actual order.

First, a document class that instantiates a component:

package
{
	import flash.display.Sprite;
	import flash.events.Event;

	public class UIComponentFirstRedraw extends Sprite
	{
		public function UIComponentFirstRedraw()
		{
			super();

			var test:TestComponent = new TestComponent();
			this.addChild(test);

			this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);

			//the trace calls demonstrate the actual order of operations
			//numbering indiciates the expected order.
			trace("1. END OF DOCUMENT CLASS CONSTRUCTOR");
		}

		private function enterFrameHandler(event:Event):void
		{
			this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
			trace("3. ENTERING FIRST FRAME. COMPONENT IS NOW VISIBLE TO USER.");
		}

	}
}

And the simple component that is created in the document class constructor:

package
{
	import fl.core.UIComponent;

	public class TestComponent extends UIComponent
	{
		public function TestComponent()
		{
			super();
		}

		private var drawnOnce:Boolean = false;

		override protected function draw():void
		{
			super.draw();

			if(!this.drawnOnce)
			{
				this.drawnOnce = true;
				trace("2. THE COMPONENT IS DRAWING FOR THE FIRST TIME! I SURE HOPE IT ISN'T VISIBLE YET!");
			}

		}

	}
}

For the next version of Astra, I plan to work around the bug in a different way so that developers don’t need to call drawNow() manually. However, it is a hack that involves visibility changes, and I definitely want to see this bug fixed in UIComponent in the future.

Foundation Flex for Designers has a misleading title

Friends of ED markets its books with the slogan Design to Designer. When I read Foundation Flex for Designers by Greg Goralski and LordAlex Leon, I wondered who gave this book the wrong title because it didn’t quite fit that philosophy. A better name might have been Foundation Design Tools for Flex Developers because I don’t think the book’s target audience will find it very appealing. Instead, maybe a developer might be able to pick up a few skills to use when he doesn’t have a designer on hand. Either way, I think the book as a whole could use some rethinking.

A design major was my second choice in university. I ultimately become a software engineer, but I’d like to think I have at least a little insight into what makes a good book for designers. When I put my design hat on, I want to learn from looking at things that are designed well. Inspire me while you teach me the basics. Unfortunately, this book doesn’t offer anything like that for me. Almost every screenshot displays what some of my co-workers call “programmer art”. Even worse, many still have “a blue-gray background and silver-skinned components”. That’s exactly what the description on the back says the book is trying to prevent. It also claims to help the reader create “an application that is both visually stunning and beautifully functional”. With big goals like that, some very strong designs featured in every example should have been a high priority. At the very least, every example should have been fully skinned so that they looked nothing like Flex’s defaults.

It’s common for book authors and documentation writers to ignore best practices when demonstrating how to do something specific with technology. People want simple examples, and it can be hard to do things “right” when there are many more ways to get the point across that take a shortcut or two. I’m against this practice of taking shortcuts because I believe every line of code (or every pixel of your design, for that matter) will teach your reader something, and its not always something you intended. Someone who has no basis for judging good code will believe all your code is perfect because you’re supposed to be the expert.

An example of skipped best practices appears in chapter 3 where the authors create a “personal website” with Flex. Where should I begin? First and foremost, this website consists of mostly text and and a few static images. No real rich interactions provide a justification for using Flex (or even using Flash Player!). The chapter’s purpose was to teach the reader how to use states. Personally, I think a view stack would have been better for the use-case presented in the example. In short, everything about this example would have been better in HTML. Something smaller, perhaps more of a component with advanced options, would have provided a better example of states.

One interesting detail about the design of the book itself bothered me: All the sample code is displayed through screenshots from Flex Builder. In other words, a ton of text in this book is displayed as images. Sadly, this makes all the code slightly blurry because the regular book text is printed at a much higher quality. Additionally, for some particularly long lines of code, rather than breaking each statement across multiple lines, they simple scaled some of the screenshots down to smaller size. This makes the text absolutely tiny. Anyone with poor vision will only get frustrated trying to read the many of the MXML samples.

In most chapters, the examples are presented through simple Flex applications. Unfortunately, I believe this pulls the focus of the book away from design and the tools available for designers targeting Flex, and it presents a lot of ActionScript that doesn’t influence the design in any way. Friends of ED, O’Reilly, and other publishing companies already have entire books introducing ActionScript. It seems to me that most of the code should be skipped to really focus on things designers can do to enhance rich applications. More time could have been spent on building content in Flash CS3 or other designer-friendly apps and bringing those designs over to Flex Builder. Similarly, some tricks for making skins completely transform components in new ways would really energize the Flex community. I remember the first time I learned how to exploit background images combined with padding in CSS to add icons and other flare to HTML. For something so simple, I was excited because it was looking at a problem from a direction I would never have considered. Nothing like the CSS design revolution of the HTML world has influenced Flex yet. Projects like Degrafa are starting to change things, but the book provides no evidence of this project’s interesting new take on Flex design.

I can’t recommend Foundation Flex for Designers. With the focus of design inherent in the title, I expected some real new approaches to design for Flex that would provide ways to skin components that aren’t immediately obvious (and maybe even do things in ways that Adobe didn’t expect). Instead, I got a rehash of the same old stuff that appears in other Flash and Flex books. All the Flex and ActionScript basics are available in book form now. Publishers need to begin branching out to more specialized areas. Most disturbing, for me, is the fact that the skin designs presented in the book are so poor that it seems difficult for even an experienced designer to pick up Flex-related skills. I see many readers spending their entire time critiquing the ugly screenshots instead of reading and learning.