6 Replies Latest reply on Apr 9, 2007 8:50 AM by Gil1

    Working with states - how to detect changes

    Gil1 Level 1
      I am trying to change the type of content on a container canvas via states and it sort of work. However, it is making the state change when the panel inside TabNavigator is clicked as opposed to when a tab on the TabNavighator is clicked.

      The structure I have is:
      2 main containers inside a Hbox.
      On the left container I have a TabNavigator that includes several panels that each include a list. For one particular tab on the TabNavigator I want to change the state on the right container, when clicking that tab and go back to the base state when clicking on the other tabs.

      What is happening is that the state changes only when I click an item on one of the list inside the the tabNavigator.

      The code looks as:
      ActionScript section:

      [Bindable]
      private var contentList:XMLList;
      private function init():void
      {
      xmlFeed.send();
      }


      private function loaded(e:ResultEvent):void
      {
      contentList = e.result.categories;
      }

      private function changeTabHandler(evt:Event):void
      {
      currentItem.text = evt.currentTarget.selectedItem.label;
      video_stage.stop();
      currentState='';
      if(evt.currentTarget == "Movies") {
      currentItem.text = "Movies";
      } else {

      }
      }

      private function changeHandler(evt:Event):void
      {
      video_stage.stop();
      cover_picture.source = evt.target.selectedItem.imageURL;
      currentItem.text = evt.currentTarget.selectedItem.name;
      }

      mxml section:
      <mx:TabNavigator width="396" height="567" y="10" cornerRadius="0"
      id="tn1" click="changeTabHandler(event)" creationPolicy="all">

      <mx:Panel title="Modules" label="Modules" width="100%" height="100%" layout="absolute"
      fontSize="14" click="currentState=''" >

      <mx:List id="cList1" dataProvider="{contentList..module}" labelField="name" x="0" y="0"
      width="100%" height="100%" change="changeHandler(event)" fontSize="12"></mx:List>
      </mx:Panel>

      <mx:Panel title="Movies" label="Movies" width="80%" height="100%" layout="absolute"
      fontSize="14" click="currentState='video'">
      <mx:List id="cList3" dataProvider="{contentList..movie}" labelField="name" x="0" y="0"
      width="100%" height="100%" change="changeHandler1(event)" fontSize="12"></mx:List>
      </mx:Panel>
      </mx:TabNavigator>
        • 1. Re: Working with states - how to detect changes
          peterent Level 2
          The click event bubbles, so anything inside of the TabNavigator may find its way to this event handler if it is not caught sooner.

          You want the change event, not the click event. From the change event you can tell which tab has been selected.

          private function onTabChange(event:mx.events.IndexChangedEvent) : void
          {
          var child:Container = TabNavigator(event.target).getChildAt( event.newIndex ) as Container;
          ...
          }

          The event.newIndex is the index selected. If need the actual child, the code above gets you that.
          • 2. Re: Working with states - how to detect changes
            Gil1 Level 1
            Peter,

            That was a big help.
            I put

            private function onTabChange(event:mx.events.IndexChangedEvent) : void
            {
            var child:Container = TabNavigator(event.target).getChildAt( event.newIndex ) as Container;
            currentItem.text = child.label;
            var l:int = child.label.length;
            currentTab = child.label.substr(0,l-1);
            var iniListItem:List = child.getChildAt(0) as List;
            }

            and now I get the actual child. However, I don't know how to tell each list to refresh when a user clicks on a tab. (like clear the previous selection on the corresponding list). I still get the warning:

            Data binding will not be able to detect changes to XMLList "module", need an XML instance.

            Gilbert
            • 3. Re: Working with states - how to detect changes
              Gil1 Level 1
              I couldn't find a solution to the warning so, I edited the onTabChange function

              private function onTabChange(event:mx.events.IndexChangedEvent) : void
              {
              var child:Container = TabNavigator(event.target).getChildAt( event.newIndex ) as Container;
              currentItem.text = child.label;
              var l:int = child.label.length;
              currentTab = child.label.substr(0,l-1);
              cover_picture.source = "";
              var iniListItem:List = child.getChildAt(0) as List;
              iniListItem.selectedIndex = -1;
              }

              Now each time a user clicks on a tab no item on the list is selected and no image is displayed. Although it works probably is not the best approach.

              Gilbert
              • 4. Re: Working with states - how to detect changes
                Gil1 Level 1
                The last issue with this is that when I click on the video tab and then on any item on the list, the state changes to be able to display a video instead of a SWFLoader object (image or swf). However, when clicking on a list item I get the following error:

                TypeError: Error #1009: Cannot access a property or method of a null object reference.
                at SPADE/SPADE::changeHandler1()[C:\Documents and Settings\mizrahi\My Documents\Spade\Flex\SPADE.mxml:93]
                at SPADE/__cList3_change()[C:\Documents and Settings\mizrahi\My Documents\Spade\Flex\SPADE.mxml:177]
                at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
                at flash.events::EventDispatcher/dispatchEvent()
                at mx.core::UIComponent/dispatchEvent()[C:\dev\flex_201_gmc\sdk\frameworks\mx\core\UICompone nt.as:8323]
                at mx.controls.listClasses::ListBase/mx.controls.listClasses:ListBase::mouseUpHandler()[C:\d ev\flex_201_gmc\sdk\frameworks\mx\controls\listClasses\ListBase.as:7096]
                at mx.controls::List/mx.controls:List::mouseUpHandler()[C:\dev\flex_201_gmc\sdk\frameworks\m x\controls\List.as:1898]

                For some reason it doesn't like the video_stage.source = evt.target.selectedItem.imageURL; on the ChangeHandler1 function.

                private function changeHandler1(evt:Event):void
                {
                video_stage.source = evt.target.selectedItem.imageURL;
                if(currentTab == null) currentTab ="";
                currentItem.text = currentTab +": " + evt.currentTarget.selectedItem.name;
                }

                • 5. Re: Working with states - how to detect changes
                  peterent Level 2
                  Either video_stage is null, evt is null, evt.target is null, evt.target.selectedItem is null. You should set a break-point in the event handler and examine each of these. Perhaps knowing which one is null will help you figure out what to do.
                  • 6. Re: Working with states - how to detect changes
                    Gil1 Level 1
                    Peter,

                    I know that video_stage is null before I click on the list item that changes to the video state where I then load a video to video_stage.

                    What I don't know is what to do to avoid that error. I mean do I load a dummy video that is replaced when the appropriate video is loaded via video_stage.source?

                    Or is there a better way?

                    Gilbert