The Spark SkinnablePopUpContainer container

You use the SkinnablePopUpContainer container as a pop-up in your application. One typical use for a SkinnablePopUpContainer container is to open a simple window in an application, such as an alert window, to indicate that the user must perform some action.

The SkinnablePopUpContainer container can be modal or nonmodal. A modal container takes all keyboard and mouse input until it is closed. A nonmodal container lets other components accept input while the pop-up window is open.

Flex also defines the Spark TitleWindow container that you can use as a pop-up. A TitleWindow container consists of a title bar, a caption and status area in the title bar, a border, content area, and optional close button. Users can drag the TitleWindow container to move it around the application window. For more information, see The Spark TitleWindow container.

Unlike the TitleWindow container, the SkinnablePopUpContainer does not support dragging. It is a light-weight container that you use for simple pop-ups. You can define a custom skin class to control the visual aspects of the SkinnablePopUpContainer, such as the transitions and effects that play when the container opens and closes.

Creating a simple Spark SkinnablePopUpContainer container

The SkinnablePopUpContainer container appears as a pop-up window on top of its parent container. Therefore, you do not create a SkinnablePopUpContainer container as part of the normal MXML layout code of its parent container.

Instead, you can define the SkinnablePopUpContainer container as a custom MXML component in an MXML file. In the following example, you define it in the file MyAlertPopUp.mxml:
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\myComponents\MyAlertPopUp.mxml -->
<s:SkinnablePopUpContainer xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">

    <s:Panel title="My Alert Panel">
        <s:VGroup width="100%" horizontalAlign="center"
            paddingTop="20" gap="20">
                <s:Label text="Your custom alert box"/>
                <s:Button label="OK" click="close();"/>
        </s:VGroup>
    </s:Panel>

</s:SkinnablePopUpContainer>

The MyAlertPopUp.mxml component creates a SkinnablePopUpContainer that contains a Panel container. Notice that the Button control calls the close() method to close the pop-up.

At runtime, you create an instance of the SkinnablePopUpContainer in ActionScript, then call the following methods of the SkinnablePopUpContainer class to open and close it:
  • open()

    Opens a SkinnablePopUpContainer container. The open() method takes two arguments: the first specifies the parent container of the SkinnablePopUpContainer container, and the second specifies if the container is modal.

    Opening the SkinnablePopUpContainer container dispatches the open event.

  • close()

    Closes a SkinnablePopUpContainer container. The close() method takes two arguments: the first specifies whether the container passes back any data to the main application, and the second specifies an object containing the returned data.

    Closing the SkinnablePopUpContainer container dispatches the close event.

The following example shows the main application file that uses MyAlertPopUp.mxml:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkSkinnablePopUpContainerComponents.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">
    
    <fx:Script>
        <![CDATA[
            // Import the MyAlertPopUp class.
            import myComponents.MyAlertPopUp;
            
            // Create an instance of MyAlertPopUp.
            public var alertDB:MyAlertPopUp = new MyAlertPopUp();
        ]]>
    </fx:Script>
        
    <!-- Open the MyAlertPopUp instance. -->
    <s:Button label="Open Alert" click="alertDB.open(this, false);"/>
</s:Application>

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

In this application, you first import the MyAlertPopUp component, then create an instance of it. The Button control calls the open() method to open the pop-up in response to a click event.

The first argument to the open() method specifies this. Therefore, the parent container of the SkinnablePopUpContainer container is the Application container. The second argument is false to specify a nonmodal window.

In this example, the application creates a single instance of the MyAlertPopUp component. It then reuses that instance every time the user selects the Button control. Therefore, the pop-up component stays in memory between uses.

If the pop-up component is large, or you want to reduce the memory use of the application, create a new instance of the component for each pop-up. The component is then destroyed when it closes. However, make sure to remove all references to the components, especially event handlers, or else the component is not destroyed.

Creating an inline Spark SkinnablePopUpContainer container

You do not have to define the SkinnablePopUpContainer container in a separate file. The following example uses the <fx:Declaration> tag to define an inline component:
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkSkinnablePopUpContainerSimple.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">

    <fx:Declarations>
        <fx:Component className="MyAlert">
            <s:SkinnablePopUpContainer>
                <s:Panel title="My Alert Panel">
                    <s:VGroup width="100%" horizontalAlign="center"
                        paddingTop="20" gap="20">
                        <s:Label text="Your custom alert box"/>
                        <s:Button label="OK" click="close();"/>
                    </s:VGroup>
                </s:Panel>
            </s:SkinnablePopUpContainer>
        </fx:Component>
    </fx:Declarations>
    
    <s:Button label="Open Alert" click="(new MyAlert()).open(this, false);"/>
</s:Application>

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

The <fx:Component> tag defines a class named MyAlert. Notice that the click event handler for the Button control first creates a new instance of the MyAlert class, then opens the pop-up.

Alternatively, you could write the inline component so that it creates a single instance of the pop-up that is reused every time, as the following example shows:
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkSkinnablePopUpContainerInlineReuse.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx">
    
    <fx:Declarations>
        <s:SkinnablePopUpContainer id="alert">
            <s:Panel title="My Alert Panel">
                <s:VGroup width="100%" horizontalAlign="center"
                          paddingTop="20" gap="20">
                    <s:Label text="Your custom alert box"/>
                    <s:Button label="OK" click="alert.close();"/>
                </s:VGroup>
            </s:Panel>
        </s:SkinnablePopUpContainer>
    </fx:Declarations>
    
    <s:Button label="Open Alert" click="alert.open(this, false);"/>
</s:Application>

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

Controlling the pop-up window

You can use properties of the SkinnablePopUpContainer and the mx.managers.PopUpManager class to control the pop-up window. In the following example, you modify the width and height of the pop-up by setting properties of the SkinnablePopUpContainer. You then use the PopUpManager.centerPopUp() method to center it in its parent container:
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkSkinnablePopUpContainerMoveResize.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">
    
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.managers.PopUpManager;
            
            protected function button1_clickHandler(event:MouseEvent):void {
                
                // Create an instance of MyAlert.
                var alert:MyAlert = new MyAlert();
                alert.open(this, true);   
                
                // Increase the width and height.
                alert.width += 100;
                alert.height += 100;
                
                // Center the pop-up in the parent container.
                PopUpManager.centerPopUp(alert);
            }
        ]]>
    </fx:Script>    
    
    <fx:Declarations>
        <fx:Component className="MyAlert">
            <s:SkinnablePopUpContainer>
                <s:Panel title="My Alert Panel" width="100%" height="100%">
                    <s:VGroup width="100%" horizontalAlign="center"
                              paddingTop="20" gap="20">
                        <s:Label text="Your custom alert box"/>
                        <s:Button label="OK" click="close();"/>
                    </s:VGroup>
                </s:Panel>
            </s:SkinnablePopUpContainer>
        </fx:Component>
    </fx:Declarations>
    
    <s:Button label="Open Alert SMG" click="button1_clickHandler(event);"/>
</s:Application>

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

Passing data back from the Spark SkinnablePopUpContainer container

Use the close() method of the SkinnablePopUpContainer container to pass data back to the main application from the pop-up. The close() method has the following signature:

public function close(commit:Boolean = false, data:*):void
where:
  • commit contains true if the returned data should be committed by the application.

  • data specifies the returned data.

The close() method dispatches the close event. The event object associated with the close event is an object of type spark.events.PopUpEvent.

The PopUpEvent class defines two properties, commit and data, that contain the values of the corresponding arguments to the close() method. In the event handler of the close event, you use these properties to inspect any data returned from the pop-up.

The following example of the Spark SkinnablePopUpContainer contains a List control. If the user selects an item in the List, then the close() method passes that value back to the main application. If the user select the Cancel button, the close() method returns nothing:,
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\myComponents\MyAlertPopUpReturn.mxml -->
<s:SkinnablePopUpContainer xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">
    
    <fx:Script>
        <![CDATA[
            import spark.events.IndexChangeEvent;

            // Event handler for the change event of the List control.
            protected function list1_changeHandler(event:IndexChangeEvent):void {
                // Close the SkinnablePopUpContainer.
                // Set the commit argument to true to indicate that the 
                // data argument contians a vaild value.
                close(true, list1.selectedItem);
            }
        ]]>
    </fx:Script>

    <s:Panel title="My Alert Panel">
        <s:VGroup width="100%" horizontalAlign="center"
                  paddingTop="20" gap="20">
            
            <s:List id="list1" width="100%" height="100%"
                    change="list1_changeHandler(event);">
                <s:layout>
                    <s:VerticalLayout/>
                </s:layout>
                <s:dataProvider>
                    <s:ArrayCollection source="{['Add', 'Delete', 'Post', 'Bookmark']}"/>
                </s:dataProvider>
            </s:List>
            
            <s:Button label="Cancel" click="close();"/>
        </s:VGroup>
    </s:Panel>
    
</s:SkinnablePopUpContainer>
Shown below is the main application that uses this component:
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkSkinnablePopUpContainerReturn.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    
    <fx:Script>
        <![CDATA[
            // Import the MyAlertPopUp class.
            import myComponents.MyAlertPopUpReturn;
            import spark.events.PopUpEvent;
            
            // Create and open the SkinnablePopUpContainer.
            protected function button1_clickHandler(event:MouseEvent):void {
                // Create an instance of MyAlertPopUp.
                var alertDB:MyAlertPopUpReturn = new MyAlertPopUpReturn();
                
                // Add an event handler for the close event to check for 
                // any returned data.
                alertDB.addEventListener('close', alertDB_closeHandler);
                alertDB.open(this, true);
            }
            
            // Handle the close event from the SkinnablePopUpContainer.
            protected function alertDB_closeHandler(event:PopUpEvent):void {
                // If commit is false, do data is returned.
                if (!event.commit)
                    return;
                
                // Write the returned String to the TextArea control.
                myTA.text = event.data as String;
            }            
        ]]>
    </fx:Script>
    
    <s:Button label="Open Alert" click="button1_clickHandler(event);"/>
    <s:TextArea id="myTA"/>
</s:Application>

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

This application uses the click event of the Button control to open the SkinnablePopUpContainer. The event handler for the click event creates an instance of the MyAlertPopUpReturn components, and then adds an event listener for the component’s close event.

The event handler for the close event examines the commit property of the event object. If the commit property is true, the data returned from the MyAlertPopUpReturn component is written to the TextArea control.