Understanding Window Events
An event-based programming model is used to interact with NativeWindows, so let’s take a look at what happens when an event takes place before we get into any specific operations.
For some NativeWindow operations, there are two associated events. The first dispatched event notifies you that something is about to happen, allowing you the opportunity to interject with a callback function. The second event tells you that something has already happened.
You’ll have to register a listener with that particular window instance to handle these events. The listener catches any of the events and allows you to execute logic using a callback function. In other words, “when object xyz dispatches a certain event, execute this particular function I’ve defined.”
Suppose a user clicks the Close button of a window. An event is dispatched to notify listeners that a window is about to close, giving our application a chance to react. We might want to prompt the users to save their work if they haven’t done so already. If the users choose to save, we’d first invoke the necessary functionality to save, and after that’s done, trigger the window to close. If our users don’t want to save their work, our callback function logic simply does nothing, and the window closes. Now, a second event is dispatched signaling that the window has finished closing.
Listing 5.5 shows an example in which we add event listeners for both Event.CLOSING and Event.CLOSE on an instance of mx.core.Window.
Listing 5.5. Exploring Window CLOSE and CLOSING Events
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" horizontalAlign="center"> <mx:Script> <![CDATA[ import mx.core.Window; private function openWindow():void { var myWindow:Window = new Window(); myWindow.systemChrome = NativeWindowSystemChrome.STANDARD; myWindow.type = NativeWindowType.NORMAL; myWindow.open( true ); myWindow.nativeWindow.addEventListener( Event.CLOSE, onWindowClose ); myWindow.nativeWindow.addEventListener( Event.CLOSING, onWindowClosing ); } private function onWindowClosing( event:Event ):void { trace( "Window is about to close" ); } private function onWindowClose( event:Event ):void { trace( "Window has closed" ); } ]]> </mx:Script> <mx:Button label="Create Window" click="openWindow()" /> </mx:WindowedApplication>
Canceling a Window Event
Often you’ll need to intercept an event and invoke conditional logic to determine whether you want that event to continue, such as in the example cited earlier in Listing 5.5. In that example we’re simply tracing a message to the output console, but in the real world, you may want to prompt users that their work isn’t currently saved and ask if they want to do so.
Listing 5.6 outlines how to interrupt the closing sequence by catching the CLOSING event and calling preventDefault() on the event object. This stops the event in its tracks. In this example we’re only doing this if isWorkSaved is false, indicating the user has attempted to close the application without saving his or her work.
Our Alert dialog makes a callback to onAlertClose, upon which time we act on the users’ decision to save their work. When that has been done, we can simply call the close() method on our Window. We’re also calling exit() because this is our main application Window we’re closing. If we didn’t call exit(), the Window would close but the application process would still be running, so it’s important to keep that in mind!
Here’s how we could add to our example in code Listing 5.5:
Listing 5.6. Cancelling a Window CLOSING event
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" horizontalAlign="center" initialize="init()"> <mx:Script> <![CDATA[ import mx.events.CloseEvent; import mx.controls.Alert; private var isWorkSaved:Boolean = false; private function init():void { nativeWindow.addEventListener( Event.CLOSING, onWindowClosing ); } private function onWindowClosing( event:Event ):void { if( !isWorkSaved ) { event.preventDefault(); Alert.show( "Would you like to save your work?", "Warning!", Alert.YES | Alert.NO, this, onAlertClose ); } } private function onAlertClose( event:CloseEvent ):void { if( event.detail == 1 ) { // Save users work here isWorkSaved = true; trace( "Work has been saved" ); } nativeWindow.close(); exit(); } ]]> </mx:Script> </mx:WindowedApplication>