I’ve moved my blog: http://www.robsondesign.com/blog/
Please update any bookmarks, links, etc.
Web-based software (RIA) developer
I’ve moved my blog: http://www.robsondesign.com/blog/
Please update any bookmarks, links, etc.
In view of the fact that I’ve written about bubbles here and here, you might conclude that I find bubbles interesting. And it’s OK for you to conclude that; I won’t be offended.
Here’s an interesting tidbit about bubbles and tool tips: tool tips bubble down – sometimes. If you have a container with its toolTip property set to some value, and the container has a child with no value set for its toolTip property, then the child will show the container’s toolTip on mouse-over (why, I don’t know). However, this will not occur if the container is itself inside a navigation control (such as an Accordion or TabNavigator).
To see how this works, take a look at this sample. As usual, right-click on the app to view and download the source.
I don’t know why tool tips bubble this way, but it seems useful to know that they do.
Until now I haven’t had much reason to alter the default tool tip behavior in Flex: apart from styling, the tool tips work just fine out of the box for most applications. Recently, though, I’ve started playing with the tool tips a little, and thought I’d share some of the results.
First, it’s very easy to add show and hide effects to the tool tips. The only quirk is a standard Flash / Flex thing: to animate the alpha of text, the font needs to be embedded. Apart from that, it’s a simple matter of defining the effects that you want and then setting the value of the ToolTipManager.showEffect and ToolTipManager.hideEffect properties to your new effects. Cool!
However, there are a couple of things about the way the tool tip effects work that I find mildly disappointing. One of these is that the hideEffect is not triggered on mouse-out. Instead, when you roll the mouse cursor off of the UI element, the tool tip goes away instantly, just as though you never set a value for hideEffect. The only time the hideEffect is triggered is if the mouse cursor remains on the UI element past the time set in the ToolTipManager.hideDelay property (the default is 10 seconds).
The other disappointing thing (and maybe I’m just contrary) is that the showEffect *does* get triggered even when there is no delay between tool tips. What I mean here is that ToolTipManager has a property called scrubDelay (default = 100 milliseconds) that defines how much time there needs to be between mouse-out and mouse-over in order for showDelay (default = 500 milliseconds) to kick in. So if you have two buttons right next to each other (each with its toolTip property set to something interesting) and the user moves quickly from one to the next, Flex will dispense with the delay and show the tool tips immediately. Under these circumstances, it would seem to me to be ideal if Flex also dispensed with the showEffect, because by the very nature of effects (change over time) the showEffect necessarily introduces a delay.
OK – if a picture is worth a thousand words, then a code sample is worth a million. Check out this sample app which has no effect defined. When you move the mouse cursor quickly from one button to the next, you’ll notice that there is a delay of about 0.5 second for the first tool tip to appear, but after that there is no delay. Click here to view the application, and right-click on the app to view the source (not very interesting source, you’ll no doubt agree).
Now, here is an app with effects defined and assigned to the tool tip. When you move the mouse cursor from one button to the next, you’ll see that the hideEffect is omitted but the showEffect isn’t. Click here to view, and right-click on the app to view the source (somewhat more interesting source this time – I recommend you download and play with it).
As you’ll see in this new sample app, I’ve been having fun playing with Flex Component Kit for Flash CS3. The new app has some important features that my sample app for part one did not have:
Overall, there is more interaction between the SWC and the Flex app, and yet at the same time they are more loosely coupled (the Flex app no longer specifies the view state of the SWC).
In the course of putting this demo together, I ran across a number of bugs and gotchas. These may be documented elsewhere, but I’m listing them here for convenience:
1. At one point, I placed the FLA and AS source in the root folder of the Flex app, thinking it would make distribution simpler. I did not receive any error message, but the Flash component simply refused to appear in the compiled Flex app. Lesson: don’t put your Flash source in the Flex root!
2. When you use external AS files in your FLA, you need to manually set the source attachment parameter in Flex to point to the root folder of your Flash AS files. In Flex Builder, you do this like so:
Open Project Properties -> Flex Build Path -> Library path
Expand your SWC by clicking on the plus sign next to it
Click on Source attachment and click Edit (or double-click on Source attachment)
Enter the path to your Flash source files (or click Browse to navigate and select)
3. In the AS file for the Flash movie clip class, it’s necessary to import flash.display.MovieClip even though you don’t use it in the class. If you don’t import it, you’ll get a compiler error in Flash and an utterly unhelpful error in Flex (see #4).
4. If there’s a problem with the Flash component, you are likely to get a message from the Flex compiler telling you that an “internal error” has occurred. This, of course, is the sort of error message that’s lots of fun to see, because it tells you absolutely nothing yet prevents you from making any progress in your work. Yippee!!!
5. When your Flash SWC movie clip is based on a custom class, you need to take an extra step after running Commands -> Make Flex Component: In the movie clip’s Symbol Properties, the Base class needs to be changed back to flash.display.MovieClip.
6. Flex Builder’s Auto-complete did not detect the custom event defined in the SWC base class, so I had to type it in by hand (ugh!). However, Flex seemed to recognize the event name after it was typed; I didn’t get a compiler error or warning.
7. This one may seem obvious to you, but I didn’t think about it till I ran afoul of it. In your Flash SWC movie clip, you may use a boundingBox to establish your component’s size inside Flex (so that Flex doesn’t keep resizing it when it animates). Well, your boundingBox must be on the stage for the entire timeline of movie clip, or Flex will do really weird things with your component.
Overall, the integration is still more cumbersome and buggy than I would like, but there is reason to hope it will improve as Flex 3 moves through its Betas toward production. Meanwhile, the Flex Component Kit is usable, and it provides a useful tool for building very cool applications.
You can view the demo app here. Usually, all you need to do is right-click on the app to access the source; however, the SWC seems to be interfering with that, at least with version 9.0.28 of the player. If you right-click a few times and can’t get the “View source” option, then click here to get the source. Enjoy!
(In case you’re wondering, the demo app was inspired by an old Far Side cartoon that showed a scientist catching a butterfly and asking for a jar of ether.)
Well, I finally posted the files from my FlexManiacs presentations. I was hoping to have the source files completely documented before posting them, but I’ve been busy moving my family to Rhode Island (it isn’t easy to move a family of 6). I still plan to add the documentation, and to extend the sample applications further, but I think that they are useful in their current state. You can get the presentation slides and sample apps here.
The FlexManiacs folks, meanwhile, posted a Connect recording of my Modules presentation. The sound quality isn’t great (I didn’t stay close enough to the pc mic), I talked too fast, and I said “um” too many times, but in spite of all that it’s probably still useful. I recommend advancing the play head to about the 2 minute mark, because everything before that is just me getting set up and the audience getting settled in. Anyway, you can see and hear the presentation here.
Update: I put together an extremely simple Cairngorm app for one of my FlexManiacs presentations, “Using the Cairngorm Framework.” The app was so simple that I did not think it worth posting for download, but then I received a request for it. I figured that if one person requested it, then others may find it useful as well, so I uploaded it. You can get it along with my other FlexManiacs materials from the downloads page. (As an aside, this incident points to the need for blogs such as S.A.S.S.I.E. – sometimes you just need a simple example.)
Ryan McGeary is a co-worker who, paradoxically, is both a Flex skeptic and a nice guy. In fact, he was good enough to attend FlexManiacs in spite of his aversion to Flex / Flash so that he could provide me (and our CEO) with some constructive feedback. As I had hoped, he came away from the conference with a bunch of thoughtful comments and questions, some of which made me step back and re-evaluate my own attitudes and approaches.
I hope to write responses to several of Ryan’s points in the near future, but I’d like to start with an observation he made about the Flex developer community: he noted that we tend to be IDE dependent. I know that there are some Flex developers out there who do all their work with text editors and won’t touch Flex Builder with sterile gloves, but based on my experience I have to concede that they seem to be a small minority. (Whether they constitute a proportionally smaller segment of the Flex community than their counterparts in other development communities I have no idea. Someone should do a study on that.) As for me, I use Flex Builder every day, and I don’t see a need to change that habit. Let me explain why.
Memory
I have invested substantial effort in developing a knowledge and understanding of the Flex framework. I’m sure that if I were to put the effort into developing a few applications using just TextPad and mxmlc I would end up with even more of the Flex framework committed to memory, and in fact I would need to have it committed to memory in order to be as productive with TextPad as I am with Flex Builder. But I don’t know why I would want all that stuff in my memory when it’s already in my laptop’s memory.
Don’t misunderstand me. I’m not among those who think that it’s a waste of time to teach arithmetic to children now that we have calculators. On the contrary, I strongly believe that everyone should learn to think and act independently – which is one of the reasons my wife and I home school our children. However, I’m not convinced that memorizing highly transient data is of any lasting value.
Like many other technologies, Flex is changing rapidly. While some people are just now discovering Flex 2, Flex 3 is in public Beta. By the time many of us are comfortable with 3, Adobe will be pushing 4 out the door. Who can tell what parts of the framework will change? Some properties and methods that are now private are likely to become protected. Some members – and even entire classes – that we now use every day will probably be deprecated. New methods, properties, and classes will be added that will provide native means of accomplishing tasks that we now hack for ourselves. It seems to me that memorizing all the details of the Flex framework in its current state would only make it more difficult for me to go with the flow of all of these changes, and hinder me from maximizing the benefit that could be derived from them. That being the case, it makes sense — having already built a strong familiarity with the framework — to allow the IDE to help with the details via code hinting.
Other factors
Besides memory helps, auto-complete is also a useful time saver. For example, it’s nice to be able to type “tabn” instead of “TabNavigator” all the time. Also, having the closing tag generated automatically is a helpful bonus. (Go ahead, call me lazy.)
Then again we have the annoying phenomenon of programmer error. I’m old enough to know that no matter how thoroughly I learn Flex (or any other framework) I will still make mistakes from time to time. When that happens, and the compiler fusses at me, it’s really nice to be able to double-click on the error message and be taken right to the very line of code where my error resides.
Another benefit of Flex Builder is the ability to quickly dive into the framework source. I can highlight a framework class or member identifier in my own code, hit F3, and be taken directly to the appropriate place in Adobe’s source code. This is a great help when trying to figure out why I’m getting unexpected side effects, or in determining the best way to extend a framework class.
Let’s not forget the other useful keyboard shortcuts: Shift-CTRL-C to comment a block of code; CTRL-O to open an outline of the current file; Shift-CTRL-O to sort and organize import statements; etc.
So far, I’ve only been dealing with benefits of the IDE’s source editor. The design view (WYSIWYG) makes it easy to quickly throw together a UI layout, and has saved me a substantial amount of time on a number of occasions.
Simply put, a well-built IDE is a useful tool, and Flex Builder – for all of its shortcomings – is a well-built IDE. I acknowledge that there may be some developers who are too lazy to learn the framework at all, and couldn’t even write HelloWorld.mxml without Flex Builder. However, the fact that some people misuse a tool is not an argument against using the tool. Murder has been committed using hammers, but when it comes time to drive a nail I don’t hesitate to reach for my Estwing.
During my Flexmaniacs presentation on Flex modules this morning, I encouraged the audience to check out Michael Labriola’s cool implementation of modules using ILibrary and LibraryLoader. However, for some reason I referred to him as “Jeff Labriola.” Thankfully, Rob Rusher was there, and he was good enough to point out my error. He also introduced me to Mike, who took it very graciously. Now that I have a face to put with the name, I hope to keep it straight in the future. Anyway – my apologies to Mike and to anyone who was misled by the misinformation I disseminated.
In response to some good feedback to the previous post on event bubbling, I’ve expanded the Bubbles demo to show how an MXML component can dispatch a custom event, which in turn bubbles up and is handled by a grandparent container defined in ActionScript. I’ve also commented the code to help clarify the difference between target and currentTarget, and added id’s to the UI components to make the value of the target property more readable.
When you open the new demo, click on the Feedback tab to see the custom event dispatched and handled. As always, right-click on the application to view and download the source. When you look at the code, notice the constructor arguments in CustomClickEvent.as:
public function CustomClickEvent( message:String,
type:String=EVENT_CUSTOM_CLICK,
bubbles:Boolean=true,
cancelable:Boolean=false)
The value of bubbles defaults to true, since the CustomClickEvent’s entire purpose in life is to bubble. (Don’t you love bubbly personalities?)
I’ve been playing with the Flex Component Kit for Flash CS3, and it looks pretty cool. I have run into a couple of issues, however.
One issue has to do with the bounding box feature which – in theory – works as follows: When you create a new Flash CS3 file that is to be published as a Flex component, the Flex layout managers treat it as though it is the full size of the Flash stage (which still has the same age-old default of 550 x 400). In order to avoid this, you create a rectangular movie clip of the size that you want the component to be, and give it an instance name of boundingBox. However, in actual practice this does not work if your component includes GIF images that are larger than the bounding box: the portion of the GIF that is outside of the bounding box shows up in the Flex application. Not cool.
The other issue has to do with Flex Builder’s code-hinting and code-complete features. Even though my Flash SWC had all of the appropriate frame labels, Flex Builder didn’t help me out with any code hints for currentFrame. Call me spoiled, but I like it when the IDE helps me out with the spelling of arbitrary language and framework names.
In spite of these disappointments, I’m liking the possibilities here; it looks like it will help to build even cooler UIs. And according to Adobe it’s going to get a whole lot better with Flex 3 – but I’m not going to let myself get too distracted with Flex 3 until Flexmaniacs is over.
I’ve put together an extremely simple demo – simple enough that I think it should be self-explanatory. However, these things always seem simpler to the author than they do to anyone else, so feel free to post any questions or issues that arise. I hope to take the demo a step or two further, and will make the results of my experiments available with future posts.
As a child, I never thought much about why bubbles worked. I just stuck the wand in the bottle, lifted it back out, and blew. It was fun to watch the bubbles rise up in the air and float away. It was even more fun when there was a dog around, because then you could watch the dog chase the bubbles.
When I started working with Flex, however, I found that I had to think about bubbles. What are bubbles? How do they work? What is the point of bubbles?
I’m not sure I fully understand them yet, but I’m starting to figure out some of their practical uses, and it occurs to me that the bottled bubbles help a little. Just like those bubbles float up and up through the air until a dog or some other event handler does something with them, bubbling events float up through the application containers. The containers can either enjoy watching the events float, or they can jump up and handle them.
It turns out that this behavior can save some work and help to build loosely coupled components. For example, suppose you have a form-based app with a validation routine that checks to see whether the user has changed the data. One way to do this is to run the routine whenever any field in any form loses focus. Obviously, writing code to add the event handler to every single form element is sub-optimal. This is where bubbling can come in handy: You can create an event listener in the root container (usually the main Application mxml file) that listens for the focusOut event. Every time any form element in the app loses focus, this event will be fired. This is a fine place to put the code that checks whether the user has made any modifications to the data.