PositionedTabNavigator

One of the limitations of the default TabNavigator in the Flex 3.0 framework is that it still only allows for tabs at the top of the component, either aligned on the left, right or in the center by applying the style “horizontalAlign”.

PositionedTabNavigator removes the “horizontalAlign” style, but lets you specify where you want the tabs using the style “tabPosition”.

Valid values are: topLeft, topCenter, topRight, bottomLeft, bottomCenter, bottomRight, leftTop, leftMiddle, leftBottom, rightTop, rightMiddle and rightBottom.

You can also fine tune the tabs position using the style “tabOffset”, as you can with TabNavigator.

A new TabBar was required where a position can be set so knows how to render the tabs. PositionedTabBar takes care of this, and sets its “direction” property automatically when its “position” styles is set. An instance of this in action is included in the example below.

Value values are: top, bottom, left and right.

PositionedTabSkin also checks the “position” style which is set on each PositionTab, and draws the tab with the correct rotation. PositionedTabSkin follows the Halo skin theme.

PositionedTabNavigatorExample (right click for source).

Please post any bugs in the comments and I will do my best to fix them.

65 Responses to “PositionedTabNavigator”

  1. Josh says:

    The source for PositionedTabBar.as and PositionedTab.as seems to be missing:

    “The requested URL /blog/files/flex/positionedTabNavigatorExample/source/[source path] as3/ws/tink/flex/controls/PositionedTabBar.as.html was not found on this server.”

  2. [...] o; Small Toys, Big Stories StyleProxy It was when developing the PositionedTabNavigator that I first came across StyleProxy and there seemed to be very little inf [...]

  3. Tink says:

    My apologies.

    I’m having a problem uploading these files at the moment. There seems to be a problem with the directories. I’ll update the source as soon as this is fixed. For now the ZIP should be complete though.

    • Veerabadrachari R says:

      Hi,

      We are in need of this control. The example link is not working (404 Page not found). Even Google Code check out is not working.

      Could you please provide me the zip link?

      Thanks in advance.

  4. Daniel Spirn says:

    Hi Tink,

    I was doing some sub-classing of the TabNavigator over the past couple of days myself. I took a slight variation for getting my version of the TabBar to work within by extending the TabNavigator, as opposed just copy/pasting all of TabNavigator code.

    You could try.

    public class PositionedTabNavigator extends TabNavigator implements IFocusManagerComponent
    {

    // protected var tabBar : PositionedTabBar; // Not Necessary
    // protected var tabBar : TabBar; // Let the TabNavigator continue to
    // manage the tabBar

    override protected function createChildren():void
    {
    // Here in this overrivde initialize your PositionTabBar first then call the
    //super.createChildren for the TabNavigator
    // You can even leave the type for tabBar as TabBar
    // and write only the code needed for PositionTabBar in
    // PositionedTabNavigator by re-casting the tabBar as PositionTabBar

    if( !tabBar )
    {
    var positionedTabBar: PositionedTabBar = new PositionedTabBar();
    tabBar = TabBar(positionedTabBar);
    tabBar.name = “tabBar”;
    tabBar.focusEnabled = false;
    tabBar.styleName = new StyleProxy( this, tabBarStyleFilters );
    rawChildren.addChild( tabBar );

    if( FlexVersion.compatibilityVersion

  5. Tink says:

    Hey daniel

    I didn’t just copy and paste all the code. If i’d have extending TabNavigator I would have had to call super on a lot of methods that would have done needless calculations which were incorrect.

    Due to the fact that AS 3.0 doesn’t support multiple calls to super, so that methods down the chain can be skipped, the cleanest approach was to extend ViewStack and write my own code. I wanted the component to be efficient so that others can use it as a based to extend.

    The methods that re-writen were:
    get contentWidth()
    get contentHeight()
    get contentX()
    get contentY()
    get tabBarWidth()
    get tabBarHeight()
    createChildren()
    measure()
    updateDisplayList()
    layoutChrome()

    the _tabStyleFilters were also changed

    Methods added were:
    positionTabBar()
    setDefaultStyles()
    styleChanged()

    Methods that remained the same were:
    get baselinePosition()
    commitProperties
    drawFocus()
    adjustFocusRect()
    getTabAt()
    focusInHandler()
    focusOutHandler()
    keyDownHandler()

    Where it made sense to extend the original classes was TabBar and Tab.

  6. PositionedTabNavigator

    使用过Flex 的人应该都用过 TabNavigator 这个组件,但是自带的TabNavigator 组件有个缺点,就是tab只能在组件的上面。为此 Tink 写了一个PositionedTabNavigator 组件,可以定义 tab 的位置,很酷。
    查看…

  7. Chris Bray says:

    Hi Tink,

    Great work — I needed this exact component in an app that I have been developing but have been too busy to try to write one. My laziness has finally paid off!

    btw, the TabNavigator.png file referenced by PositionTabNavigator.as doesn’t appear to be in the source zip.

    Thanks,
    Chris

  8. Chris Bray says:

    Nevermind — I realized that you were probably just reusing the icon file by the same name from the Flex SDK source.

  9. Anonymous says:

    I’ve been searching for some time for hints on how to design a tabbar or tabnavigator extension that allows the labels to be rotated sideways (and tabs positioned on the side). I think adding that is just about all this component needs to be perfect.

  10. Alex says:

    Did anyone figure out how to make the tabs auto-resize based on the label width?

  11. Philipp says:

    Hi Tink,

    I have been trying to use your nice positionedtabbar component. Now, I have the following problem.

    I have a blue canvas and a white area just beneath it in a vertical layout. I would like to put in a tabbar with position = bottom in the white area. I want the selected tab to be of the blue color. However, I get my tabbar with the right color, but then there is a white little gap between my tabbar and the blue canvas above it. It looks like the tabbar paints that little gap itself but I dont know how to remove it. Can you help? I would like to send a screenshot but dont know how to with the comment function.

    Thx in advance
    Philipp

  12. Tink says:

    Hi Philipp

    Try setting ‘paddingBottom’ to 0.

  13. Hi, i have 2 questions
    it`s possible to use another itemRenderers ?
    this component supports dataBinding ?

  14. Tink says:

    Hey Rodislav

    1. Not sure what you mean, neither TabNavigator, not PositionedTabNavigator use itemRenderers.
    2. This should support data binding, but if you do have any problems, please come back with example and I will do my best to address them.

  15. Vitalik says:

    hi Tink. it’s greit job. can you help me and said how can i determinate the gradient background color of non selected tabs and selected tab i try with style properties
    selectedTabTextStyleName and tabStyleName but they work strange …

  16. Tink says:

    Hi Vatalik

    I haven’t checked, but doesn’t it work in the same way as the TabNavigator included in Flex?

    u should be able to get the styling stuff out of the explorer

    http://examples.adobe.com/flex3/consulting/styleexplorer/Flex3StyleExplorer.html#app=a712&e64f-selectedIndex=23&e51-selectedIndex=0&661d-selectedIndex=0

    I’d also suggest you get the source from our google code library. It will be more up-to-date. http://code.google.com/p/tink/

  17. Vitalik says:

    hi Tink! thanks a lot!
    you help me!
    have a nice day=)

  18. dilip says:

    Hi Tink!

    I would like to add icon to the tab and also wanted to change the icon when it selected and on rollover.
    Can you help me?

    Thanks

  19. Tink says:

    To add icons to the tabs you need to specify an icon for the container, it will then be added to the corresponding tab.

  20. jing says:

    Hi Tink,

    This is a great an example. I was trying apply a SelectedTabSkin like:

    selected-up-skin: ClassReference(“handmultimedia.scenario.view.positionedTabNavigator.skins.SelectedTabSkin”);

    selected-down-skin: ClassReference(“handmultimedia.scenario.view.positionedTabNavigator.skins.SelectedTabSkin”);

    selected-over-skin: ClassReference(“handmultimedia.scenario.view.positionedTabNavigator.skins.SelectedTabSkin”);

    SelectedTabSkin can be applied to normal TabNavigator but can not apply on the positionedTabnavigator.

    Any suggestions Tink?

    Thanks.

  21. Tink says:

    Hi jing

    Yyou cannot set a ‘selectedTabSkin’ on a TabNavigator.

    You would need to set the following styles ‘selectedDisabledSkin’, ‘selectedDownSkin’, ‘selectedOverSkin’, ‘selectedUpSkin’ on the ‘firstTabStyleName’, ‘lastTabStyleName’ & ‘tabStyleName’ on the TabNavigator/PositionedTabNavigator.

  22. DDDan says:

    Hey Tink!

    I’m encountering some trouble using your component.
    I have a Canvas, which I use as a Popup. In that Popup there is the PositionedTabNavigator. When I create the popup for the first time the whole application turns blue for about a second, (this standart-flex-preloader-background-blue ;-) ). Only labels and images are in front of that blue area, everything else stays behind. I didn’t find a way to solve this within my code. It only happens when I use PositionedTabNavigator in my Popup.

    I created a TestApp to show you what I mean:

    And my Popup:

    In this testApp the blue screen stays only for some milliseconds, but one can see it. Do you have an idea how to fix this?

    Cheers,
    Dan

  23. DDDan says:

    Oh, my code isn’t visible :-( Well, I can mail it to you, if you want :-)

  24. Tink says:

    Hi DDDan

    Can you upload an example with view source enabled and post a link here?

  25. DDDan says:

    Sure. Here’s the link:

    http://myphotobook.de/__flexdemo/PopupBugfixTest.html

    As i said the blue screen is only visible for some milliseconds in this testApp and only when you click the button for the first time. But in a bigger app it can take much longer.

  26. Tink says:

    i don’t ever see any popup?

  27. DDDan says:

    Yes, that’s right. for testing purposes there’s only an empty PositionedTabNavigator in the popup. That’s probably why you can’t see it. But i hope you can see that short blue flickering when you click on the button!? That’s the problem. Also in this case i didn’t use PopupManager, but simply used addChild. But the flickering is the same.

  28. Tink says:

    Cool I see it.

    I’ll take a look into it, although it may take some time.

  29. DDDan says:

    Hi Tink! Cool, thanks. Do you think you can fix it this week or will it take longer? Cheers, Dan

  30. Tink says:

    I doubt I’ll get to look at it this week :( .

  31. hopF says:

    I noticed a similar problem when using the PositionedTabNavigator in my app. Sometimes the whole page flickers, and many times it seems to affect the page refresh, the whole page turns white and moving the mouse will redraw portions of the page. It happens as soon as one tab is clicked, and using Firefox browser (I’m on Mac), but Safari is fine.

    So I disabled history by setting historyManagementEnabled to false, and that seems to fix the problem.

  32. Tink says:

    Thanks hopF

    I promise I will get round to addressing it.

  33. Hi Tink,

    I just included your component into FlairBuilder and it works great. Except to minor details:

    1. The blue screen that some a seeing is caused by this method call: StyleManager.setStyleDeclaration( “style-name-here”, style, true );

    You basically need to make sure that there is a CSS class defined in your CSS file. Adding CSS styles at runtime causes that CSS refresh of the entire app.

    2. If you set a tabPosition style value difference than the default one on the tabnavigator, and it has no children yet, when children are created they don’t get the initial value, but the default one ‘top’. What I did was to pass the style value upon creation time:

    override protected function createNavItem(
    label:String,
    icon:Class = null):IFlexDisplayObject {
    var navItem:IFlexDisplayObject = super.createNavItem(label, icon);
    var position:String = getStyle( “position” );
    PositionedTab(navItem).setStyle(“position”, position);
    return navItem;
    }

    It may be an hack, but I don’t have time for 100% clean fixes. :-)

    Any thoughts?

  34. arest says:

    Hey Tink,

    seems to be a real great component, but I wasn’t able to manage it to work :(
    I can’ t find any Lib-SWC for download, so that I can include this lib in my project.
    Hope you can help me…

    Greetings and go on :)

  35. Tink says:

    Hi arest

    You can check it out of the SVN repository, the class itself it here

    http://code.google.com/p/tink/source/browse/trunk/ws/tink/flex/containers/PositionedTabNavigator.as

  36. arest says:

    I’m very sorry but I have to disturb you again.
    A checkout isn’t possible, because it says that the google-code server isn’t reachable. Maybe a network thing, I haven’t control of.

    I was downloading the zip-File from the example and add it to my “libs”-Folger in my Flex Project.
    After this I tried to add the “ws”-Folder as a SWC Folder to my Library Paths in the Project properties. (Link type merged into code)
    I also add the namespaces to my application:
    xmlns:containers=”ws.tink.flex.containers.*”
    xmlns:controls=”ws.tink.flex.controls.*”

    But it isn’t possible to add a positionedtabbar in the MXML:
    Could not resolve to a component implementation.

    I used a component from FlexLib, which provides a SWC-File to add to the library. This works but I’m not able to manage the positionedTabBar.

    Where is the mistake?
    Thanks a lot. Also for the fast answer on my first post!

  37. Tink says:

    Hi Arest

    There is no SWC, only SVN. If for some reason Google code was down, you’ll need to try a bit later, as I have no control over there servers.

  38. arest says:

    Hey Tink,

    I’m very sorry, but the SVN from google won’t work here in this enviroment.
    Instead I’ve downloaded the source-package from the example.

    Maybe it’s because of my englisch skills or it’s like “not to see the wood for the trees”, but how can I now use the positionedTabNavigator in my application?
    I tried to add the as3/tink-folder in the libs-folder of my project and also add this to the library Paths and other stuff but nothing will work :(

    Even If I try to add only the example application I get the errors:
    1046: Typ wurde nicht gefunden oder war keine Kompilierungszeit-Konstante: PositionedTabBar. PositionedTabNavigatorExample/src PositionedTabNavigatorExample.mxml line 123

    1046: Typ wurde nicht gefunden oder war keine Kompilierungszeit-Konstante: PositionedTabNavigator. PositionedTabNavigatorExample/src PositionedTabNavigatorExample.mxml line 123

    in english:
    Type couldn’t be found or wasn’t a “compiling-time-constant”

    I’m very sorry if I bother you, but I don’t know who I can ask :(

  39. Tink says:

    The source package just has the code for the example, but not for the PositionedTabNavigator, and the classes it uses. They must be download from the SVN repository.

  40. arest says:

    It was like“not to see the wood for the trees”.
    I always try to add the folder to the library paths, but it’s a source path :)

    Well, then I was happy that I can use the PositionedTabNavigator but know there is the issue, that it won’t work with the Yahoo-FlexSkin.
    Is this a known issue or is there a workaround?

  41. Franto says:

    Hey Tink,

    I have same problem as Cristian in 2) problem with tabPosition with new Canvas added to PositionedTabNavigator. But Cristian hack helps me. It needs to be added to PositionedTabBar. :)

    Hope we will see in Brighton next week :)

  42. Zdenek K. says:

    setting third argument of all StyleManager.setStyleDeclaration calls to false removes the “flashing”. Thanks to Cristian Pascu for the post.

  43. Alex Araujo says:

    Yes, Cris Pascu hack worked nice, thanks Cris. BTW, this is the best Flex Vertical TabNavigator implementation that I have seen. Very thanks Tink!

  44. Eyal says:

    Hi Tink,
    I’m having some size issues when setting the tabPosition to left/right. The tabs seems to take much more space than actually required. I think it has something to do with the fact you set the explicit size of the tab (PositionedTabNavigator.updateDisplayList).

    The default direction of the tabs is horizontal and they are set with explicit width there. When the direction is changed they already were set with explicit width so they stick with it..

    Any thoughts?

    Eyal

  45. Tink says:

    Hi Eyal

    Can you make an example, make sure view source is enabled and then give me a link to it.

  46. Pierre says:

    Hey Tink!

    I’m very new to Flex and I’m not sure how to use your component (PositionedTabNavigator). Do I have to copy your .as file in my project?

    If so, is that all I need to do?

    Thank you

  47. Cristian Pascu says:

    Hi Pierre,

    Yes, that should be all. And then you just use the class in a MXML file. I guess that first of all you need to get used to how Flex works, which are the differences and similarities between MXML files and AS files. Also, you need to know how to import an AS class in MXML by defining the namespace for the package of that AS file in the MXML.

    Experiment, the compiler will tell you when you do something wrong! Good luck.

  48. Tink says:

    Hi Pierre

    If you view the source you should se a tree on the top left. The first node is named ‘[source path] as3′.

    You need to have all the files found retaining that directory struction in that folder somewhere in your project either by

    1. compiling a SWC and adding the SWC to you project (easiest way to do this is create a library project, and add the files to that, the add the library to your Flex project.
    2. adding them so a folder on your HD and adding that folder as a ‘source path’ to your Flex project
    3. or coping them directly into your src folder of you Flex project

    Hope that helps

  49. Pierre says:

    Hi TInk|

    Tanx, thats all working fine!

    But I got one more question for you!

    Is it possible that the Event MouseEvent.CLICK is not trhown when you click on the tabs of the positionedtabnavigator ?

  50. Ilan says:

    The solution for the flickering issue can be found here:
    ======================

    http://tikalk.tikalknowledge.com/flex/newly-created-style-declaration-may-cause-a-performance-hit

    in short, you should declare the style selectors required for this component in advance, even empty ones (in css for example) to avoid creating them by the setStyleDeclaration used by this component.

    place the following in your css, and the flicker is gone:

    PositionedTabNavigator{}
    PositionedTabBar{}
    PositionedTab{}

  51. Alexander says:

    Hi
    Thanks for the component.
    Want to submit fix for the issue “Styles are not applied to dynamically added children of PositionedTabNavigator”.

    This should go to PositionedTabBar c’tor :

    addEventListener(ChildExistenceChangedEvent.CHILD_ADD,function (e:ChildExistenceChangedEvent):void{
    (PositionedTab(e.relatedObject)).setStyle(“position”,getStyle( “position” ))
    });

  52. Mukund says:

    Hi Tink,

    Thansks for the component, I am using it. I wanted to have a multiline text. I searched and founds something from
    http://blogs.adobe.com/aharui/2007/04/multiline_buttons.html

    Basically, I had to override the createchildren method .

    I have it as follows
    override protected function createChildren():void
    {
    if (!textField)
    {
    textField = new UITextField();
    textField.styleName = this;
    addChild(DisplayObject(textField));
    }
    super.createChildren();
    textField.multiline = true;
    textField.wordWrap = true;
    }

    I dont’ see that the multiline and wordwrap working .The tab bar extends itself. any idea how to get a multiline label in your component?

  53. [...] AlertTabNavigator extends PositionedTabNavigator. [...]

  54. It seems that the PositionedTabNavigator example is gone??

    • Tink says:

      Hey Tom

      Yeah unfortunately my site was hacked and all the examples were lost. If you can use spark I would recommend using a Navigator with a ToggleButtonBar connected to it inside the skin.

  55. wincheer says:

    Hi Tink,

    Thansks for your great job.

    when i remove a tab from PositionedTabNavigator,it throw a exception as bellow :
    TypeError: Error #1009: 无法访问空对象引用的属性或方法。
    at ws.tink.mx.skins.halo::PositionedTabSkin/updateDisplayList()[/Users/tinktink/Documents/tink/libraries/Tink Google Code/flex4/mx/src/ws/tink/mx/skins/halo/PositionedTabSkin.as:182]

    – i’m a chinese ,the tips means can’t access property or method of a null object

    how can i remove a tab ?

    thanks a lot

    • Tink says:

      Thanks, I’ve put in an untested fix for this in the flex 4 libs. That said if your using Flex 4 or above I really would recommend looking at the Navigator container instead. You can then create a skin for it and include a TabBar where ever you want.

  56. Tom says:

    Can you please fix the link to the example. Can’t see it any more….

    Thanks,
    Tom

  57. Mobeen says:

    Could you please send me the URL for the demo or source code.

    Thanks,
    Mobeen Zar

  58. typhoid says:

    positionedtabnavigator+supertabnavigator=ultimatetabnavigator

Leave a Reply