I just finished up a new Flex 2 component that allows you to add close icons to tabs that when clicked will remove them from a TabNavigator.
Here is the component in action:
When you click the "Add Tab" button, a new tab is created with the given label and icon. The display of the close icon depends on the state of showCloseIcon. When set to mouseOver, the close icon is only show when the mouse is over the table. Setting to true always shows the close icon, and setting to false always hides it. Note that in the above example, when changing the state of the close icon, the tabs needs to be removed and re-created. I didn't build in support to change the behavior on-the-fly because I didn't feel this was a common use case.
When a close icon is clicked, a new ItemCloseEvent is dispatched. You can listen for this event via the itemClose event in MXML. By default, the close icon will automatically remove the tab from the tab navigator. If you don't want this default behavior, you call event.preventDefault(); in the event handler and the tab will no longer be removed automatically. This is useful for having, say, a question mark instead of a close icon that when clicked can open a help document.
Lastly, the close icon can be specified via the closeIcon and overCloseIcon properties. I didn't build in support for a down icon because I didn't feel it was necessary, but doing so would require just a few minor tweaks to the code base.
This is a component that I built for the current client project I'm working on. Therefore, I'm not able to offer this for download, nor am I able to share the code with you. Everyone that knows me knows I'm a big fan of open source and a large contributor to OSFlash, so I'd share if I could...
This component was a little on the tricky side to write, but I hope it proves inspirational for developers out there. With Flash (and therefore Flex), you can pretty much do anything that you can imagine... it just takes a little time, ingenuity and determination. Honestly, I tried 3 different approaches to making this component before I was successful, but overall it was less than a day's work.
I'm sure there are some bugs to work out, but I'm pleased with how well it's turned out so far. It's a vital piece in the project that I'm working on...
Flex 2, Component, ActionScript 3
Very cool Darron, wish I could learn from the code.
I find this a little scary though. I'm (still) new to Flex and when I see somebody of your caliber taking 'less than a day' (sounds more like 7 hours than 2) then I get the feeling that it would take me something like 3 days.
Time? I got a little
Determination? Check
Ingenuity? Hmm maybe...
Maybe I am the only one that feels that anything out of the ordinary can be really hard work in Flex. To the user this looks like a tiny little change as far as the UI goes but it sounds as if it was quite a challenge behind the scenes, even for you who, if I may say so, is of Rockstar ability.
7 hours instead of 2 is about right. The problem I ran into was that I tried 2 different approaches first before I was able to come up with the right solution, so I hit a brick wall a few times.
Component development in general takes a lot of practice and study. I've been building component since before they were called components (remember SmartClips in Flash 5?)...so I just have a lot of experience in that arena.
The biggest thing, I think, is just spending time learning the component framework. When you understand the Flex component architecture, it becomes easier to roll your own. A really good resource is the slides and examples from the Flex 2 Component Developer Summit on Ted's blog:
http://www.onflex.org/ted/2006/07/adobe-component-developer-summit.php
In particular, pay attention to the Flex Framework Internal slides.. they should be a big help in overall understanding of components in general.
Pretty ace :) Found a glitch, if you add a tab and then click the close button and then press the down key, you get the following error in the debug player:
TypeError: Error #1034: Type Coercion failed: cannot convert mx.skins.halo::HaloBorder@806d581 to mx.controls.Button.
at mx.controls::ButtonBar/http://www.adobe.com/2006/flex/mx/internal::drawButtonFocus()
at mx.controls::ButtonBar/drawFocus()
at mx.containers::TabNavigator/drawFocus()
at mx.core::UIComponent/mx.core:UIComponent::focusOutHandler()
at mx.containers::TabNavigator/mx.containers:TabNavigator::focusOutHandler()
at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.containers::TabNavigator/mx.containers:TabNavigator::keyDownHandler()
Thanks for the heads up Owen.. like I said, I'm sure there are some bugs to work out. :-)
Since we'll be using this pretty heavily in our app, the component should be rock-solid by the time we're done with it!
Awesome but I have a couple questions....
Would it be possible for you to explain how you measure where the close buttons go (which event)? Also, how you maintained the tab's "hover" effect when the close button has focus?
Great post, if it had code. Kinda dumb that you can't share it.
Long labels overlap the close icon.. other issues if there's more then enough tabs.. but thats probably just the default Flex behaviour
@Ryan - Thanks. The overlap issue is a strange one because I'm just adding enough space for the close icon in the overriden measure() function. It seems to only be a problem when the label gets shortened and displys the "..." at the end. I guess the label width isn't being reported as what I thought it was, so I'll have to take a closer look at that.
I didn't do anything for too many tabs, so anything you see there is just the default Flex behavior. The better option would be to add scroll arrows and clip the children appropriately.