Search code examples
apache-flexevent-listenertabnavigator

Flex TabNavigator Tab Buttons not firing Click Event


I have a TabNavigator that i'm trying to make work like Firefox in that the last tab is a special "+" tab that adds a new tab to the control. To do this I add an event handler to the very first tab's button which I get using tabNavigator.getTabAt(0).addEventListener(MouseEvent.CLICK, clickFunction, false, int.MAX_VALUE, false). I set the priority to int.MAX_VALUE so my method should be the very first one called and then can stop other handlers from being called using stopImmediatePropagation().

My problem is that every now and then my click handler isn't called and instead the normal logic runs and the "+" tab is switched to.

Code for CustomTab (I've removed a lot of proprietary code):

private var addTab:Function = null;
private var tabCreationAllowed:Boolean = true;

private function onCreationCompleted():void {
    var tabButton:Button = getTab(0);
    Container(getChildAt(0)).setStyle("closable", false);
    tabButton.addEventListener(MouseEvent.CLICK, clickFunction, false, int.MAX_VALUE, false);
    tabButton.addEventListener(MouseEvent.DOUBLE_CLICK, function(event:MouseEvent):void {event.stopImmediatePropagation(); }, false, int.MAX_VALUE, false);
}

private function clickFunction(event:MouseEvent):void {
    event.stopImmediatePropagation();
    if (this.tabCreationAllowed && (this.addTab != null) && (event.eventPhase == EventPhase.AT_TARGET)) {
        this.tabCreationAllowed = false;
        this.addTab();
        var $this:CustomTab = this;
        setTimeout(function ():void {
            $this.tabCreationAllowed = true;
        }, 1500);
    }
}

Solution

  • After trying many different things, best I can tell the problem is that the TabBar that the TabNavigator uses to create the tab buttons can switch around what button does what (possibly even removing and adding) but only when adding or removing tabs. To solve this problem I store the "+" button in a class variable. I then override all the add and remove methods. On each of them I call a method that removes all event listeners from the button, if I have one, set the variable to the last tab's button (which is the "+" tab) and then re-adds the listeners.

    A cut down version of the final code:

    private var addTab:Function = null;  
    private var tabCreationAllowed:Boolean = true;  
    private var addTabButton:Button = null;
    
    private function prerAddTabButton():void {
        if (addTabButton != null) {
            addTabButton.removeEventListener(MouseEvent.CLICK, clickFunction);
            addTabButton.removeEventListener(MouseEvent.DOUBLE_CLICK, doubleClickFunction);
        }
        addTabButton = getTabAt(numChildren - 1);
        addTabButton.addEventListener(MouseEvent.CLICK, clickFunction, false, int.MAX_VALUE, false);  
        addTabButton.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickFunction, false, int.MAX_VALUE, false);  
    }
    
    private function onCreationCompleted():void {  
        var tabButton:Button = getTab(0);  
        Container(getChildAt(0)).setStyle("closable", false);
        prerAddTabButton();
    }  
    
    private function doubleClickFunction(event:MouseEvent):void {
        event.stopImmediatePropagation(); 
    }
    
    private function clickFunction(event:MouseEvent):void {  
        event.stopImmediatePropagation();  
        if (this.tabCreationAllowed && (this.addTab != null) && (event.eventPhase == EventPhase.AT_TARGET)) {  
            this.tabCreationAllowed = false;  
            this.addTab();  
            var $this:CustomTab = this;  
            setTimeout(function ():void {  
                $this.tabCreationAllowed = true;  
            }, 1500);  
        }  
    }