A TitleWindow layout
container is a Panel container
that is optimized for use as a pop-up window. The container consists
of a title bar, a caption and status area in the title bar, a border,
and a content area for its children. Unlike the Panel container,
it can display a close button. The TitleWindow container is designed
to work as a pop-up window that users can drag around the screen
the application window.
Modality
A pop-up TitleWindow container can be modal, which means
that it takes all keyboard and mouse input until it is closed, or nonmodal,
which means other windows can accept input while the pop-up window
is still open.
Forms
One
typical use for a TitleWindow container is to hold a form. When
the user completes the form, you can close the TitleWindow container
programmatically, or let the user request the application to close
it by using the close icon (a box with an x inside it) in
the upper-right corner of the window.
PopUpManager
Because
you pop up a TitleWindow, you do not create it directly in MXML,
as you do most controls. Instead you use the PopUpManager to
open a TitleWindow container.
SkinnablePopUpContainer
Flex also defines the SkinnablePopUpContainer 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. For more
information, see The Spark SkinnablePopUpContainer container.
Using the PopUpManager to create a Spark TitleWindow container
To create and remove a pop-up TitleWindow container, you
use methods of the PopUpManager. The PopUpManager is in the mx.managers
package.
Creating and deleting Spark pop-up window
To create a pop-up window, use the PopUpManager createPopUp() method.
The createPopUp() method has the following signature:
public static createPopUp(parent:DisplayObject, class:Class,
modal:Boolean = false):IFlexDisplayObject
The
method takes the following arguments.
Argument
Description
parent
A reference to a window to pop-up over.
class
A reference to the class of object you want
to create. This is typically a custom MXML component that implements a
Spark or MX TitleWindow container.
modal
(Optional) A Boolean value that indicates
whether the window is modal, and takes all keyboard and mouse input until
it is closed (true), or whether interaction is
allowed with other controls while the window is displayed (false).
The default value is false.
Note: Flex continues executing
code in the parent even after you create a modal pop-up window.
You
use the createPopUp() method to create a pop-up
window from a component definition. Typically, that means you have
created an MXML component based on the TitleWindow container that
defines your pop-up window. You can also create a pop-up window
by passing an instance of a TitleWindow class or custom component
to the PopUpManager addPopUp() method.
To
remove a pop-up window, use the PopUpManager removePopUp() method.
Pass the object created with the createPopUp() method
or the addPopUp() method to the removePopUp() method.
Defining a custom Spark TitleWindow component
One
of the most common ways of creating a TitleWindow container is to
define it as a custom MXML component. Define the TitleWindow container,
its event handlers, and all of its children in the custom component.
Then, use the PopUpManager createPopUp() and removePopUp() methods
to create and remove the TitleWindow container.
The following
example code defines a custom MyLoginForm TitleWindow component
that is used as a pop-up window:
<?xml version="1.0"?>
<!-- containers\spark\myComponents\MyLoginForm.mxml -->
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
close="handleCloseEvent();">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
// Handle the close button and Cancel button.
private function handleCloseEvent():void {
PopUpManager.removePopUp(this);
}
// Handle the OK button.
private function processLogin():void {
// Check credentials (not shown) then remove pop up.
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<s:Form>
<s:FormItem label="User Name">
<s:TextInput id="username" width="100%"/>
</s:FormItem>
<s:FormItem label="Password">
<s:TextInput id="password"
displayAsPassword="true"
width="100%"/>
</s:FormItem>
</s:Form>
<s:HGroup>
<s:Button label="OK"
click="processLogin();" />
<s:Button label="Cancel"
click="handleCloseEvent();"/>
</s:HGroup>
</s:TitleWindow>
This file, named MyLoginForm.mxml,
defines a TitleWindow container by using the <s:TitleWindow> tag.
The TitleWindow container defines a Form container with two TextInput
controls for user name and password. It also defines two Button
controls for submitting the form and for closing the TitleWindow container.
This example does not include the code for verifying the user name and
password in the submitForm() event listener.
In
this example, you process the form data in an event listener of
the MyLoginForm.mxml component. To make this component more reusable,
you can define the event listeners in your main application. This
lets you create a generic form that leaves the data handling to
the application that uses the form.
Close icon
By
default, the TitleWindow container displays a close icon (a small x in
the upper-right corner of the TitleWindow title bar) to make it
appear similar to dialog boxes in a GUI environment.
Close event
The
TitleWindow broadcasts a close event when the user
clicks the close icon. Flex does not close the window automatically.
Create a handler for that event and close the TitleWindow from within
that event handler. In the MyLoginForm.mxml component, you use the
same event handler for the close and Cancel buttons. You can create
a skin file for the TitleWindow to hide the close button, or set
the visible property of the close button to false.
Using the PopUpManager.createPopUp() method to create the pop-up Spark TitleWindow
To create a pop-up window,
you call the PopUpManager createPopUp() method
and pass it the parent, the name of the class that creates the pop-up,
and the modal Boolean value. The following main application code
creates the TitleWindow container defined in the previous section:
<?xml version="1.0"?>
<!-- containers\spark\SparkMainMyLoginForm.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">
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import spark.components.TitleWindow;
import myComponents.MyLoginForm;
// Open the pop-up window.
private function showLogin():void {
// Create a non-modal TitleWindow container.
var helpWindow:TitleWindow=
PopUpManager.createPopUp(this, MyLoginForm, false) as TitleWindow;
PopUpManager.centerPopUp(helpWindow);
}
]]>
</fx:Script>
<s:VGroup width="300" height="300">
<s:Button label="Login"
click="showLogin();"/>
</s:VGroup>
</s:Application>
The executing SWF file for the previous example is shown below:
In this example, when
the user selects the Login button, the event listener for the click event
uses the createPopUp() method to create a TitleWindow container,
passing to it the name of the MyLoginForm.mxml file as the class name.
By
casting the return value of the createPopUp() method
to TitleWindow, you can manipulate the properties of the pop-up
TitleWindow container, as the following example shows:
<?xml version="1.0"?>
<!-- containers\spark\SparkMainMyLoginFormCast.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">
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import spark.components.TitleWindow;
import myComponents.MyLoginForm;
private function showLogin():void {
// Create the TitleWindow container.
var helpWindow:TitleWindow =
PopUpManager.createPopUp(this, MyLoginForm, false) as TitleWindow;
// Add title to the title bar.
helpWindow.title="Enter Login Information";
// Make title bar slightly transparent.
helpWindow.setStyle("borderAlpha", 0.9);
// Hide the close button.
helpWindow.closeButton.visible = false;
}
]]>
</fx:Script>
<s:VGroup width="300" height="300">
<s:Button click="showLogin();" label="Login"/>
</s:VGroup>
</s:Application>
The executing SWF file for the previous example is shown below:
Using the PopUpManager.addPopUp() method to create the pop-up Spark TitleWindow
You can use the addPopUp() method
of the PopUpManager to create a pop-up window without defining a
custom component. This method takes an instance of any class that
implements IFlexDisplayObject. Because it takes a class instance, not
a class, you can use ActionScript code in an <fx:Script> block
to create the component instance to pop up, rather than as a separate
custom component.
Using the addPopUp() method
may be preferable to using the createPopUp() method
if you have to pop up a simple dialog box that is not reused elsewhere
in the application. However, it is not the best coding practice
if the pop-up is complex, or if you want to create a component that
can be used anywhere in the application.
The following example
creates a pop-up with addPopUp() method and adds
a Button control to that window that closes the window when you
click it:
<?xml version="1.0"?>
<!-- containers\spark\MyPopUpButton.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="600" width="600" >
<fx:Script>
<![CDATA[
import spark.components.TitleWindow;
import flash.events.*;
import mx.managers.PopUpManager;
import spark.components.Button;
import mx.core.IFlexDisplayObject;
// The variable for the TitleWindow container
public var myTitleWindow:TitleWindow = new TitleWindow();
// Method to instantiate and display a TitleWindow container.
// This is the initial Button control's click event handler.
public function openWindow(event:MouseEvent):void {
// Set the TitleWindow container properties.
myTitleWindow = new TitleWindow();
myTitleWindow.title = "My Window Title";
myTitleWindow.width= 220;
myTitleWindow.height= 150;
// Call the method to add the Button control to the
// TitleWindow container.
populateWindow();
// Use the PopUpManager to display the TitleWindow container.
PopUpManager.addPopUp(myTitleWindow, this, true);
}
// The method to create and add the Button child control to the
// TitleWindow container.
public function populateWindow():void {
var btn1:Button = new Button();
btn1.label="close";
btn1.addEventListener(MouseEvent.CLICK, closeTitleWindow);
myTitleWindow.addElement(btn1);
}
// The method to close the TitleWindow container.
public function closeTitleWindow(event:MouseEvent):void {
PopUpManager.removePopUp(myTitleWindow);
}
]]>
</fx:Script>
<s:Button label="Open Window" click="openWindow(event);"/>
</s:Application>
The executing SWF file for the previous example is shown below:
Using the mouseDown event to close the Spark TitleWindow
You
can use the mouseDownOutside event to close the
pop-up window when a user clicks the mouse outside the TitleWindow.
To do this, you add an event listener to the TitleWindow instance
for the mouseDownOutside event, as the following
example shows:
You define the event listener
in the main application, and then assign it to the pop-up window
when you create it. This technique lets you use a generic pop-up window,
defined by the component MyLoginForm.mxml, and then modify the behavior
of the component by assigning event listeners to it from the main
application.
Creating a modal pop-up window
The createPopUp() method
takes an optional modal parameter. You can set this parameter
to true to make the window modal. When a TitleWindow
is modal, you cannot select any other component while the window
is open. The default value of modal is false.
The following example
creates a modal pop-up window:
var pop1:IFlexDisplayObject = PopUpManager.createPopUp(this, MyLoginForm, true);
Dragging the popup Spark TitleWindow
After you pop up the Spark TitleWindow container,
you can drag it around the application window. To drag the TitleWindow,
click and hold the mouse in the title bar area of the window, then
move the mouse.
By default, you click in the title bar area of the TitleWindow
container to drag it. That area is defined by the moveArea skin
part. You can create a custom skin class to modify the move area.
Events during a move operation
The Tile Window dispatches the following events as part of a
move operation:
Event
Descriptions
windowMove
Dispatched when you stop dragging the window.
This event can be dispatched multiple times before the windowMoveEnd event
if you stop dragging the window but do not release the mouse button.
windowMoveEnd
Dispatched when the user releases the mouse
button to end the drag.
windowMoveStart
Dispatched when the user presses the mouse
button while the pointer is in the move area to begin the drag. This
event is cancelable.
windowMoving
Dispatched repeatedly as the user drags
the window. This event is cancelable.
The event handlers for these events receive an object of type TitleWindowBoundsEvent.
The TitleWindowBoundsEvent class defines the beforeBounds and afterBounds properties,
of type Rectangle.
You can use these properties to determine the position of the TitleWindow
as it is dragged, as the following table shows:
Event
beforeBounds
afterBounds
windowMove
The previous bounds of the window.
The current bounds of the window.
windowMoveEnd
The starting bounds of the window.
The ending bounds of the window.
windowMoveStart
The starting bounds of the window.
null
windowMoving
The current bounds of the window.
The future bounds of the window if the window
moves to the current cursor position.
The following example shows a TitleWindow component that displays
each event in a TextArea control
as it occurs:
The following example uses this component. As you drag the TitleWindow container
around the application, the event handlers write a string to the TextArea
control:
<?xml version="1.0"?>
<!-- containers\spark\SparkMainMoveEvents.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">
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import spark.components.TitleWindow;
import myComponents.MyLoginFormMoveEvents;
// Open the pop-up window.
private function showLogin():void {
// Create a non-modal TitleWindow container.
var helpWindow:TitleWindow =
PopUpManager.createPopUp(this, MyLoginFormMoveEvents, false) as TitleWindow;
PopUpManager.centerPopUp(helpWindow);
}
]]>
</fx:Script>
<s:VGroup width="300" height="300">
<s:Button label="Login"
click="showLogin();"/>
</s:VGroup>
</s:Application>
The executing SWF file for the previous example is shown below:
You can disable dragging of the TitleWindow by setting the visible property of
the moveArea skin part to false:
helpWindow.moveArea.visible = false;
Passing data to and from a Spark pop-up window
To make your pop-up window more flexible, you might want
to pass data to it or return data from it. To do this, use the following
guidelines:
Create a custom component to be your pop-up. In most
circumstances, this component is a TitleWindow container.
Declare variables in your pop-up that you set in the application
that creates the pop-up.
Cast the pop-up to be the same type as your custom component.
Pass a reference to that component to the pop-up window,
if the pop-up window is to set a value on the application or one
of the application’s components.
For example, the following application populates a ComboBox in
the pop-up window with an ArrayList defined
in the main application.
<?xml version="1.0"?>
<!-- containers\spark\SparkMainArrayEntryForm.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>
<fx:Script>
<![CDATA[
import mx.collections.ArrayList;
import mx.managers.PopUpManager;
import myComponents.ArrayEntryForm;
public function displayForm():void {
/* ArrayList with data for the custom control ComboBox control. */
var doctypes:ArrayList = new ArrayList(["*.as", "*.mxml", "*.swc"]);
/* Create the pop-up and cast the
return value of the createPopUp()
method to the ArrayEntryForm custom component. */
var pop1:ArrayEntryForm = ArrayEntryForm(
PopUpManager.createPopUp(this, ArrayEntryForm, true));
/* Set TitleWindow properties. */
pop1.title="Select File Type";
/* Set properties of the ArrayEntryForm custom component. */
pop1.targetComponent = ti1;
pop1.myArray = doctypes;
PopUpManager.centerPopUp(pop1);
}
]]>
</fx:Script>
<s:TextInput id="ti1" text=""/>
<s:Button id="b1" label="Select File Type"
click="displayForm();"/>
</s:Application>
The executing SWF file for the previous example is shown below:
When creating the pop-up, the application casts the pop-up to
be of type ArrayEntryForm, which is the name of the custom component
that defines the pop-up window. If you do not do this, the application
cannot access the properties that you create.
The application passes a reference to the TextInput component
in the Application container
to the pop-up window so that the pop-up can write its results back
to the container. The application also passes the ArrayList of filename
extensions for the pop-up ComboBox control’s data provider, and
sets the pop-up window’s title. By setting these in the application,
you can reuse the pop-up window in other parts of the application
without modification, because it does not have to know the name
of the component it is writing back to or the data that it is displaying,
only that its data is in an Array and it is writing to a TextArea.
The following custom component, ArrayEntryForm.mxml, declares
two variables. The first one is for the ArrayList that the parent
application passes to the pop-up window. The second holds a reference
to the parent application’s TextInput control. The component uses
that reference to update the parent application:
<?xml version="1.0"?>
<!-- containers\spark\myComponents\ArrayEntryForm.mxml -->
<s:TitleWindow 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="200" borderAlpha="1"
close="removeMe();">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import spark.components.TextInput;
import mx.managers.PopUpManager;
import mx.collections.ArrayList;
// Variables whose values are set by the main application.
// Data provider array for the component's ComboBox control.
[Bindable]
public var myArray:ArrayList;
// A reference to the TextInput control
// in which to put the result.
public var targetComponent:TextInput;
// OK button click event listener.
// Sets the target component in the application to the
// selected ComboBox item value.
private function submitData():void {
targetComponent.text = String(cb1.selectedItem);
removeMe();
}
// Cancel button click event listener.
private function removeMe():void {
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<s:ComboBox id="cb1" dataProvider="{myArray}"/>
<s:HGroup>
<s:Button label="OK" click="submitData();"/>
<s:Button label="Cancel" click="removeMe();"/>
</s:HGroup>
</s:TitleWindow>
From within a pop-up custom component, you can also access properties
of the parent application by using the parentApplication property.
For example, if the application has a Button control named b1, you
can get the label of that Button control, as the following example
shows:
myLabel = parentApplication.b1.label;
This technique, however, uses a hard-coded value in the pop-up
component for both the target component id in the parent and the
property in the component.
Passing data using events
The following
example modifies the example from the previous section to use event
listeners defined in the main application to handle the passing
of data back from the pop-up window to the main application. This
example shows the ArrayEntryFormEvents.mxml file with no event listeners
defined within it.
<?xml version="1.0"?>
<!-- containers\spark\myComponents\ArrayEntryFormEvents.mxml -->
<s:TitleWindow 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="200"
borderAlpha="1">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import mx.collections.ArrayList;
// Variables whose values are set by the main application.
// Data provider array for the component's ComboBox control.
[Bindable]
public var myArray:ArrayList;
]]>
</fx:Script>
<s:ComboBox id="cb1" dataProvider="{myArray}"/>
<s:HGroup>
<s:Button id="okButton" label="OK"/>
<s:Button id="cancelButton" label="Cancel"/>
</s:HGroup>
</s:TitleWindow>
The main application
defines the event listeners and registers them with the controls
defined within the pop-up window:
<?xml version="1.0"?>
<!-- containers\spark\SparkMainArrayEntryFormEvents.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>
<fx:Script>
<![CDATA[
import mx.collections.ArrayList;
import mx.managers.PopUpManager;
import myComponents.ArrayEntryFormEvents;
public var pop1:ArrayEntryFormEvents;
public function displayForm():void {
/* ArrayList with data for the custom control ComboBox control. */
var doctypes:ArrayList = new ArrayList(["*.as", "*.mxml", "*.swc"]);
/* Create the pop-up and cast the return value
of the createPopUp() method to the ArrayEntryFormEvents custom
component. */
pop1 = ArrayEntryFormEvents(
PopUpManager.createPopUp(this, ArrayEntryFormEvents, true));
/* Set TitleWindow properties. */
pop1.title="Select File Type";
/* Set the event listeners for
the ArrayEntryFormEvents component. */
pop1.addEventListener("close", removeMe);
pop1.cancelButton.addEventListener("click", removeMe);
pop1.okButton.addEventListener("click", submitData);
/* Set properties of the ArrayEntryFormEvents custom control. */
pop1.myArray = doctypes;
PopUpManager.centerPopUp(pop1);
}
/* OK button click event listener.
Sets the target component in the application to the
selected ComboBox item value. */
private function submitData(event:Event):void {
ti1.text = String(pop1.cb1.selectedItem);
removeMe(event);
}
/* Cancel button click event listener. */
private function removeMe(event:Event):void {
PopUpManager.removePopUp(pop1);
}
]]>
</fx:Script>
<s:VGroup>
<s:TextInput id="ti1" text=""/>
</s:VGroup>
<s:Button id="b1" label="Select File Type" click="displayForm();"/>
</s:Application>
The executing SWF file for the previous example is shown below: