Create and apply view states

The properties, styles, event handlers, and components that you define for an application or custom component specify its default view state. Any additional view state specify changes to the default view state.

For each additional view state, define overrides of the default view state. Overrides modify the properties, styles, and event handlers for a component, add a component to a view state, remove a component from a view state, or change the parent container of a component in a view state.

Creating view states

Consider the following when you define a view state.

  • Define view states at the root of an application or at the root of a custom component; that is, as a property of the Application container of an application file, or of the root tag of an MXML component.

  • Define states by using a component’s states property, normally by using the <s:states> tag in MXML.

  • Populate the states property with an Array of one or more State objects, where each State object corresponds to a view state.

  • Use the name property of the State object to specify its identifier. To change to that view state, you set a component’s currentState property to the value of the name property.

    Note: View state definitions are processed at compile time. Therefore, you cannot use data binding to set the State.name property because data binding occurs at run time.

The following MXML code shows this structure:

<s:Application>  
    <!-- Define the view states.  
        The <s:states> tag can also be a child tag of  
        the root tag of a custom component.  
    --> 
    <s:states> 
        <s:State name="State1"/> 
        <s:State name="State2"/> 
        <s:State name="State3"/> 
        . 
        . 
    </s:states> 
    <!-- Application definition. --> 
    . 
    . 
</s:Application>

The default view state is defined as the first view state in the <s:states> Array. An application uses the default view state when it loads. The name of the default view state is not reserved, so it is not required to be "default".

Changing view state

The UIComponent class defines the currentState property that you use to set the current view state. When the application starts, the default value of the currentState property is the name of the first view state defined by the <s:states> tag.

In the next example, you use a Button control to set the currentState property of the Application object to "State1" or "State2", the names of a view state specified by the <s:State> tag:

<s:Button id="b1" label="Change to State 1" click="currentState='State2';"/> 
<s:Button id="b2" label="Change to the default" click="currentState='State1';"/>

The second button in the previous example sets the current state to "State1" so that you can switch back to the default view state from "State2".

You can also set the currentState property to an empty String to set it to the default state, as the following example shows:

<s:Button id="b2" label="Change to the default" click="currentState='';"/>

You can change a component’s view state by calling the setCurrentState() method of the UIComponent class. Use this method when you do not want to apply a transition that you have defined between two view states. For more information on transitions, see Transitions.

Setting properties, styles, and events for a view state

Define state-specific property and style values by using the dot (.) operator with any writable MXML tag attribute. The dot notation has the following format:
propertyOrStyleName.stateName
For example, specify the value of the label property of a Button control for the default view state and for one additional view state, as the following example shows:
<s:Button label="Default State" label.State2="New State"/>

The value of the label property qualified by “State2” specifies the value for the property in that view state. The unqualified property definition, the one that omits the dot notation, defines the value of the property for all view states where you do not explicitly define an override.

Do not define an override for every property, style, and event for all view states. Only define the override for those view states where you want to change the value of the element.

You can also use child tags with the dot notation to define property overrides, as the following example shows for the b1 button control:

<?xml version="1.0"?>
<!-- states\StatesSimpleChildTags.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:states>
        <!-- Define the new view states. -->
        <s:State name="default"/>
        <s:State name="NewButton"/>
    </s:states>    
 
    <s:VGroup >
        <s:HGroup>
            <!-- Disable Button in the NewButton view state. -->
            <s:Button id="b1">
                <s:label>Click Me</s:label>
                <s:label.NewButton>Disabled</s:label.NewButton>
                <s:enabled.NewButton>false</s:enabled.NewButton>
            </s:Button> 
            
            <!-- Add a new child control to the VBox. -->
            <s:Button id="b2" label="New Button"
                includeIn="NewButton"/>
        </s:HGroup>

        <!-- Define Button control to switch to NewButton view state. -->
        <s:Button label="Change to NewButton state" 
            click="currentState='NewButton';"/>            

        <!-- Define Button control to switch to default view state. -->
        <s:Button label="Change to default view state" 
            click="currentState='default';"/>
    </s:VGroup>    
</s:Application>

The executing SWF file for the previous example is shown below:

To clear the value of a property in a view state, set the property to the value @Clear(), as the following example shows:
<s:Button color="0xFF0000" color.State1="@Clear()"/>

For a style property, setting the value to @Clear() corresponds to calling the clearStyle() method on the property.

Use the dot operator to change the event handler for a specific view state, as the following example shows. In this example, the handler for the click event for button b1 is set based on the view state:

<?xml version="1.0"?>
<!-- states\StatesEventHandlersSimple.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:states> 
        <s:State name="default"/> 
        <s:State name="logout"/> 
    </s:states> 
 
    <s:VGroup >
        <s:Button id="b1" label="Click Me" 
            click="ta1.text='hello';"
            click.logout="ta1.text='goodbye'"/>
        <s:TextArea id="ta1" height="100" width ="50%"/>
 
        <s:Button label="Default State" 
            click="currentState='';"
            enabled="false"
            enabled.logout="true"/>
        <s:Button label="Logout State" 
            click="currentState='logout';"
            enabled="true"
            enabled.logout="false"/>
    </s:VGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

Adding or removing components for a view state

Use the includeIn and excludeFrom MXML attributes to specify the set of view states in which a component is included, where:

  • The includeIn attribute specifies the list of view states where the component appears. This attribute takes a comma delimited list of view state names, all which must have been previously declared in the <s:states> Array.

  • The excludeFrom attribute specifies the list of view states where the component is omitted. This attribute takes a comma delimited list of view state names.

  • The excludeFrom and includeIn attributes are mutually exclusive; it is an error to define both on a single MXML tag.

The following example uses view states to add components to the application based on the current state:

<?xml version="1.0"?>
<!-- states\StatesSimpleIncExc.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark"> 

    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <s:states> 
        <s:State name="default"/> 
        <s:State name="addCheckBox"/> 
        <s:State name="addTextInput"/> 
        <s:State name="addCheckBoxandButton"/> 
    </s:states> 
     
    <s:HGroup >
        <!-- Included in the addCheckBox and addCheckBoxandButton view states. --> 
        <s:CheckBox id="myCB" label="Checkbox" 
           includeIn="addCheckBox, addCheckBoxandButton"/>
     
        <!-- Included in the addTextInput view state. --> 
        <s:TextInput id="myTI" 
           includeIn="addTextInput"/>    

        <!-- Included in the addCheckBoxandButton view state. --> 
        <s:Button id="myB" 
           includeIn="addCheckBoxandButton"/>
        
        <!-- Exclude from addTextInput view state. --> 
        <s:TextArea text="Exclude from addTextInput" 
            excludeFrom="addTextInput"/>        
    </s:HGroup>

    <s:HGroup>
        <s:Button label="Add CheckBox" 
            click="currentState='addCheckBox'"/> 
        <s:Button label="Show Textinput Only" 
            click="currentState='addTextInput'"/>    
        <s:Button label="Add CheckBox and Button" 
            click="currentState='addCheckBoxandButton'"/> 
        <s:Button label="Default" 
            click="currentState='default'"/> 
    </s:HGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

You can specify the includeIn and excludeFrom attributes on any MXML object within an MXML document, with the exception of the following tags:
  • The root tag of an MXML document, such as the Application tag or the root tag in an MXML component.

  • Tags that represent properties of their parent tag. For example, the <s:label> tag of the <s:Button> tag.

  • Descendants of the <fx:XML>, <fx:XMLList>, or <fx:Model> tags.

  • Any language tags, such as the <fx:Binding>, <fx:Declarations>, <fx:Metadata>, <fx:Script>, and <fx:Style> tags.

Restriction on modifying container children when using view states

When you use view states to control the children of a container, do not add or remove container children, or change the order of children in the container, at runtime. For example, the following container defines a Button control that appear only in State2:

<s:Group id="myGroup"> 
    <s:Button/> 
    <s:Button includeIn="State2"/> 
    <s:Button/> 
</s:Group>

The view states infrastructure relies on the structure of the container as defined by the MXML file. Changing the child order of the container at runtime can cause your application to fail. Therefore, do not call the addElement(), removeElement(), setElementIndex() method on the Group container at runtime, or any other method that changes the child order of the container.

Changing the parent of a component

A view state can change the parent container of a component. Changing the parent container of a component is called reparenting the component.

Use the <fx:Reparent> tag to change the parent container of a component. The <fx:Reparent> tag has the following syntax:
<fx:Reparent target="targetComp" includeIn="stateName">

The target property specifies the target component, and the includeIn property specifies a view state. When the current view state is set to stateName, the target component becomes a child of the parent component of the <fx:Reparent> tag. You can think of the <fx:Reparent> tag as a placeholder for the component for a specific view state.

You can use the <fx:Reparent> tag in any component that can hold a child component, and the child can use the includeIn or excludeFrom keywords.

The following example uses the <fx:Reparent> tag to switch a Button control between two Panel containers:
<?xml version="1.0" encoding="utf-8"?> 
<!-- states\NewStatesReparent.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark"> 
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <s:states> 
        <s:State name="Parent1"/> 
        <s:State name="Parent2"/> 
    </s:states> 
    
    <s:HGroup>
        <s:Panel id="Panel1" 
            height="100" width="100"
            title="Panel 1"> 
            <s:Button id="setCB" includeIn="Parent1"/> 
        </s:Panel> 
        <s:Panel id="Panel2" 
            height="100" width="100"
            title="Panel 2"> 
            <fx:Reparent target="setCB" includeIn="Parent2"/> 
        </s:Panel>     
    </s:HGroup>
 
    <s:HGroup>
        <s:Button label="Parent 1" 
            click="currentState='Parent1'" 
            enabled.Parent1="false"/> 
        <s:Button label="Parent 2"
            click="currentState='Parent2'" 
            enabled.Parent2="false"/> 
    </s:HGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

Two <fx:Reparent> tags cannot target the same component for the same view state. That means a component can only have a single parent in each view state.

Controlling when to create added children

When you remove a component as part of a change of view state, you remove the component from the application’s display list, which means that it no longer appears on the screen. Even though the component is no longer visible, the component still exists and you can access it from within your application.

When you add a component as part of a change of view state, you can either create the component before the first change to the view state, or create it at the time of the first change. If you create the component before the first change, you can access the component from within your application even though you have not yet changed view states. If you create the component when you perform the first change to the view state, you cannot access it until you perform that first change.

By default Flex creates container children when they are first required as part of a change of view state. However, if a child requires a long time to create, users might see a delay when the view state changes. Therefore, you can choose to create the child before the state changes to improve your application’s apparent speed and responsiveness.

Regardless of when you create a component, the component remains in memory after you change out of the view state that creates it. Therefore, after the first change to a view state, you can always access the component even if that view state is no longer the current view state.

The specification of when the child is created is called its creation policy. For more general information on creation policies and controlling how children are created, see Improving startup performance.

Use the itemCreationPolicy property to specify the creation policy. The itemCreationPolicy property supports the following values:

deferred
Creates the component instance when it is first added by a change to the view state. This is the default value.

immediate
Creates the component instance at application startup.

The following example uses the Immediate view state to add a Button control named newButtonImmediate. You set the itemCreationPolicy property for this button to immediate to create the button at application startup. Therefore, the application can access it to set its label property before it switches to the Immediate view state.

The application also uses the Deferred view state to create the button named newButtonDeferred with the itemCreationPolicy property set to deferred. Therefore, this button is created when you first change to the Deferred view state, and you cannot access it until after the first switch to the Deferred view state:

<?xml version="1.0"?>
<!-- states\StatesCreationPolicy.mxml  -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark"
    creationComplete="initButton();">
    
    <fx:Script>
        <![CDATA[

            // Because the Immediate view state creates the Button control
            // at application startup, you can access the control to
            // set the label before the first switch 
            // to the Immediate view state.
            public function initButton():void {
                newButtonImmediate.label="Immediate Button";

                // Uncommenting this line to access the label causes a 
                // Run Time Exception because newButtonDeferred does not exist yet.
                // newButtonDeferred.label="Deferred Button";
            }            
        ]]>
    </fx:Script>

    <s:states>
        <s:State name="default"/>
        <s:State name="Immediate"/>
        <s:State name="Deferred"/>
    </s:states>    
    
    <s:Panel id="myPanel" 
        title="Static and dynamic states" 
        width="300" height="150">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
        <!-- Create the Button control at application startup. -->
        <s:Button id="newButtonImmediate" 
            includeIn="Immediate" 
            itemCreationPolicy="immediate"/>

        <!-- Create the Button control when you switch to this view state. -->
        <s:Button id="newButtonDeferred" 
            label="Deferred button" 
            includeIn="Deferred" 
            itemCreationPolicy="deferred"/>
            
        <!-- Change to the Immediate view state. -->
        <s:Button label="Change to Immediate state" 
            click="currentState='Immediate';"/>
            
        <!-- Change to the Deferred view state. -->
        <s:Button label="Change to Deferred state" 
          click="currentState='Deferred';"/>

        <!-- Change to the default view state. -->
        <s:Button label="Change to default state" 
          click="currentState='default';"/>
    </s:Panel>
</s:Application>

The executing SWF file for the previous example is shown below:

Controlling caching of objects created in a view state

A change to a view state can cause Flex to create an object. By default, after Flex creates the object, the object is cached indefinitely, even after you switch to another view state. The item is cached even if the destination view state excludes the object.

Use the itemDestructionPolicy attribute with the includeIn and excludeFrom attributes configure Flex to completely destroy the object when leaving a view state, including deleting it from the cache. Typically it is more efficient to allow items to be cached because it improves performance when switching back to the view state that created the object, or to a view state that uses the object. However your application might define a view state that is rarely used, and you do not want to allocate memory for caching the object.

You can use the itemDestructionPolicy attribute on any object in MXML that supports the includeIn and excludeFrom attributes. The possible values for itemDestructionPolicy are never (default) and auto.

The value of never specifies that the object is cached indefinitely. A value of auto means that the object is destroyed when leaving a view state where the object exists. The following example sets the attribute to auto:

<s:TextInput includeIn="newTextInput" itemDestructionPolicy="auto"/>

Defining view state groups

The stateGroups attribute of the <s:States> tag lets you group one or more states together. For example, if multiple components appear in the same set of view states, create a view state group that contains all these view states. Then, when you set the currentState property to any view state in the group, the components appears.

In the following example, the CheckBox control named myCB appears when you change to any view state in Group1:

<?xml version="1.0"?>
<!-- states\StatesSimpleGroups.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark"> 
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    
    <s:states> 
        <s:State name="default"/> 
        <s:State name="addCheckBox" stateGroups="Group1"/> 
        <s:State name="addTextInput"/> 
        <s:State name="addCheckBoxandButton" stateGroups="Group1"/> 
    </s:states>
      
    <s:HGroup>
        <!-- Included in the addCheckBox and addCheckBoxandButton view states. --> 
        <s:CheckBox id="myCB" label="Checkbox" 
            includeIn="Group1"/>
     
       <!-- Included in the addTextInput view state. --> 
       <s:TextInput id="myTI" 
            includeIn="addTextInput"/>    

        <!-- Included in the addCheckBoxandButton view state. --> 
        <s:Button id="myB" 
           includeIn="addCheckBoxandButton"/>
        
        <!-- Exclude from addTextInput view state. --> 
        <s:TextArea text="Exclude from addTextInput" 
           excludeFrom="addTextInput"/>             
    </s:HGroup>

    <s:HGroup>
        <s:Button label="Add CheckBox" 
            click="currentState='addCheckBox'"/> 
        <s:Button label="Add Textinput" 
            click="currentState='addTextInput'"/>    
        <s:Button label="Add Group 1" 
            click="currentState='addCheckBoxandButton'"/> 
        <s:Button label="Default" 
            click="currentState='default'"/>
    </s:HGroup> 
</s:Application>

The executing SWF file for the previous example is shown below:

Example: Login form application

The following example creates the Login and Register forms shown in About view states. This application has the following features:

  • When the user clicks the Need to Register LinkButton control, the event handler for the click event sets the view state to Register.

  • The Register state code adds a TextInput control, changes properties of the Panel container and Button control, removes the existing LinkButton controls, and adds a new LinkButton control.

  • When the user clicks the Return to Login LinkButton control, the event handler for the click event resets the view state to the default view state.

Note: For an example that adds a transition to animate the change between view states, see Example: Using transitions with a login form.
<?xml version="1.0"?>
<!-- states\LoginExample.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <!-- The Application class states property defines the view states.-->
    <s:states>
        <s:State name="default"/>    
        <s:State name="Register"/>
    </s:states>

    <!-- Set title of the Panel container based on the view state.-->
    <s:Panel id="loginPanel" 
        title="Login" title.Register="Register">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>        

        <s:Form id="loginForm">
            <s:FormItem label="Username:">
                <s:TextInput/>
            </s:FormItem>
            
            <s:FormItem label="Password:">
                <s:TextInput/>
            </s:FormItem>
            
            <s:FormItem id="confirm" label="Confirm:" includeIn="Register">
                <!-- Add a TextInput control to the form for the Register view state. -->           
                <s:TextInput/>
            </s:FormItem>            
            
            <s:FormItem>            
                <!-- Use the LinkButton to change view state.-->
                <s:HGroup>
                    <!-- Set label of the control based on the view state.-->
                    <mx:LinkButton id="registerLink"
                        label="Need to Register?" 
                        label.Register="Return to Login"
                        click="currentState='Register'"
                        click.Register="currentState=''"/>
                    <s:Button id="loginButton" 
                        label="Login" label.Register="Register"/>
                </s:HGroup>
            </s:FormItem>            
        </s:Form>
    </s:Panel>
</s:Application>

The executing SWF file for the previous example is shown below:

Example: Controlling layout using view states groups

In this example, you define an application with three Panel containers and three view states, as the following example shows:

View full size graphic
A.
Default view state

B.
One view state

C.
Two view state

To change view state, click the Panel container that you want to display in the expanded size. For a version of this example that adds a transition to animate the view state change, see Defining transitions.

<?xml version="1.0"?>
<!-- states/ThreePanel.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" width="400">

    <!-- Define the two view states, in addition to the default view state.-->
    <s:states>
        <s:State name="default"/>
        <s:State name="One"/>
        <s:State name="Two"/>
    </s:states>

    <!-- Define the Group container holding the three Panel containers.-->
    <s:Group width="100%" height="100%">
        <s:Panel id="p1" title="One" 
                x="0" y="0" 
                x.One="110" y.One="0" 
                x.Two="0" y.Two="0" 
                width="100" height="100"
                width.One="200" height.One="210"
                width.Two="100" height.Two="100"
                click="currentState='One'">
            <s:Label fontSize="24" text="One"/>
        </s:Panel>
        
        <s:Panel id="p2" title="Two" 
                x="0" y="110" 
                x.One="0" y.One="0" 
                x.Two="110" y.Two="0" 
                width="100" height="100"
                width.One="100" height.One="100"
                width.Two="200" height.Two="210"
                click="currentState='Two'">
            <s:Label fontSize="24" text="Two"/>
        </s:Panel>
        
        <s:Panel id="p3" title="Three" 
                x="110" y="0" 
                x.One="0" y.One="110" 
                x.Two="0" y.Two="110" 
                width="200" height="210" 
                width.One="100" height.One="100" 
                width.Two="100" height.Two="100" 
                click="currentState='default'">
            <s:Label fontSize="24" text="Three"/>
        </s:Panel>
    </s:Group>
</s:Application>

The executing SWF file for the previous example is shown below:

You can optimize this application by using view state groups, as the following example shows:

<?xml version="1.0"?>
<!-- states/ThreePanelGroups.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" width="400">

    <!-- Define the two view states, in addition to the default state.-->
    <s:states>
        <s:State name="default" stateGroups="grpDefaultOne, grpDefaultTwo"/>
        <s:State name="One" stateGroups="grpDefaultOne, grpOneTwo "/>
        <s:State name="Two" stateGroups="grpDefaultTwo, grpOneTwo"/>
    </s:states>

    <!-- Define the Group container holding the three Panel containers.-->
    <s:Group width="100%" height="100%">
        <s:Panel id="p1" title="One" 
                x.grpDefaultTwo="0" y.grpDefaultTwo="0" 
                x.One="110" y.One="0" 
                width.grpDefaultTwo="100" height.grpDefaultTwo="100"
                width.One="200" height.One="210"
                click="currentState='One'">
            <s:Label fontSize="24" text="One"/>
        </s:Panel>
        
        <s:Panel id="p2" title="Two" 
                x="0" y="110" 
                x.One="0" y.One="0" 
                x.Two="110" y.Two="0" 
                width.grpDefaultOne="100" height.grpDefaultOne="100"
                width.Two="200" height.Two="210"
                click="currentState='Two'">
            <s:Label fontSize="24" text="Two"/>
        </s:Panel>
        
        <s:Panel id="p3" title="Three" 
                x="110" y="0" 
                x.grpOneTwo="0" y.grpOneTwo="110" 
                width="200" height="210" 
                width.grpOneTwo="100" height.grpOneTwo="100" 
                click="currentState='default'">
            <s:Label fontSize="24" text="Three"/>
        </s:Panel>
    </s:Group>
</s:Application>

The executing SWF file for the previous example is shown below:

Using view state events

When a component’s currentState property changes, the State object for the states being exited and entered dispatch the following events:

enterState
Dispatched after a view state is entered. Dispatched by a State object and by a component.

exitState
Dispatched when a view state is about to be exited. Dispatched by a State object before it is exited, and by a component before it exits the current view state.

The component on which you modify the currentState property to cause the state change dispatches the following events:

currentStateChanging
Dispatched when the view state is about to change. It is dispatched by a component after its currentState property changes, but before the view state changes. You can use this event to request any data from the server required by the new view state.

currentStateChange
Dispatched after the view state has completed changing. It is dispatched by a component after its currentState property changes. You can use this event to send data back to a server indicating the user’s current view state.

The following example uses the enterState and exitState events to update two TextArea controls with the name of the new state and of the old state:
<?xml version="1.0"?>
<!-- states\StatesSimpleEvent.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark"
    height="450">

    <s:states>
        <!-- Define the new view states. -->
        <s:State name="default"
            enterState="MyEnterTA.text = 'Enter state: default';"
            exitState="MyExitTA.text = 'Exit state: default';"/>
        <s:State name="NewButton"
            enterState="MyEnterTA.text = 'Enter state: NewButton';"
            exitState="MyExitTA.text = 'Exit state: NewButton';"/>
    </s:states>    

    <s:VGroup id="g1">
        <s:HGroup>
            <s:Button id="b1" label="Click Me"
                enabled.NewButton="false"/>
            <s:Button id="b2" label="New Button"
                includeIn="NewButton"/>
        </s:HGroup>

        <s:Button label="Change to NewButton state" 
            click="currentState='NewButton';"/>            
        <s:Button label="Change to default view state" 
            click="currentState='default';"/>

        <s:TextArea id="MyEnterTA"/>
        <s:TextArea id="MyExitTA"/>
        
    </s:VGroup>    
</s:Application>

The executing SWF file for the previous example is shown below: