Awhile back I had developed (as many of you may have already) a Panel subclass. Basically I needed a way to add buttons to the titleBar area much like the mx:TitleWindow has the close button. The end result being something very similar to a Window’s Explorer window (not IE). Well if you have tried this, then you know it is not as simple as just saying titleBar.addChild().
A developer’s initial approach may be to override updateDisplayList and createChildren to insert child components inside the titleBar. This was my initial take on it. But this is flawed in that you are…
- …unnecessarily overriding methods not generally associated with this area of the Panel. UpdateDisplayList in a nutshell is used to update child components. In terms of mx:Panel, generally child components are what a developer sticks inside the content area. CreateChildren is again something generally associated with child components. Basically these methods are the wrong place to insert items in the titleBar area.
- The other flaw in this is that it inefficiently/unnecessarily renders your new titleBr assets. For instance, you want to add 3 buttons to the Panel’s content area. Now let’s assume that the Panel will remain a fixed width and height. So not including calls to these methods during pre-child attachment phases, we are calling these methods 3 times each per button.
I should probably start prefacing my posts with a disclaimer that they are simply guess-timations on the flex framework as I haven’t done any true performance testing and/or benchmarking on my findings. But what testing I have done has yielded positive results. So what I am really trying to say is, correct me if I am wrong.
After doing some peeking into how Panel (not TitleWindow) does the close button logic, I found that it isn’t really tapping the aforementioned methods. The only time it was really calling the createChildren method was to attach the titleBar to its rawChildren and the subsequent children of the titleBar. No layout, sizing, etc was really being handled in this method. More about this later….
Firstly I wanted to be able to make my Panel subclass scalable in that I could have one guy with 3 buttons in the titleBar and then another with one. Also I wanted to be able to attach functionality on the instance’s buttons rather than have a class with hardcoded click listeners. So I just made a simple public method addTitleBarButton (value:Button = null):Button. This method basically takes/creates a button, adds it to an array, then adds it to the titleBar. Lastly it returns the button in case you need to do more to it later on. Just doing this though will not display the items added. You need to resize and reposition them as well. Onto a bit about rawChildren.
Panel’s titleBar is considered a rawChild. So it is not really counted in the displayList (at least directly). This is also true of alot of the skins associated with the container’s borders. When Panel needs to update its borders and titleBar, it does so via LayoutChrome. So this would be an ideal place to add some logic to any new titleBar assets. Now you can get those newly added buttons from that array I mentioned earlier. Then by cycling through the array and getting some x, y, width and height info we can see the new title buttons inside the titlebar area. All without even touching the createChildren or updateDisplayList.
30 Comments so far
Leave a comment
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Hi There, do you have any example usage… it’s just that I’ve used this code and I just get a normal looking Panel. I’m thinking that there must be a way of adding buttons, but alas I’m too incompetent to work out how (and it is late on a Friday here in New Zealand).
Thanks,
Comment by Luke McLean Friday, March 23, 2007 @ 3:40 amLuke.
Oops silly me (lazy me actually). Soon worked it out. Thanks heaps for the post it has saved me lots of time, now just to write all the events I need and it will look sweet!
Blessings,
Comment by Luke McLean Friday, March 23, 2007 @ 4:08 amLuke.
[...] Pod [...]
Pingback by Source Code for jwo_lib components have been added. « jwopitz - flex/flash exploration Friday, April 27, 2007 @ 1:41 pmThanks for the component. Is there any way I can create a controlbar in the panel by modifying this class? I’ve been racking my brain trying to create a controlbar using actionscript. My understanding is that the controlbar needs to be the last component. I’ve tried adding a controlbar last and it still shows up inside the panel. Any advise?
Thanks
Comment by Luis Alvarez Sunday, April 29, 2007 @ 6:33 am-Luis
You could probably add a controlBar in the header. Just use:
var cb:ControlBar = new ControlBar();
Pod.addTitleBarComponent(cb);
You might have to do some casting as currently the addTitleBarComponent method does not work as elegantly as I want it to.
Comment by jwopitz Sunday, April 29, 2007 @ 4:03 pmGive me an old cool bicycle, and I’ll ride around the city for days.
Comment by Retro Bicycles Tuesday, October 23, 2007 @ 6:50 pmHi there,
Useful component and much trickery needed to get it working. Thanks for figuring it all out.
Have just migrated from 2.01 to 3B3 and buttons in titlebar no longer appear – any ideas why?
Cheers, Rich
Comment by Rich Monday, December 31, 2007 @ 8:09 pmThanks for the feedback. I have not tested these guys against FB3. I will take a look into this as soon as I get a chance.
Probably has something to do with a change to their rendering of the Panel’s border area.
Comment by jwopitz Monday, December 31, 2007 @ 8:13 pmJust put an issue on the project’s home
Comment by jwopitz Monday, December 31, 2007 @ 8:15 pmHi,
This is grate. Just the one I was looking for. Thanks
Comment by charitha Friday, February 8, 2008 @ 5:58 amawesome! i was intially overriding the updateDisplayList and createChildren. but your approach makes sense!
can you please post the MXML of the example too… please?
power to flex!
Comment by arun Saturday, March 8, 2008 @ 5:09 am@arun
Comment by jwopitz Saturday, March 8, 2008 @ 5:27 pmFor some reason the view source is not working. Maybe I accidentally deleted the files. But I have the source here – http://code.google.com/p/jwopitz-lib/source/browse/examples/src/PodApplication.mxml
excellent! thanks!
Comment by arun Sunday, March 9, 2008 @ 11:04 amhey, another question: how do i limit the panel drag boundaries, i mean i would like the panel to be dragged only within a specific area in the screen…
thanks in advance…
Comment by arun Monday, March 10, 2008 @ 7:07 pmyou’d need to say use the bounds parameter of Sprite.startDrag(lockCenter, bounds); – http://livedocs.adobe.com/flex/201/langref/flash/display/Sprite.html#startDrag()
Comment by jwopitz Monday, March 10, 2008 @ 7:12 pmHooray for this component! I could not initially get it to work in Flex 3 – the added components were being added, but were very, very tiny and located in the upper-left corner of the panel – but was able to fix it with a small change. In the declaration of the defaultStylesInitialized variable, instead of initializing it to setDefaultStyles(), I set it to false (private static var defaultStylesInitialized:Boolean = false; //setDefaultStyles();), and added the following to the end of the titleBar_onCreationComplete event handler (after the line that reads “creationQueue = [];”):
if(!defaultStylesInitialized) {
defaultStylesInitialized = setDefaultStyles();
}
Thanks for making this available
Comment by Greg Monday, March 24, 2008 @ 5:31 pm~greg
@Greg
Comment by jwopitz Monday, March 24, 2008 @ 5:43 pmWow. Thanks for posting back. I will update the wiki/issues on the google code project to reflect this. I will probably not implement this fix just yet as I want to be able to do further testing, but thanks again for the lead. Nice find!
@Greg
Comment by jwopitz Friday, March 28, 2008 @ 6:35 pmOk I think I fixed that issue. All that is needed is to call the invalidate methods after creationQueue = []; That forces the title bar assets to reposition correctly. Thanks for the find tho. This has been updated in the source as well as the recent swc.
Thanks a ton..!
Comment by Sunil Tuesday, May 27, 2008 @ 3:59 pmmade my day….was looking exactly for this.
hey, how do i set an application with this component?
I get erros like:
“Could not resolve to a component implementation.”
i don’t know where to add the Pod.as file and the mxml….which one is the correct folder strucuture? where both mxml and as file should be? and the package and xmlns tag?
Comment by Carlos Saturday, October 25, 2008 @ 12:27 pm@Carlos
It sounds like you don’t have the Pod.as file in a correct folder structure. Make sure it resides at the com.jwopitz.containers (which means com/jwopitz/containers folder). Your MXML file that would make use of this will reside in the appropriate package of your choice.
Comment by jwopitz Saturday, October 25, 2008 @ 4:53 pmi just can’t setup it…but in your example mxml says:
xmlns:jwolib=”http://www.jwolib.com/2006/mxml”
that’s actually an unreachable page
and the as file says “package com.jwopitz.jwolib”
can’t you send a zip as flex project can be zipped? with all file?
thanks
Comment by Carlos Saturday, October 25, 2008 @ 11:33 pmyes that page is unreachable as it only serves as a means to identify the components when instantiated within the MXML file. If you are trying to use this component within your project, you can either copy the com.jwopitz package over into your project’s source folder or you can use the compiled SWC and place it in your project’s lib folder and make sure the project properties are pointing to that folder. I don’t have an example project to send to you. But you can certainly do a search on how to use SWC libraries in a Flex project.
Comment by jwopitz Sunday, October 26, 2008 @ 4:41 pmhey, thanks. i’m using it correctly now, with the mxml and as files. I needed to copy the as file to my “component” folder and then change the “package component {}” in as file. now it’s working fine.
Comment by Carlos Sunday, October 26, 2008 @ 5:14 pmHi,
I am using the Pod.as and have an issue. If I bind a button in the titleBar to a property. It doesn’t update property. I’ve used visible and enabled property of the button but it doesn’t work correctly. If I add another button in the panel the binding works but not if the button is in the titleBar.
Any idea what could be the problem here?
Thanks.
Comment by Tahir Awan Wednesday, March 18, 2009 @ 5:25 am@Tahir
I am starting to think this has to do with the invalidation/updateDisplayList procedure and how those children get notified of their updates.
Comment by jwopitz Wednesday, March 18, 2009 @ 6:12 amYou are correct but unfortunately I am not yet experience enough in flex to resolve this issue.
there was a typo in my first post. I meant to say that the binding does not update the button in the titleBar properly so it stays enabled (or visible) even if I change the property it is bound to.
Comment by Tahir Awan Wednesday, March 18, 2009 @ 2:45 pmI will get to this here shortly. Please log a bug at the project home page.
Comment by jwopitz Wednesday, March 18, 2009 @ 2:50 pmbinding to enabled property is working ok but problem is with visible.
If I toggle the visible property of button in TitleBar directly, the button show/hide properly.
Comment by Tahir Awan Thursday, March 19, 2009 @ 8:09 amThis as well as your other bug is a known issue. I am in the process of addressing this currently. I will post a new build to the site as soon as it has been thoroughly tested.
Comment by jwopitz Thursday, March 19, 2009 @ 4:07 pm