navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

AIR for Flex Developers (2008)
Don Barnett

AIR for Flex Developers (2008)

with David Gassner

 


AIR for Flex Developers is David Gassner's follow-up to his AIR Essential Training course, and takes a deeper look at how Flex Builder 3 and the Flex 3 framework can be used to build cross-system desktop applications with Adobe AIR. David examines every point of integration with the host operating system, including working with the local file system, creating and maintaining local databases, and managing native windows and menus. He also shares tips for how to configure the development environment, and how to publish and update finished AIR applications. Example files accompany the course.
Topics include:
  • Installing Apache, MySQL, and PHP on Windows or Mac OS X
  • Starting a Flex project for AIR
  • Transferring complex objects and data collections with the Clipboard
  • Creating drag-and-drop interfaces
  • Working with HTML content and JavaScript
  • Monitoring network connections
  • Encrypting local data
  • Opening files and using custom file types
  • Communicating between AIR applications

show more

author
David Gassner
subject
Developer, Desktop Apps
software
AIR 1, Flex
level
Advanced
duration
6h 39m
released
Jul 23, 2008

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:00Hi, my name is David Gassner and I'd like to welcome you to this video series, AIR for Flex Developers.
00:06This is a followup to a previous lynda.com video series, AIR Essential Training, in which I described how to build and
00:13deploy basic AIR applications
00:15using either Flex, Flash or Dreamweaver and AJAX.
00:20In this series, I offer a deep dive into the details of building more powerful desktop applications with the Adobe
00:26Integrated Runtime, with an exclusive focus on building applications with Flex Builder 3 and the Flex 3 framework.
00:34I hope you enjoy this training,
00:36and that it helps you build better, more powerful, cross operating system desktop applications using Flex 3 and AIR 1.0.
Collapse this transcript
Prerequisites
00:00In this video I describe some of the prerequisites for working with this video series.
00:05This video series, AIR for Flex Developers, was primarily designed for developers
00:09with some experience already in working with Flex and AIR.
00:13It's not a beginning course. It's designed as a follow up to the AIR Essential Training course
00:18that was previously delivered at lynda.com.
00:21For all of you who are brand new to Flex, you will be able to get a lot out of this course.
00:25You'll get a lot more if you have some background working with Flex and AIR already.
00:30Some of the skills that can help you get more out of the course include knowing how to build basic applications
00:35in Adobe Flex and how to deliver those over the Adobe Integrated Runtime.
00:40How to use the ActionScript 3 programming language.
00:43How to parse XML using E4X, an aspect of ActionScript 3 that allows to easily parse and extract data from XML structures
00:52and some of the most fundamental things about the Adobe Integrated Runtime, including getting
00:56and installing the Runtime and delivering new applications using such features as the seamless installation batch.
01:03If some of these skills are new to you, there are plenty of resources to help you get started.
01:08First of all for Flex itself, take a look
01:11at the Flex 3 Essential Training video series that I previously did for lynda.com.
01:16In that series you learned how to build basic Flex applications,
01:19how to lay out those applications visually using containers and controls, how to work with the Event Architecture
01:25of the Flex framework and how to communicate with application servers
01:29such as the PHP Application Server that's used in this video series using a Flex component named HTTP Service.
01:37If you'd like a refresher on the ActionScript language, take a look at ActionScript 3
01:42in Flex Builder Essential Training by Joey Lott also on lynda.com.
01:47There you'll get refresh on programming fundamentals and on object oriented programming
01:52as it's implemented in the ActionScript language.
01:55Finally for AIR itself, take a look at AIR Essential Training.
01:59In that video series I showed developers how to build
02:02into play basic AIR applications using either FLEX, Flash or Dreamweaver and AJAX.
02:08This video series focuses on a deep dive into the details of working
02:12with AIR including very detailed programming techniques to work with the local file system, the local database
02:18and so on, but it assumes that you understand the fundamentals of AIR first,
02:23how to get and install the Runtime and how to deliver your applications using
02:27such techniques as creating seamless installation.
02:31These and other features are all covered in the Essential Training So go ahead and jump in and at any point
02:37when you feel like you might need some help you can go back to these other preliminary titles, Flex 3 Essential Training,
02:43ActionScript 3 and AIR Essential Training to get the background that you need.
Collapse this transcript
Installing WAMP on Windows
00:00In this video I'm going to describe how to install WAMP, the Integrated Server bundle
00:05for Windows that includes Apache, MySQL and PHP.
00:10I'll be using services hosted by WAMP throughout many of the exercises in this video series.
00:15If you are working on Mac OS X, you instead want to use a MAMP, the Mac equivalent of this server bundle.
00:22Look for the separate video on downloading and installing that product.
00:26To download a copy of WAMP, go to WAMP's website which you'll find at this URL www.en.wampserver.com.
00:37The WAMP server bundle is completely free and includes everything you need for hosting simple services
00:43for your AIR applications, you can download the latest release.
00:47I'm using the latest version as of the time of this recording, WampServer 2.0c.
00:52I have already downloaded the Installer on to my desktop.
00:56So now to get started, I will start the Installer, I'll step through the various prompts including the notice not to try
01:03to upgrade from WAMP 1.x, I'll click Yes to continue the installation, click Next and then read
01:11through the License Agreement, if you agree to the License Agreement continue on, click Next again
01:17and then select the installation folder location.
01:20The default location for the WAMP Server is C:WAMP, that will also create a WWW sub folder under the WAMP root
01:29that will serve as your Web documents directory, click Next, at this screen indicate whether you want a Quick Launch icon
01:37or a Desktop icon, you really don't need these icons for WAMP because once you start
01:42up the WAMP server you will have an easy access icon in the system tray
01:46that appears automatically, I'll click Next and click Install.
01:51Once the files are copied over, you'll be prompted to select which browser you want to use when you navigate
01:56to various WAMP Administrative Tools, if Firefox has been detected on your system as it has been on mine,
02:04you'll be prompted to use it as the default browser with WAMP.
02:07If you don't have Firefox, you'll see a different version of this screen prompting you to select a default browser,
02:13I'll say Yes, I want to use Firefox for my Administrative Tools in WAMP
02:18and then the installation process will complete.
02:21You are prompted along the way to select an SMTP server and then to your email address, I'll enter my email address
02:30and that just means that any links that are produced by the WAMP server to send email
02:35to the system administrator will go through that email address.
02:38I'll click Next and then on the final screen I'm prompted to launch the WAMP Server.
02:43I'm not going to launch it right away because I'd also like to show you how
02:47to start it up after it's already been installed.
02:49I will click Finish and then I'll go to the Windows menu, if you are working on Windows Vista as I am,
02:56type in WAMP and look for the item labeled Start WAMP Server, I'll click to start the server.
03:02In the system tray on the lower right corner you'll see an icon appear, I'll go down and click the icon
03:09and the menu pops up showing the all the administrative tools for the WAMP Server.
03:13The WAMP Server includes not just the server itself but also Apache, PHP and MySQL.
03:20So, for example if I wanted to administer any of these services individually I could go to the MySQL menu choice
03:27to be able to start, stop and otherwise manage that service, I could go to PHP and select various settings there
03:34or once again I can start and stop the Apache Server from this menu choice.
03:38Under the Quick Admin section there are menu choices to Start All Services, Stop All Services and Restart All.
03:45To use the WAMP Server right away I'll select Put Online and that means that I'd like to start
03:51up the server and be able to use it immediately.
03:53In the low right hand corner the icon in this system tray will temporarily change color
03:58and then the pointer will move all the way over to the right indicating the server is ready for use.
04:04Then I'll go back to the icon, click it again and select Localhost and that will take me to the WAMP Home Page.
04:11This is how you know your WAMP Server is working correctly.
04:15I'll close that browser window, go back to the icon again and this time I'm going to select phpMyAdmin.
04:24This is how I'll start up the web based management console for MySQL.
04:29This same application phpMyAdmin is hosted both by WAMP on Windows and by MAMP on Mac.
04:36In a later video I'll describe how to use this interface to import the database that you'll use
04:42in the AIR application examples throughout the video series.
Collapse this transcript
Installing MAMP on Mac OS X
00:00In this video I'm going to describe how to install MAMP, the Integrated Server bundle that includes Apache,
00:06MySQL and PHP for Mac OS X. To download and install MAMP, go to the MAMP website www.mamp.info/en/index.php.
00:21Scroll down towards the bottom of the home page and click the Download Now button,
00:26there are two versions of MAMP, MAMP and MAMP Pro.
00:30MAMP is a free version of the server bundle which includes Apache, MySQL and PHP and MAMP Pro is a licensed version
00:38which requires a fee, we are going to use the simpler MAMP, the one that's free because it has all the tools we need
00:44to run the exercises in this video series, but there is only a single installer for both versions,
00:50download the DMG installer package and then once the MAMP DMG file has been downloaded to your system unpack it.
00:58Then open up the MAMP and MAMP Pro virtual disk.
01:02The installation of MAMP is very simple, simply drag the MAMP folder into the Applications folder,
01:10it'll take a few seconds for everything to copy over, there is a little over 300 megabytes of content there,
01:16but then once the copying is complete, you 'll be ready to launch MAMP for the first time.
01:21Close the Installer window and then navigate to your Applications folder and locate the new MAMP folder.
01:31Within the MAMP folder you'll find a MAMP application.
01:35Start it up, you may see this security prompt and click Open,
01:40when MAMP starts up as an application you'll see two things happen, first you'll see a browser window open
01:46to localhost:8888, the Apache web server that's a part of the MAMP installation starts up on this custom port
01:55and you'll be able to navigate around to the various tools that lead to administer the servers.
02:00Before you visit those administrative tools though, you'll want to go to the MAMP application
02:04and change the ports for both Apache and MySQL.
02:08Click on the MAMP icon in your Dock, then click the Preferences button in the MAMP application,
02:15click on Ports at the top of the Window and then click Set to Default Apache and MySQL ports.
02:22This will cause the Apache and MySQL servers to run on the same ports as they are in Windows which will allow you
02:28to run the code in exactly the same way as a Windows user might do, then click OK.
02:33You'll see that the servers restart automatically and you maybe prompted for a password.
02:41If so, enter your Mac administrative password.
02:45It's also a good idea that the built-in web server that comes with Mac OS X is turned off.
02:51To do that goto System Preferences, from there goto Sharing and check to make sure that Web Sharing is unchecked,
02:59if you had Web Sharing checked that would meant that the version of Apache that's included
03:04with Mac OS X is also running and you might run into a port conflict.
03:09You should now be able to navigate around and see all the different tools of MAMP.
03:13In order to make sure that the MAMP servers keep running just keep the MAMP application open,
03:18if you close the application that shuts down the servers.
03:22I'll just minimize the MAMP application to the Dock, the tool that you'll be using here
03:26and there throughout the video series is phpMyAdmin,
03:29a web based administrative tool that lets you manage your MySQL server.
03:34Close the browser and close any other windows, we turn to the MAMP application and then click Open Startpage.
03:43This time you'll see that the page opens on a localhost with no port number because we updated the port numbers
03:48in the MAMP installation, then goto phpMyAdmin and from there you'll be able to follow steps in later videos
03:56where you will import a database table into your MySQL database.
04:00One other thing that's important to know about using MAMP, your Apache document root folder that is the folder
04:06that contains all of the root document is in the htdocs folder under the MAMP folder.
04:12In the later video you'll be instructed to copy some existing PHP code into your document root,
04:18at that point if you are working on the Mac you'll copy the files into this htdocs folder,
04:23I'll mention that in the later video at that time too, but it's a good thing to know at this point as well.
Collapse this transcript
Installing the sample database on MySQL
00:00In this video, I'm going to describe how to import the database table into the MySQL database that I'll be using
00:07in many of the exercises throughout this video series.
00:10In the previous exercises I showed you how to install either WAMP or MAMP, so that you already have MySQL
00:17and PHP installed and running on your system.
00:20Now I'm going to go to an application called phpMyAdmin.
00:25To get started goto your Server Administrator.
00:28If you are working on Windows, click on the icon in the system tray and if you are working
00:32on Mac you can go to the MAMP application.
00:35Locate the phpMyAdmin menu choice or item and start up the application,
00:41it should appear at this URL http://localhost/phpmyadmin/.
00:46The next task is to create a new database, click into the text field under the label Create new database
00:53and type in the name of the database contacts and then click Create.
00:58If prompted with a security warning click Continue, that will result in creating the database.
01:05Now the next step is to import the database table.
01:09Click the Import button, then click the Browse button, navigate to the location of your exercise files.
01:17If for instance, your exercise files are on your desktop, go there and then click into the exercises folder,
01:25from the exercises root directory, click into Assets, from there into Server and from there into MySQL,
01:33you'll find two files there named contacts.sql and readme.txt, select the file contacts.sql,
01:42on Windows just click Open, that will add the path of the contacts.sql file to the text field in the import screen,
01:50then click the Go button in the lower right hand corner.
01:53It takes just a few seconds to execute the import operation.
01:57Once the import operation is complete, go to the structure link under the Server Listing
02:03and from there you'll find the person table that was created by the import script.
02:08Click the first button which allows you to browse the data and that will show you
02:12that in fact you have successfully imported the data from the database,
02:16this database table named person includes a 1000 records of data.
02:22I'll be using this data in many of the exercises and demonstrations in AIR applications, both retrieving the data
02:28from the server and then in the section that describes how to persist data
02:32to the local system using the embedded SQL live database, I'll show how to retrieve the data
02:37from the server and then save it locally.
02:40If you can see this data on the screen, you are ready for the next step of the installation
02:45which is to setup the actual exercise files.
Collapse this transcript
Using the example files
00:00Just a quick word about the exercise files we'll be using.
00:03If you're a premium member of the lynda.com Online Training Library or if you are watching this tutorial on a DVD,
00:10you have access to the exercise files used throughout this title.
00:13In the Exercise File folder, I have collected some assets for you to use during our tour of AIR for Flex developers.
00:20They include everything you will need to create the applications in this title.
00:23Two videos following this one show you how to set up the exercise files first for the Mac and then for Windows.
00:30If you're a monthly or annual subscriber to lynda.com, you don't have access to the exercise files
00:36but you can easily follow along and create your own code as we go.
00:40Let's get started.
Collapse this transcript
Setting up the example files on Mac OS X
00:00In this video I'm going to describe how to install the exercise files on Mac OS X. The steps are very similar
00:07to those on Windows, but there are some variations so it's worth a separate video.
00:12First, assuming that you have the DVD version of the video series or you have a premium membership
00:17to the Online Training Library, you can download and extract the exercise files anywhere on your system.
00:23I have placed the exercise files in a folder called Exercises on my desktop.
00:27The first step is to move some files from the Exercises folder into your MAMP document root.
00:34Go to the Exercises folder, open it up and go down to the Assets folder, from there to the Server folder
00:42and from there to php, you will find a folder there named AIRFlex, copy that folder to the clipboard
00:49and then using finder, navigate to the MAMP document root, I will go to the Applications folder,
00:57to the MAMP folder and from there into the htdocs folder.
01:03The htdocs folder is your document root when you are working with Apache through MAMP.
01:08Now paste the contents of the AIRFlex folder into the htdocs folder, before you can test these files you need
01:15to make a certain change in the configuration, drill down into the AIRFlex folder within htdocs
01:21and from there locate the file contactsconn.php, this is a php file that defines how you will be connecting to MySQL.
01:29Open this file in any text editor, for speed I will use Text Edit, there is a difference between the configuration
01:37of MySQL on Windows using WAMP and Mac using MAMP.
01:42On Windows, MySQL is installed with a blank password, on MAMP it's installed with a password of root.
01:49So, in this file move to the line that starts $password_conn and between the quotes put
01:55in the word root, then Save and Close the file.
02:00Then close whatever text editor you are using, close any finder windows
02:05and now make sure that you have your MAMP server started.
02:09I have placed my MAMP server application on the dock, so I can get to it easily.
02:13I will click to start up MAMP and then I will enter my administrative password.
02:18Now, to test the php files that were installed, go to the browser web address
02:23and enter http://localhost/AIRFlex/Person.php?method=FindAll,
02:36it's important to note that this entire URL is case-sensitive, type it exactly as you see on the screen.
02:42With AIRFlex capitalized as you see it Person.php with an initial uppercase character and the word FindAll
02:49with an uppercase F and A, you should see after a few moments the data returned from the MySQL server
02:56as an xml packet, this is how you will be working with the PHP server and My SQL using your AIR application.
03:03So, if that's over so far, you are ready to move on to Flex Builder.
03:07Close the browser window, remember to keep MAMP running at all time,
03:11so just minimize that to the dock and then go to Flex Builder.
03:15Within Flex Builder, change your workspace to point to the Exercises folder, from the Menu select File,
03:23Switch Workspace, Other and then click Browse, then navigate to the location of your Exercises folder,
03:31I have placed my Exercise folder in the desktop under Exercises,
03:35I will choose that, I will click OK, to switch work spaces.
03:40Whenever you switch workspaces, Flex Builder closes and then reopens to release any locks on any open files or folders.
03:48Now to test the ability to use an AIR application, that uses data from a PHP server and MySQL, import an existing project
03:57from the exercises area, go to the Flex Builder Menu and select File, Import, Flex Project,
04:06click to browse for an archive file, locate your exercises area and find the file FlexAIRTest.zip,
04:14this is a flex archive file, that you can import into either Windows or Mac, click to open
04:21and then click Finish, that will open up the project.
04:25Next go to the Test Application, open the project in the Flex Navigator view, open the source folder
04:31and double click to open FlexAIRTest.mxml.
04:36This application makes a simple call to a PHP page and retrieves the same data that you saw
04:41on the browser and then displays it in a data grid.
04:44Go to the Menu and select Run, run FlexAIRTest, you can also click the Run button on the toolbar
04:51or press the appropriate keyboard shortcut.
04:55When the application opens up, you will see that it has a Get Data button and a Data Grid, click the Get Data button
05:01and after a few moments the data should appear in the data grid.
05:04You will see that there are thousand rows that are being displayed in the data grid and you will be able
05:09to scroll up and down freely through the data.
05:12So, if all that's working you are ready to launch into the video series.
Collapse this transcript
Setting up the example files on Windows
00:00In this video I will show you how to setup some of the exercise files,
00:04so that your AIR applications can communicate with the PHP based services
00:08that in turn retrieve and send data to the MySQL database.
00:12If you have the exercise files, open up the Exercise Files folder now and then go down to the Assets folder,
00:20from there to Server and from there to php, in this folder you will find a single sub folder named AIRFlex,
00:28this folder in turn contains php based resources that will communicate with your MySQL database.
00:34I will go back to the php folder and then copy the AIRFlex folder, to the clipboard.
00:40Now, navigate to your document root within your WAMP or MAMP server, if you are working on Windows,
00:46the location of the document root is c:wampwww.
00:50Now paste the AIRFlex folder into the document root, your php files are now ready to use.
00:59To test the files, go to a browser, make sure that your WAMP or MAMP server is started up and then navigate
01:07to this web address http://localhost/AIRFlex/Person.php?method=FindAll.
01:18All parts of this URL are case sensitive and you must type it in exactly as you see it here.
01:23If the service is working, you should see that an XML structure is returned, representing one thousand rows
01:30of data, it may take a few moments to download to the browser, so be patient,
01:34scroll down to the end of the XML file and you should see down at the bottom a metadata section,
01:40showing the total rows of one thousand, if that much is working you are now ready to open Flex Builder,
01:46set up your workspace and import a project for testing an AIR application.
01:52Close the browser and close all other windows and then start up Flex Builder.
01:57Flex Builder should open up to the default Flex Development Perspective.
02:02Next, I'm going to change the workspace.
02:05If you went through Flex 2 or Flex 3 Essential Training video series,
02:09you heard me describe the nature of a workspace.
02:11As a system folder, the services are sort of table of contents, each workspace can contain more than one project
02:18and each project can contain one or more applications.
02:21Go to the Flex Builder Menu and select File, Switch Workspace, Other, then navigate to the location
02:29of your exercise files, I will click the browse button and then on Windows, I will go to the desktop
02:37and then from there I will go to the Exercises folder for this video series and click OK, you should modify your path
02:43to wherever you installed the Exercise Files, whether you are working on Windows or the Mac, then click OK.
02:50You should see that Flex Builder closes and then reopens again, once Flex Builder has reopened,
02:56import a Flex project from the exercises area, go to the Menu and select File Import, Flex Project,
03:05you are going to import an archived file, a Flex project archive file is a new architecture that was introduced
03:11with Flex Builder 3, that allows you to export and then import projects that are portable between operating systems.
03:19Click the Browse button and then in the Exercises folder,
03:23locate the file FlexAIRTest.zip, click Open and then click Finish.
03:30That will result in importing the flex project and once the project is finished importing,
03:35you will be ready to run a test to see whether your AIR applications can talk to your PHP server.
03:41Go to the Flex Navigator View and open up the project, drill down to the source root SRC
03:47and then double click to open FlexAIRTest.mxml.
03:52Notice that there are two files, the mxml file which is the main application file and FlexAIRTest-app.xml,
03:59which is the application descriptive file that contains information
04:03about how your AIR application should be packaged and run.
04:06Now, run the application, go to the Menu and select Run, Run FlexAIRTest or you can click the Run button on the toolbar
04:15or press the appropriate keyboard shortcut.
04:19Once the application is opened up on the screen, click the Get Data button, you should see a clock cursor appear
04:26and then after a few moments you should see your data show up.
04:29In the Status Bar of the application at the bottom, you should see the message,
04:33There are 1000 records in the person table and you should be able to scroll up and down
04:37and see all the data that was returned from the server.
04:41The source code for this application is fairly straight forward, it includes the use of an Http Service component
04:47and an array collection to hold the data in memory.
04:50If this code is unfamiliar to you, go back to the Flex 3 Essential Training title and it will describe not only how
04:57to use the PHP service that I'm using in this application,
05:01but also how to create the service using Flex Builder's new application wizards
05:05for various application server platforms.
05:08So, if you have installed the application and you have successfully run it and you have seen data,
05:13you are ready to start your training in this video series.
Collapse this transcript
1. AIR and Flex: A Quick Review
Creating a Flex project for AIR
00:00As described in a previous video about the prerequisites for this video series,
00:05you might have already watched the AIR 1.0 Essential Training video series,
00:09in which I described the most basic skills for building AIR applications in Flex Builder.
00:14For those who are jumping right into this video series though, I'm going to do a quick review of how
00:19to build a Flex Builder project for AIR applications and then how to package
00:23and install those applications on your desktop.
00:25To get started in Flex builder create a new project, from the menu select File, New,
00:33Flex Project, set the project name to Chapter01.
00:37As with all Flex Projects, a project name consist of letters, numbers and underscores and starts
00:43with an alphabetical character, special characters and spaces aren't allowed.
00:48Click the Browse button to select the folder.
00:51In the Exercises folder area, go down to the Chapter1 subfolder
00:55and from their choose the Begin folder and click OK.
00:59Make sure your Application Type is set to Desktop Application, Runs in Adobe AIR,
01:05set the Application Server Type to None and click Next.
01:09The output folder is the location where your debugged version of the application will be built,
01:13accept the default value of bin-debug and click Next again.
01:17The main application file is your source code for the application.
01:21Change the name of the application file to HelloWorld.mxml.
01:27The application idea is described in the previous video series essential training, should consist of the name
01:33of the application, plus a prefix including the reverse domain name of your organization
01:39and any other identifying information you might want to include in dot (.)
01:43format. For instance, for this application I will use the application id com.lynda- that's the reverse domain name
01:50of lynda.com. com.lynda.FlexAIR.HelloWorld, I will click Finish to create the project and the application.
02:01When the application opens, if it opens in Source, you click on the Design button to go into Design View,
02:08then go down to the Components View in the lower left hand corner of Flex Builder and drag in a label object.
02:14Because the application is initially created with absolute layout,
02:18the label object will drop in the place wherever you place it.
02:21Now with the label selected go over to the Flex Properties View and scroll down to the Text Section.
02:29Set the Label Size to 18 pixels, you can use the slider as I did or your can click
02:36and type the value into the text entry area.
02:39Now, scroll down to the bottom of the Flex Properties View and with the Label Control selected,
02:45use Constraints based layout to place the label in the direct center of the application.
02:50Click the horizontal center anchor and then set it's value to 0 and then click the vertical center anchor
02:57and make sure it's value is set to 0 as well.
03:03Save your changes and then run the application.
03:07To run an application from within Flex Builder, you can click the Run button, you can go to the Menu and select Run,
03:14run HelloWorld or you can press the appropriate keyboard shortcut.
03:18When the application runs it should open up in a separate window as a native application.
03:24In the next video, I will review how to package and install your application on the desktop.
Collapse this transcript
Exporting an AIR installation package
00:00In this video,
00:01I'm going to review how to create an installer package
00:04for an AIR application.
00:06Once again, these were steps that I have described in the Essential Training video series,
00:10that are worth going over again for those who are jumping right into this video series.
00:14You can follow these steps with any AIR application in Flex Builder. I'll be using the HelloWorld application
00:20I created in the previous video.
00:23From the Flex Builder menu select File,
00:26Export,
00:28Release Build.
00:29In the Export Release Build dialog box, select the Project and an Application
00:34and then indicate what AIR file you are creating.
00:37I'll accept the default setting of HelloWorld.air.
00:40A file with the .air extension again
00:42is an installer package that can be used on either Windows, Mac or in the future any other platform that supports the
00:49Adobe Integrated Runtime.
00:51Click Next
00:53and now you will need to select a digital certificate.
00:56As described in the Essential Training video series, the digital certificate is required to verify your identity to
01:02anybody who wants to install your application.
01:05If you don't already have a digital certificate that's from one of the authorized digital certificate vendors, Thawte or
01:10Verisign, you can create a self-signed certificate here. A self-signed certificate is only used during testing and
01:18development because when you install the application it will report your identity as unknown.
01:24To create a new self-signed certificate,
01:27click the Create button,
01:28enter yours or your organization's name. I'll enter Lynda.com
01:33and then type in a password twice.
01:39Browse to select a location where you want to create the certificate file.
01:43I'll place it in my top level Exercises folder, so I can use it in all the exercises throughout this video series.
01:49And then give it a name. I'll call it myCertificate
01:53and it will have a file extension of .p12.
01:56Click Save
01:57and that'll take you back to the digital certificate creation screen
02:02and click OK to create the certificate file.
02:05Next, enter the password.
02:07You may find that the password is entered automatically for you, but if it isn't just type it in.
02:13And you can check this option, Remember password for this session,
02:17and that will cause the password to always be there whenever you use this certificate again during the current Flex Builder session.
02:23Click Next,
02:26and on the following screen, you'll indicate which files should be packaged in the installer.
02:31You must include the application descriptor file,
02:34which in this application is called HelloWorld-app.xml
02:38and the compiled application HelloWorld.swf. Click Finish,
02:43and that should result in creating the HelloWorld.air file.
02:47Now before you follow the next step to actually install your application on the desktop system,
02:52you'll need to make sure you have installed the Adobe Integrated Runtime.
02:55If you don't already have the runtime, you can download it from the Adobe website.
03:00On the Adobe homepage there is a link labeled Get ADOBE AIR.
03:05Click that link and you should go to a screen that's appropriate for your operating system, Windows or Mac.
03:12Once you've downloaded and install the runtime, which I've already done previously, you're ready to install your application.
03:19Go back to the Flex Navigator view
03:21and locate the HelloWorld.air file that we just created.
03:26And then open the AIR file, which you can do by double clicking on either Mac or Windows.
03:31At the initial screen, noticed that the publisher is reported as Unknown. Once again, this is because you are using a
03:37self-signed digital certificate.
03:39If you had one from the Certificate Authorities your actual organization name would be reported here.
03:45Click the Install button,
03:47verify your Installation Preferences and the location of your application.
03:52On Windows, the Installation Location will be the Program Files folder under the C drive and on Mac it will be in the Applications folder.
04:00Click Continue to install the application
04:03and then the application should open immediately on your system.
04:07Close the application
04:09and then try opening the application again.
04:12If you're working on Windows you can open the application from the Start Menu.
04:16On Windows Vista, which I'm operating on, I'll type in HelloWorld
04:21and I'll find the HelloWorld application there
04:24and I'll be able to run the application immediately.
04:27If you're working on Windows XP,
04:28you'll find the application listed under All Programs on the Start Menu and if you are working on the Mac, you will want to go to
04:34your Application folder and double click or simply run the HelloWorld application from there.
04:40To uninstall the application, you can either follow the standard operations on your operating system.
04:46For instance, on Windows Vista you could go through the Remove Programs dialog or on the Mac you could simply drag the
04:52application into the trash
04:54or you can double click on the AIR file to run it again.
04:58The Adobe Integrated Runtime will detect that the application is already installed and it will give you the option to Uninstall.
05:05And now the application is gone from my desktop but I have the application installer ready to go anytime I need to install it again.
Collapse this transcript
Using the descriptor file
00:00In this video, I'm going to review the use of the Application Descriptor File,
00:04which determines much of the behavior of both the application and the installer.
00:09When you create a brand new mxml application in Flex Builder,
00:13a new Application Descriptor File was created for you.
00:17The name of the file will match the name of the application
00:20and will have the suffix of -app and a file extension of .xml.
00:25Here is the HelloWorld-app.xml file that's determining the behavior of both the installer and the application itself.
00:32I am going to maximize the editor so I can show you as much of this code as I can, but if you are following along
00:38in the exercises you can go ahead and open this file yourself to see all of the text.
00:42The first important element I want to describe is the xmlns attribute of the application element at the root.
00:49As I have described in the Essential Training video, this is a critical bit of information to the AIR Packager
00:56that tells it what version of the runtime this application is designed for.
01:00The namespace that's indicated here that ends with 1.0 means that this application works on AIR 1.0.
01:06If you see something that ends with a .0, .m and then a number, that would be an application
01:12that was go for previous data version of AIR.
01:15For current AIR applications, you want to ensure that you have a 1.0 at the end and nothing after it.
01:21Next, a little further down is the id element.
01:25The id element will contain the fully qualified id that you entered
01:29in the Flex Builder interface when you first created the application.
01:33If you want to change the id you can and the purpose of it is simply to uniquely identify the application.
01:40The Filename is used to determine the name of the file for the application.
01:44For instance, HelloWorld means you are creating a file called HelloWorld.air.
01:49The Name element is a value that shown during the application installation process
01:54and the version number can be used to provide information to you during automatic updates to the application.
02:01There are some additional descriptive elements down here which can either choose to enter or not.
02:06The Description if you enter it will show up on the second screen
02:09of the installer and the Copyright again, is optional.
02:13The initial window elements actually control behavior of the application rather than the installer.
02:18In the Essential Training video, I have described the use of the title element.
02:22You can set the title element either from this Application Descriptor File or from your main application file code.
02:29For example, if I were to establish the title element here, I would remove the comment tokens from the title element
02:35and then type in the title of the application here Hello World.
02:44I will then save and run the application and notice on the title bar of the application window, it shows the title.
02:50Now I will undo those changes, save the changes to the descriptor file and then go
02:58to the mxml main application file to the source code.
03:01I will go to the WindowedApplication element and I'm going to move some code around here so it's a little bit easier
03:07to see on the screen and then I will add a title element here and this time
03:12to make sure I'm seeing the new version I will use a different string Hello Again.
03:16I will save the changes, run the application and once again the application shows up and you will see
03:23that the title element is shown on the Title bar.
03:26So there are many properties that initial window which can be set either
03:30in the application code or in the application descriptor file.
03:34I will come back to the Application Descriptor File in Flex Builder.
03:38The next three elements System Chrome, Transparent
03:41and Visible are typically set through the Application Descriptor File.
03:45I have described in the Essential Training Video Series, how to use these elements in some other properties
03:51to create transparent applications, that is applications that are like widgets that appear
03:56on the screen without any rectangular background.
03:59The next three values, minimizable, maximizable and resizable can be used to control what the users allowed
04:06to do with the initial window, whether they can minimize, maximize or resize it.
04:11By default, this application can be resized at runtime.
04:14I will run the application and show you that the user is able to resize as needed.
04:22They are able to minimize, they are able to restore and they are able to maximize.
04:29Now, I will close the application and return to the Application Descriptor File.
04:35For all three of these elements, I'm going to remove their comment tokens
04:40and then put in the word false in between the tags.
04:43I will do that for the minimizable, the maximizable and the resizable elements.
04:58I will save the changes and run the application again and this time the application will put up with a fixed size.
05:05Noticed that any system chrome or controls that would normally allow you to minimize
05:10or maximize the window are gone and if I move the cursor
05:13down to the lower right corner, I will find that I can't resize it.
05:17So again, these are values that are controlled in the application descriptor.
05:22The height and width of the window can be controlled either
05:24from the Application Descriptor file or from the application itself.
05:29Here is a very important tip.
05:30When you are building an application in Flex Builder, make sure that if you set one
05:35of dimensions then you actually set both.
05:38There are circumstances where if you set a height for instance but not a width,
05:42the application will open Mac OS X and not show any content.
05:46So I'm going to set this application with an initial height of 300 pixels and an initial width of 400 pixels
05:55and I will save and run the application and now I have exerted very tight control over the size of the application.
06:02I can close the application, change the values.
06:06I will change to a height of 100 and a width of 150 and run the application again and now I will see
06:14that the application opens up in a much smaller initial window.
06:18I will close the application and then set the dimensions back to their initial settings
06:22with the width of 400 and a height of 300.
06:26Other elements that can be set through the Application Descriptor file, include the X and Y properties,
06:31that is the initial window's initial position when it first opens up on the screen and a minimum size and maximum size.
06:38So for instance, if you set minSize and maxSize elements and then we have resizable set to true,
06:44then the user will be able to resize but only bring it down to a minimum size beyond
06:49which you don't want to minimize anymore.
06:52There are many other attributes in this file that you can set, many of which I have described
06:56in the Essential Training video series and some of which I will come back to later on in this video series,
07:02but for those who went through the initial video series this will have been a good review of the purpose
07:07of the application descriptor file and how it controls both the application packaging
07:12and the applications behavior at runtime.
Collapse this transcript
2. Using the Clipboard
Understanding the Clipboard architecture
00:00In this chapter, I'm going to describe the use of the Clipboard
00:03to move data back and forth between applications in AIR.
00:06The clipboard is an architecture that allows copying and pasting between different applications.
00:12For example, if you are using the Microsoft Office suite and you want to move data between say Excel and Microsoft Word,
00:19you would copy content from Excel and then paste it into Word.
00:23In a manner very similar to these sorts of applications, AIR application allow you to place data
00:28in the clipboard programmatically using ActionScript code and then retrieve the data using other ActionScript code.
00:34I will be using a standard action script class called the Clipboard.
00:38Users already have the ability to copy and paste simple text values between applications when they are working
00:45in their desktop application deployed on AIR.
00:47For example, if your application has a data entry form and you have some content say a text or a word file,
00:54the user can move data between the applications using standard user adjusters such as Ctrl+C or Command+C
01:01on the Mac and Ctrl+V or Command+V on the Mac.
01:05The clipboard allows programmatic support of these features though.
01:09The AIR clipboard class allows you to place data into the clipboard and get data
01:14out while your AIR application is executing.
01:17It allows you to move data not just within an AIR application but also allows you to move data
01:23between AIR applications, from an AIR application to a non-AIR application and back in the other direction
01:29from a non-AIR application to an AIR application.
01:32There are limitations to this ability.
01:34First of all, you only have control over what happens inside the AIR application.
01:39You naturally can't control directly what happens in a target or a source application that's not built-in AIR,
01:45but within those restrictions the clipboard class allows you to move data quite easily from one application to another.
01:51The concept of a clipboard is wrapped around the idea of formats.
01:55When you place data into a clipboard, you indicate what format it's in.
02:00Formats are identified by names which as expressed as Strings.
02:04There are five built-in formats in the AIR environment.
02:08They are listed here.
02:09When you place data in the clipboard you can does made that it's simple text, that it's a bitmap representing a graphic,
02:16that it's a URL, a file list which would be a list of file objects or HTML formatted test.
02:23You also have the ability to create your own custom format names.
02:27For instance, if you wanted to move complex data from one application to another and had it both the copying
02:33of the data in the source application and the retrieve of the data
02:37in the destination application using ActionScript code, you would designate your own custom format name because none
02:44of the standard formats would match the type of data that you are moving between applications.
02:49The System Clipboard is represented in the world of AIR by a static generalClipboard property of the clipboard class.
02:57When you call any of the methods of the clipboard class, you call them as members of the general clipboard object.
03:04For example, the clipboard class has getData method, which receives a format name as it's only argument is called
03:11as a member of the generalClipboard static property.
03:14For example, the getData method, which receives a formatname as an argument and returns data associated
03:21with that format name is always called as a member of the generalClipboard static property
03:26of the Clipboard class and not of the clipboard class itself.
03:29There can only be one clipboard at any time,
03:33so the generalClipboard property represents what we called a Singleton,
03:36an object of which that can only be wanted at a given time.
03:41Here are the key members of the clipboard class that you will use.
03:44First the methods, setData, adds data to the clipbord, getData retrieves data from the clipboard,
03:52clearData removes all data from the clipboard and should be called prior to adding new data to the clipboard
03:58and the hasFormat method allows you to determine, whether data is currently stored
04:03in the clipboard associated with a particular format name.
04:07The generalClipboard static property which is I have previously described, references the only instance
04:13of the clipboard object and the formats property, an array which represents all
04:18of the formats currently stored in the clipboard.
04:21So those are the pieces of the puzzle.
04:23In the following videos in this chapter, I will show you some examples of how to move data between the clipboard
04:28of the operating system and the clipboard of an AIR application and back again and then how
04:34to move complex data between AIR applications.
Collapse this transcript
Copying data to the system Clipboard
00:00In this video, I'm going to describe how to copy data to the system clipboard so that it can be accessed
00:06by other applications running in the operating system.
00:09For all the demonstrations in this chapter, I will be using a Flex Project that you will find
00:13in the Exercise files if you are following along.
00:15To import the Flex Project, go to the Flex Builder Menu and select File, Import, Flex Project.
00:23Click the Browse button next to Archive file and in the Chapter02 folder
00:28within the Exercises area select the Chapter02BeginProject.zip.
00:34Open the project and click Finish to import it.
00:38Now open the project in the Flex Navigator view, open the source folder
00:43and from there open a file named ClipboardDemo.mxml.
00:47In this first demonstration, I'm going to be showing you how to copy a simple string value to the clipboard
00:53so that it can then be pasted into other applications.
00:56The user of course could do this themselves by simply using a keyboard or a mouse adjuster to copy text
01:03but the clipboard class and ActionScript allows you
01:05to explicitly copy data using your own ActionScript commands and that's what I will be showing here.
01:11The existing AIR application is very simple.
01:13It has two text area controls and two buttons.
01:17The first text area control is label Source, the second Destination and there are Copy and Paste buttons.
01:24The existing source code has two functions named copyData and pasteData.
01:28I will be simply filling in the code to execute these functions.
01:33In this first demonstration I'm going to copy a string value to the clipboard.
01:36If you are following along, place your cursor inside the copyData function.
01:41I will expand my editor to full screen to see as much code as possible
01:46and then I will start the process of copying data to the clipboard.
01:49I will be using a class called Clipboard.
01:52This is a class that's in the AIR library that does not have to be explicitly imported.
01:57Putting the name of the class and press a period and you will see
02:00that there is a single static property named generalClipboard which represents the system clipboard.
02:06Put in the generalClipboard property and press another period and then call the clear() method.
02:11This method clears all data from the clipboard, regardless of format.
02:16Put in a semicolon to close the line then start a new ActionScript statement.
02:21In the next statement, once again use the Clipboard class as generalClipboard property and then call the setData method.
02:28The setData method has two required arguments and one that's optional.
02:32The first argument is the name of the format.
02:35There are five built-in formats in the AIR library.
02:38They are represented as constants in the class called ClipboardFormats.
02:43Put in the ClipboardFormats class and press a period and you will see the five constants listed.
02:49Select the Text Format.
02:50This is the format that's used when you pass simple text values into or out of the clipboard.
02:56Put in a comma after the constant and then passing the value from the text in text area control, textIn.text.
03:05Close the parenthesis and close the command with the semicolon.
03:09That's it.
03:11The copyData function is already being called when the user clicks on the Copy button.
03:16Save your changes and then I will restore the editor to regular size so I can see the Flex Navigator view again.
03:24I am going to close up the Source folder and open a file called SimpleTextFile.txt.
03:30I will be using this text file to show that once I have copy data into the clipboard from the AIR application,
03:35I can then paste it from any other application.
03:38I will go back to ClipboardDemo and run the application.
03:42Once the application is opened up, I will click into the source text area folder and type a value in.
03:51Now I will click the Copy button to actually copy the data to the clipboard.
03:55There is no indication to the user that this is worked but the code in the background should have been executed.
04:01Notice I can still use standard copy and paste functionality.
04:05Either within an AIR application here I have right click on the text area control and selected Paste
04:11or more to the point, I can go back to the SimpleTextFile running in any text editor and I can also paste from here
04:18and you will see that the data has moved from the AIR application into the SimpleTextFile.
04:24Just to make sure that there is no slide of hand and the text is actually coming
04:28from the application I will demonstrate again.
04:30I will type in another line, I will once again copy to the clipboard by clicking the button,
04:40switch back to the text file and once again Paste and you will see all of the text coming from the AIR application.
04:48So this is the basic model for copying data into the clipboard programmatically in ActionScript.
04:54We use the generalClipboard property to represent the singleton instance of the system clipboard.
05:00Before copying any data into the clipboard you clear it and then you call the setData method to pass the data in.
05:08Now in the next video, I will show you how to get data out of the clipboard programmatically using ActionScript code.
05:132
Collapse this transcript
Retrieving data from the system Clipboard
00:00In this video, I'm going to describe how to use the ActionScript clipboard class
00:04to retrieve data from the system clipboard.
00:07I will be using the same application as the previous video ClipboardDemo.mxml.
00:12If you didn't watch that video previously, you will need to go back to that video and follow the steps
00:17to import the project and then open the file ClipboardDemo.mxml.
00:22If you are following along, place the cursor inside the existing pasteData function just
00:27as when adding data to the clipboard.
00:29To retrieve data from the clipboard, you will use the Clipboard class as generalClipboard static property.
00:35To reference the single instance of the system clipboard, place the cursor inside the pasteData function
00:41and declare a variable named pastedString and data type it as a string.
00:49Then assigned the variable by calling the Clipboard's generalClipboard properties getData method
00:55like this, Clipboard.generalClipboard.getData.
01:02There is one required argument, the format name you are looking for
01:05and then an optional argument named transferMode that I will describe later.
01:09For this example, I will use the simplest syntax just passing in a format name, just as when setting data
01:16in the clipboard we use the ClipboardFormats classes constants to indicate what kind of data we are looking for.
01:21I will select the Text Format constant just as before, then I will close the method call with the parenthesis
01:30and then explicitly cast the data type of the return value as a string.
01:34If you look in the API documentation for the getData method, it indicates that it returns in object.
01:40If you know that you are getting back a string you have to say so.
01:43Now I will take that returned data and assign it to the text
01:47out to text areas text property like this, textOut.text = pastedString.
01:56I will save the changes and notice again that the pasteData function is already being called
02:01when the user clicks the button with a label of paste.
02:04I will run the application.
02:06Now I will come back to Flex Builder and returned to the file SimpleTextFile.txt and I'm going to select
02:14and copy the text that was already there, The quick red fox jumped over the lazy brown dog.
02:19I will copy it to the clipboard, I will return back to the running AIR application and click the Paste button
02:26and you will see the data show up in the Destination text area control.
02:30So that's the basic syntax for getting data out of the clipboard regardless
02:34of whether the data was placed there using an AIR application
02:38or some other application running in the operating system.
02:41Use the getData method, you will pass in the name of the format you are looking for, you will explicitly data type
02:47to return value as the type you know it's going to be returned, in this case we know it's going to be a string
02:53because that's what the text format, format name is telling us and then you do something with that data.
02:59In the next video, I will show you how to do the same sort of copy
03:02and paste operation but this time using a complex object.
Collapse this transcript
Transferring complex objects with the Clipboard
00:00In this video, I'm going to describe how to use the system clipboard to move complex objects between AIR applications.
00:07I will be using two different applications named ObjectSource and ObjectDest
00:12that are part of the Chapter02Begin Project.
00:15If you are following along in the exercises, open these two application in Flex Builder.
00:20I will start off in ObjectSource.mxml.
00:24I will open up the code to full screen so we can see as much code as possible.
00:28This application retrieves data from the PHP interface that I described in earlier videos.
00:34So in order to run this application, you will need to make sure that your copy of MAMP
00:38or WAMP is running as it is on my system.
00:41I will run the application and show you the goal.
00:45In this version of the application, the date is retrieved from the server as the application opens up.
00:50I want to be able to select a single row from the Data grid and copy that row to the clipboard
00:56and then in the Destination application I would like to be able to paste that data
01:02so that its data shows up in this data entry form in detail.
01:07So here with the steps.
01:08I will close both the applications and return to the code.
01:12In the Source application, place the cursor inside the existing copyToClipboard method.
01:18Noticed that this method starts off empty.
01:20Now I'm going to retrieve a reference to the currently selected object from the DataGrid.
01:26Noticed that the DataGrid has an id of personGrid.
01:30I declare a variable named dataObj typed as an object and then I will reference
01:37that from DataGrid personGrid.selectedItem.
01:42Now I'm going to clear the clipboard and then copy this data object to the clipboard just
01:47as with the earlier video where I cleared the data.
01:50I'm going to use the Clipboard objects, generalClipboard property and from there I will call the clear method.
01:58Then I will call the Clipboard generalClipboard.setData method.
02:02So far this looks exactly the same as before, but now we get to the name of the format.
02:08If the object that you are copying from one application to another has properties that are exclusively string values,
02:15you can use Text Format as the format name, but if you are moving other kinds of data like integers, numbers,
02:22booleans and so on, you have to create your own custom format name, otherwise,
02:27you run into runtime errors when you try to paste the data in later.
02:31So I'm going to create a very simple format name named customFormat.
02:37In an actual application I would probably use a more descriptive format name but I want to make it clear
02:43that you can make up the name and call it whatever you want.
02:46Then I will pass in the data object dataObj.
02:49I will also make a call to Alert.show to give the user an indication that The data has been copied to the clipboard.
03:04I will save my changes, run the application to test it and you will notice that when the application first opens
03:10up the Copy to Clipboard button is disabled.
03:14That's because its enabled properties bound to an expression that only turns the button on when I select a row.
03:20Now I will click the button and I will get the message that the data has been copied to the clipboard.
03:25Now I will go to the Destination application.
03:29In the Destination application noticed that there is a Bindable variable named aPerson, data typed as an object.
03:36Once again, as in the previous examples I will use the clipboard class's getData method.
03:42I will assign the value of the existing variable aPerson to clipboard.generalClipboard.getData
03:51and then I will use the same customFormat name that I used when I put the data
03:57into the clipboard in the other application.
03:59Because the variable aPerson is already declared and is Bindable and because the textInput controls
04:05within the form below are binding to the properties of that object, when I paste the data in I should see the details
04:13of that appear in the Destination application.
04:15So now I will run both applications.
04:19Noticed that when you are working in Flex Builder, you can run two applications at a time as long
04:25as they each have different identifiers or application ids.
04:29So I will run the two applications and I will place them side by side on the screen.
04:37I will go to the Source Application, select a row of data, I will choose Robert Lombardi and copy it to the clipboard.
04:45I will get the message that the data has been copied successfully.
04:49Now I will go to the Destination Application and paste and you will see the data up here.
04:53I will be able to go back and forth between the two applications.
04:57Select another row and copy.
04:59Go back to the Destination and paste and once again, you will see the data moving between AIR applications.
05:06You can copy and paste complex objects very simply in this manner.
05:09There is a limitation here.
05:11In that if you use strongly typed value objects, you will be able to successfully copy a strongly typed value object
05:18into the clipboard but when you retrieve it at the other side, it will be transferred into a standard objects.
05:24There are ways around this.
05:25There is an interface called IExternalizable which you can implement in your value objects but that takes a good bit
05:31of work but in many it's a lot simpler to just use the standard ActionScript object as the format for complex data
05:39that you move from one application to another using the clipboard.
05:43Now in the next video, I will show you how to do something very similar but this time instead of passing one object
05:48from source to destination application, I will use an array collection and show you that you can pass complete sets
05:55of data from one application to another using the clipboard.
Collapse this transcript
Transferring data collections with the Clipboard
00:00In this video, I'm going to describe how to pass complete data sets
00:04from one AIR Application to another using the system clipboard.
00:08As in the previous videos, I'm going to use the standard Clipboard class and it's setData and getData methods.
00:14But this time instead of passing a simple object, I'm going to use the ArrayCollection class
00:19to hold the data that moves between the applications.
00:23Before I show you the code, I'm going to explain, why this works.
00:27The ArrayCollection class implements an interface named IExternalizable.
00:32The rule for moving data between AIR applications using the Clipboard is that the data object that you pass into
00:38and get out of the Clipboard must implement this interface.
00:42The interface is implemented not just by the ArrayCollection,
00:45but also by also by a class named ObjectProxy,
00:48which wraps an object in the same way that an ArrayCollection wraps an Array.
00:52This interface requires two methods named writeExternal and readExternal.
00:56These methods allow you to customize, how the data is stored, the format of the data and other important aspects
01:03of how the data is represented while it's stored in memory in the Clipboard.
01:07You can actually write your own custom classes that implement this interface.
01:11The exact code for that is beyond the scope of this tutorial.
01:14But what I want to explain here is that the reason we can pass an ArrayCollection between a source
01:20and a Destination Application with the Clipboard is because it does implement this interface.
01:25I will close the Help screen and return back to the code.
01:29I'm using the applications RecordSetSource and RecordSetDest, that are in the Chapter 02 project.
01:35The source application, the code for which is on my screen right now, starts off as the same code I used
01:41in the last video, that is I'm currently allowing the user to choose one row of a DataGrid
01:46and that I'm copying that data object to the Clipboard.
01:49In this version of the Application I'm going to allow the users to choose more than one row.
01:54I'll go down to the DataGrid and I will add a property called allow multiple selection and set its value to true.
02:02The user will now be able to click and select more than one row,
02:06while they hold down to Ctrl key on Windows or the Command key on Mac.
02:12Now I'll go back up to the method copytoClipboard, that's adding the data to the Clipboard.
02:16In the old version of the code, I was passing in a single data object.
02:20I'm going to comment out that line of code, that's getting the data out of the DataGrid and I'll replace it
02:27with a statement, that gets the data out as an ArrayCollection.
02:30It will look like this.
02:32I will declare a local variable name of acData and data type it as an ArrayCollection.
02:39I will initialize the ArrayCollection as a new object using the ArrayCollection class's,
02:45no arguments constructor method.
02:47Notice that when you instantiate an ArrayCollection using this syntax, you can pass in an array as it's source
02:54and it just so happens that the DataGrid has a property called SelectedItems,
02:59which returns an Array of all of the currently selected rows.
03:03So, I will pass in personGrid.selectedItems and now whatever rows the user has selected will be stored
03:13in the ArrayCollection.
03:15Now, I'll go to the line of code that's calling the setData method of the Clipboard.
03:19I'll change the name of format.
03:21I already used Custom Format to represent a single object.
03:25Now, I'm going to use something that's more descriptive.
03:27I'll call it simply people and then I'll change the name of the data object that I'm passing
03:32in from dataObj the old single object to acData, the new ArrayCollection.
03:39That's all of the code I need to change in the source application.
03:42I'll save that and go over to the Destination Application.
03:46The Destination Application RecordSetDEST.mxml already has a bindable variable named acPerson declared
03:54as an ArrayCollection and the identical DataGrid that's the source application,
03:59which is binding to the acPerson ArrayCollection as its data provider.
04:03This version of the Application is not getting its data from the sever.
04:07Instead, It will paste the data in from the Clipboard.
04:10Go to the Paste from Clipboard function which is currently empty.
04:13Make a little bit of space between the braces and assign the value of the bindable,
04:18variable acPerson by calling the Clipboard.generalClipboard.getData method.
04:27We have to match the name of the format that we are passing in.
04:31I'll name it People and then as I did in an earlier video, I'm going to explicitly cast the data as an ArrayCollection.
04:39I know that the data is coming as an ArrayCollection because that's why I put it
04:43into the Clipboard in the source application.
04:46That's all of the code I need to put into this application.
04:49The ArrayCollection is already bindable and it's already bound to the DataGrid as its data provider and the Paste
04:56from Clipboard function is already been called when the user clicks the Paste from Clipboard button.
05:01I'll save the change and run the application.
05:04I'll also go back to Flex Builder and run the source Application and then I'll move the applications around,
05:12so they are sitting side by side on the screen.
05:17Now, I'll hold down the Ctrl key, if you are working on Mac hold
05:21down to Command key instead and then click on Multiple rows.
05:25I'll then click Copy to Clipboard and I will get a verification that the data has been correctly copied.
05:33Now, come over to the Destination Application and click Paste from Clipboard
05:37and you will see the data appear in the destination DataGrid.
05:41In the current version of the Destination Application each time I select new data in the Source Application and copy it
05:48and then come back over to the destination and paste, I'm replacing the existing data.
05:53I could easily refactor the Destination Application to add Data incrementally if I so chose.
05:59There is one another thing I would like to show you in the Destination Application.
06:03It's a good idea in the Destination Application, before you would retrieve data from the Clipboard to first make sure
06:10that the correct format is stored in the Clipboard.
06:14We can do this using a method of the generalClipboard object named hasFormat.
06:19I'm going to go back to the Paste from Clipboard function and add a conditional clause.
06:24If Clipboard.generalClipboard.hasFormat and then I will pass in the name of the format I'm looking for
06:35and then I will put it in a code block and I will move the code
06:42that retrieves the data from the Clipboard into the code block.
06:48I'll reformat the code a little bit for readability and now I will only be retrieving data from the Clipboard
06:55if in fact the data is given in the correct format.
06:57There is also a property called formats which returns an array which is in an ordered list of all
07:03of the formats in which data is currently stored.
07:06Remember that the Clipboard is able to store multiple formats at the same time.
07:10When you use the Clipboard to move data either between AIR Applications or from the operating system
07:15into an AIR application, it's always a good idea to make sure
07:18that the format is already there before you try to retrieve the data.
07:22I'll run the Application one more time just to make sure that the code still works.
07:27I'll try to paste from the Clipboard and you will see that nothing happens.
07:34Now come back to the Source Application and run it again.
07:40I'll select multiple rows, copy it to the Clipboard,
07:45go back to the Destination Application and paste and there is the result.
Collapse this transcript
Transferring images in the Clipboard
00:00In this video, I'm going to describe, how to use the system clipboard to copy an Image in BitmapData format
00:06to the clipboard, so that you can then retrieve or paste it
00:10from within any graphic sensitive application in the operating system.
00:14I will be using an application in the Chapter 02 project named TransferImage.mxml.
00:20I have the application opened on the screen right now and I will show that it's a very simple application
00:26that has a single Image control displaying a JPG file called yosemitefalls.jpg.
00:32There is an existing copyToClipboard function which clears the clipboard and alerts the user
00:37that the Image has been copied, but I will need to add code to actually move the data into the clipboard.
00:43I will run the application so we can see what it looks like before I do the coding and you will see
00:48that it simply displays the image and displays a Copy button.
00:54In order to copy data to the clipboard in Image format, you have to first turn the Image
00:59into something called a BitmapData object.
01:02The BitmapData object, is an actual ActionScript class which you can instantiate very simply.
01:08I will declare a variable named bd standing for BitmapData
01:13and I will instantiate it with the class's constructor method.
01:17Notice that the constructor method accepts two required properties the width and the height.
01:23I will get those values dynamically from the existing Image object.
01:27I will pass in myImage.width and myImage.height and that will ensure
01:37that the BitmapData object's dimensions match the dimensions of my Flex image object.
01:43Next, I will pass the actual image into the BitmapData object like this, I will call it the bd.draw() method,
01:51you pass a source into the BitmapData object and you can use an image object in this location.
01:58So I have now taken the Image object, I have constructed a BitmapData object of the correct dimensions
02:04and I have drawn the BitmapData object based on the contents of the Image object.
02:09Now, I'm ready to pass the data into the clipboard.
02:13I will add a statement that calls the Clipboard.generalClipboard.setData method
02:19and I will pass in a format.
02:21I will use one of the built-in formats from the ClipboardFormats class.
02:28The name of this format is Bitmap Format and it's a format that requires a particular type
02:33of data specifically a BitmapData object and then I will pass in the actual BitmapData object
02:40in the second argument and close the method.
02:44I will Save the change and the Run the application, I once again see the Image displayed
02:49and I will click the Copy button and get the message that the Image has been copied to the clipboard.
02:55Now I can use any Graphics application that allows me to Paste from the clipboard.
03:00I'm going to demonstrate this using Fireworks.
03:04In Fireworks, you can create a brand new Image file and when you do this, it will automatically pick up the dimensions
03:09of any Image that's in the clipboard and propose that as the new size of the image.
03:15From the Menu I will select File, New and notice that the Width and Height of 320 by 240 Pixels and the Resolution
03:23of 72 Pixels/Inch, match the source file that I just copied to the clipboard.
03:28I will click OK and now I will right click and Paste and you will see that the Image was transferred
03:36from the AIR application into the system clipboard and from there into my Graphics application.
03:42Now if you don't have Fireworks, you should still be able to do this with many graphics application.
03:48For instance I will open up Paint, which is a standard graphics application that comes with all copies of Windows
03:54and I will Paste or press Ctrl+V and once again you will see the Image pasted into the application.
04:00So this a very simple way of getting Image data from an AIR application out into the general operating system clipboard,
04:08so that it can then be pasted into other graphics applications without having to save the file to disk
04:13and then exclusively retrieve it and then copy and paste within the native application.
Collapse this transcript
Deferred rendering
00:00In this video, I'm going to describe how to use a feature of the ActionScript clipboard,
00:05that allows you to defer the creation or the rendering of data until the moment
00:09when a Destination Application requests it.
00:12I will be working in two applications I have used previously, ObjectSource and ObjectDest and I'm going
00:18to make some changes in the Source Application that defer provision of data to the clipboard until the moment
00:24when the Destination Application tries to retrieve it.
00:27I will open up ObjectSource.mxml to full screen, so we can see as much code as possible
00:32and then I will go down to the code section.
00:36Right now, when the user clicks the Copy button, we are copying directly into the clipboard.
00:41Whichever row of the DataGrid, you have selected at the moment, they clicked the button,
00:44will be the data that's retrieved in the Destination Application.
00:48To use the deferred creation capability, create a function that returns the data you want to place in the clipboard.
00:55I will simply call it getData and I will data type the return value as an Object.
01:02In the body of the function, I will return the currently selected row from the DataGrid.
01:13Now, I'm going to modify the copyToClipboard function in a couple of ways.
01:17I'm no longer going to retrieve the data from the DataGrid, I'm going to clear the clipboard,
01:23but then instead of directly passing data into the clipboard,
01:27I'm going to call a function called setDataHandler.
01:31The setDataHandler function takes two required arguments, the Format name which can stay the same and then a reference
01:38to the function that should be called, when the data is requested that will be getData.
01:44Now when the user clicks the Copy button, it will simply register the call back function getData
01:50and then when the Destination Application retrieves the data from the clipboard
01:54that will cause this function to be called instantly.
01:57I will save the changes and run the application and then I will go back to Flex Builder
02:04and run the Destination Application as well and I will arrange the application,
02:10so we can see both of them on the screen at the same time.
02:14Now I will click into a row and click Copy to Clipboard and I get a message that the data has been copied to clipboard.
02:22But then I will select another row of data.
02:24I will move the cursor to James Jaeger instead of Brad Lang, then I will go to the Destination Application and Paste
02:32and notice that I pasted the data that's currently selected rather
02:36than the data was selected at the moment I clicked the button.
02:39Notice something interesting about this feature, if I go over back to the Source Application
02:44and then I immediately try to Paste again, I simply get the same data again.
02:49You can only call the function once for each time the setDataHandler method is called in the Source Application.
02:56But if I click the button and then select an entirely different row, then go to the Destination Application again
03:04and Paste, I once again get the currently selected data rather than the data
03:09that was selected at the moment the button was clicked.
03:11So this is called deferring of creation or rendering of data.
03:15Instead of pushing data directly into the clipboard, you simply tell the clipboard object,
03:21when the data is requested, this is the function that should be called
03:25to determine, what type of data and value is returned.
Collapse this transcript
3. Creating Drag-and-Drop Interfaces
Understanding drag-and-drop interfaces
00:00In this chapter of the video series, I'm going to describe, how to implement drag and drop operations that allow you
00:06to move data between AIR applications and between an AIR application and the hosting operating system.
00:12If you are following along with the exercises, you can work along in these exercises
00:16by importing a project from your exercises folder.
00:19Go to the Flex, go to Menu and select File, Import, Flex Project, browse for an Archive File,
00:29go to the Chapter03 folder in the Exercises area
00:33and select Chapter03BeginProject.zip, click Finish and Import the Project.
00:42Then open the Project in the Flex Navigator view, go to the Source folder and open the file FlexDragDrop.mxml.
00:51In this video, I'm going to show a simple approach to doing drag and drop within a Flex application,
00:58using tools that are available whether you are building an application for deployment over the web or to the desktop.
01:04I will maximize the Editor to see as much code as possible and show you that this application retrieves data
01:10from a server and then displays it in a DataGrid.
01:14There are two DataGrid controls in this application side by side.
01:17I will run the application to show what it looks like, the data appears initially in the first DataGrid,
01:24we want the user to be able to click and drag data from the first DataGrid to the second DataGrid.
01:29In Flex applications, you can implement drag and drop very simply.
01:35If your Drag and Drop Initiator and your Drag and Drop Target are both list controls.
01:41The DataGrid for instance is one of the list controls that supports this feature.
01:45If you want to be able to drag and drop data from a list control, simply add a property called dragEnabled
01:53and set it's value to true, then go to the control that you want to use as the drop target
02:00and add a dropEnabled property and set it's value to true as well.
02:05Save your changes and Run the application.
02:13Once the data appears in the first DataGrid, you should now be able to click on any row, drag it,
02:18you will see a little image of the selected row up here and when you move the cursor into the drop target DataGrid
02:26and release the mouse button, the data is copied from one DataGrid to the other.
02:31I will demonstrate that again with the second record and a third and I will also show you
02:37that using this automated drag and drop feature, you can actually place data in specific locations
02:43by paying attention to the selector bar that appears in the DataGrid.
02:46If you want to be able to drag and drop multiple items, simply go the Initiator DataGrid
02:52and set it's allowMultipleSelection property to true, from the application again and this time hold down the Ctrl
03:00or Command key, depending on which operating system you are working in and click and select multiple rows,
03:06then release the Command or Ctrl key, click on one of the selected items and drag and you will see
03:12that you are actually moving multiple rows into the Target DataGrid.
03:17There is a more advanced and more powerful architecture for creating drag and drop within a Flex application,
03:22using a class called the DragManager, but that's not the subject of this video series.
03:27We are interested here in what you can do with drag and drop in AIR application in terms of moving data
03:33between multiple applications and also moving data back and forth between an AIR application and the operating system.
03:40So that will be the focus of the rest of these videos in this chapter.
Collapse this transcript
Accepting native dropped data
00:00In this video, I'm going to describe how to accept a Native Drag and Drop operation, where the drag
00:06and drop operation is initiated by some other non-AIR application hosted by the operation system.
00:12I will be working in the application NativeDragDrop.mxml, that's a part of the Chapter03BeginProject.
00:19If you are following along in the Exercises, open that application now.
00:23This is a simple application with two labels, one that will be a static label with the text of Drop text anywhere!
00:30and the other that's a targetLabel.
00:33They both have a fontSize of 12, the second label doesn't have an initial text value,
00:38we will be filling in that value upon text being dragged and dropped into the application from an external application.
00:45To get started, go to the application's root element, WindowedApplication
00:50and add an event listener for an event called nativeDragEnter.
00:56When the mouse cursor enters the application during a Drag and Drop operation initiated by any other application,
01:03this event will tell you that a Drag and Drop operation is pending,
01:06you will react to that by passing the generated event object to an event handler function.
01:12We will call it dragEnterHandler and we will pass the event object,
01:19then go down to your Script section and create that function.
01:28The function receives an event object typed as a class named NativeDragEvent
01:35and as with all good event handler functions, returns void.
01:39Within the dragEnterHandler function, I'm first going to add a trace command
01:43to tell me that the DragEnter event happened.
01:47Within the Trace function I will put in a simple literal string of Drag enter event and then I will test this
01:56by saving and running the application in Debug mode and then I will open
02:01up another application that's capable of dragging and dropping text values.
02:05On Windows, you can use WordPad, on Mac you can use TextEdit
02:09or any other text editor that's capable of initiating a Drag and Drop operation.
02:14Now I will select some text and drag it into the application and then in the console in the background you will see
02:21that every time the cursor moves over the AIR application, the trace command is executed and this tells me
02:28that in fact I'm successfully detecting, when the DragEnter event occurs.
02:33So, now I will close the application and return to the code.
02:38In order to accept the event, you will use a class named NativeDragManager.
02:45The NativeDragManager class has a method named acceptDragDrop,
02:50you pass into it what we call the target object.
02:54In a Flex application, you can usually refer to this meaning the application itself and that tells the Flex application
03:01that if the user releases the mouse button, while the cursor is
03:05over the application then will accept the drag and drop event.
03:09Now we need to handle that event.
03:11When the user releases the mouse cursor, we will get an event named nativeDragDrop and once again we will listen
03:19for the event and handle it with an event handler function, which I will call dragDropHandler.
03:26I will once again go down to the script section and create that function
03:31and I will receive once again an event object typed as nativeDragEvent.
03:40Within the dragDropHandler, I will retrieve the data
03:44from the clipboard object that's a part of the drag and drop architecture.
03:48I will assign the written value to the label control that I already declared targetLabel.
03:53So I will start off with TargetLabel.txt=event.clipboard.getData,
04:01this is exactly the same getData function that I showed how to use in the previous chapter about using the clipboard.
04:09I have pass in a format name to designate what kind of data I want to retrieve and once again,
04:15as with standard clipboard operations, I will use the ClipboardFormat class and its Text_Format constant.
04:23I also need to specifically type cast the value that's returned from the getData method using as String.
04:30As I described in the previous chapter about the clipboard the getData method expects to return an object.
04:37If you know you are receiving the data in the form of some other class, you need to say so.
04:41I will save my changes and run the application, then once again I will go over to my initiator application,
04:49I'm using WordPad and I will drag and drop the text into the application.
04:54Notice the cursor shape changes as soon as I accept the operation and when I drop the data,
05:00it's placed into the application and my code retrieves the data from the clipboard and displays it in the targetLabel.
05:07I can do this as many times as I like, I will type in another phrase in the TextEditor,
05:14select it and drag and drop it into the application.
05:18So you will see that each time the initiator places data into the clipboard and then I accept the Drag
05:24and Drop operation and react to the drop event I'm able to get the data out.
05:29In the next video, I will show you how to do something very similar using a special kind
05:34of clipboard format called a File List.
Collapse this transcript
Dragging and dropping file references
00:00In this video, I'm going to describe how to use the drag and drop native interface to move file references
00:06from the operating system into an AIR application.
00:09I will be describing the use of references to files much more thoroughly in a later chapter,
00:13all about access to the local file system.
00:16For now, what's important to understand is that when the user initiates a drag and drop operation,
00:21from an application, that's native and hosted in the operating system and drags a file into your AIR application,
00:29that's a Native Drag and Drop operation where the format is something called File List.
00:34To demonstrate this capability, I will be using an application named DragFileReferences that's
00:39in your Chapter03Begin folder.
00:41If you are following along in the exercises, open the file now.
00:45You will see that this application is already listening for the event nativeDragEnter
00:50and nativeDragDrop that I demonstrated in a previous video.
00:54There is a label with a text value of Photo Gallery and a Tile container, which will layout objects in rows
01:01and add as many rows as it needs to display the contents that I will be adding.
01:06I will run the applications so we can see the initial interface and you will see that the tile is represented
01:12by the rectangular white area with the black border.
01:16When the user drags an image file into the application, I'm going to display the image in the Tile container
01:23by detecting the Drag and Drop operation and getting the File Reference that was dragged into the application.
01:30I will close the application and return to the code.
01:32if you are following along with me, place the cursor in the dragEnterHandler function,
01:38notice that if it receives an event object typed as the NativeDragEvent class.
01:43The first step is to detect whether the clipboard that's associated with the Drag
01:48and Drop operation contains the File List format.
01:51I will put in a conditional clause that's looks like this, if event.clipboard.hasFormat then as in previous exercises,
02:02I will use the ClipboardFormats class as constants to indicate which format I'm looking for.
02:09I'm looking for this format, File_List_Format.
02:12I will close the conditional block with a couple of ending parenthesis and put in the braces that will serve
02:19as the code block for this conditional clause.
02:22If the event object's clipboard has the appropriate format,
02:26I will use the NativeDragManager class's acceptDragDrop function and pass in reference to the application
02:35to indicate that I will accept the Drag Drop Operation targeting the application.
02:39Now once the user drags the object into the application, the cursor shape will change to indicate to the user,
02:46that they are allowed to drop the object.
02:49I will demonstrate that behavior.
02:51I will run the application.
02:54Now I'm going to move the application over to the side and then resize Flex Builder, so it's only showing part
03:00of the screen and bring back the Flex Navigator view.
03:05Notice in this project there is an images folder, which contains some graphic files.
03:10The Flex Navigator view essentially exposes the behavior of the Operating System's File Management System.
03:17Window's Explorer and Windows or Finder on the Mac.
03:20When I click and drag an object out of the file list and move it into the AIR application,
03:27as I move the cursor out of the File List and into the AIR application, notice that the cursor graphic indicates
03:33through the plus(+) icon, that I'm now allowed to drop the object.
03:38That's the result of calling the acceptDragDrop function.
03:41I'm ready now to accept the drop action, I will close the application and return to the code,
03:48and show it in full screen, so that we can see as much of the code as possible.
03:52In the dragDropHandler function the first step is to get the data out of the event object.
03:59I'm going to declare a variable called arFiles typed as an array and I will set the value of that Array
04:06from this expression, event.clipboard.getData, then I will pass in the format name I'm looking for,
04:15as before I will use the constant ClipboardFormats.FILE_LIST_FORMAT and then close that part
04:20of the expression with a closing parenthesis and explicitly data type the value that's returned as an Array.
04:27The nature of the data that's stored in the clipboard as File List is that it's an array of file objects.
04:34Each file object in the Array has a property called nativePath, which returns the location of the file
04:40on the local disk, starting from the root folder.
04:44To get that value out, I will create another variable called fileLocation typed as a String and I will get that value
04:53from arfiles, I will look for the first item because I know I'm only dragging a single item for the moment
05:00and then I will put in the property nativePath.
05:04We will learn more about the nativePath property in the later chapter about accessing the local file system.
05:10Next I will create an image object, I will declare a variable named img typed as an Image.
05:18Notice that as I selected the Image class from the list of available classes,
05:22an import statement was automatically created by Flex Builder at the top of the Script section.
05:28Continuing that line of code, I will instantiate the image object by calling it's no argument constructor
05:35and I will set the Image object's source.
05:38When you set the source of an Image object using the local file system,
05:42you should always prefix the actual file location with a prefix of file:///.
05:49If you forget this step, things will work fine on Windows,
05:54but on the Mac the image will probably not show up correctly.
05:57So I'm going to set the source property of the Image object with file:/// and then append the fileLocation property,
06:06I could have written this syntax a lot more concisely, combining these statements into single statements,
06:12but I want you to see each step of the process along the way.
06:15I extract the array of files out of the event object's clipboard using the getData method,
06:20I will get the file location from the nativePath property of the first file in the array,
06:26I instantiate an Image object and I set its source.
06:31Finally, I will add this image object to the Tile that I have already declared,
06:35using the syntax imageTile.addchild and I will pass in the Image object.
06:41I don't need to retain a reference to that Image object, this is only for displaying the image once.
06:46I don't for instance need to be able to remove the Image object from the Tile,
06:50later on in the current application, that's all of the code.
06:54Now I will run the application, I will once again move the application over to the right side of the screen,
07:01restore the size of Flex Builder and then look at the Flex Navigator view
07:06and I will drag an image into the application.
07:09This time when I drop the image, the image is added to the Tile.
07:13I can continue this operation as many times as I want to.
07:17The nature of a Tile container, is that each time I add a new image in,
07:21it's going to create additional rows as needed.
07:25Each of the cells within the Tile has to be of exactly the same size.
07:29There might be a little bit more work to do to make this a little bit more attractive,
07:33but you can see that the functionality is working correctly.
07:36You can drag images from any application that knows how to provide a File List.
07:41Another application that knows how to provide a File List is in fact Windows itself.
07:46I will go to the Exercises folder that's on my local system, I will go to the Assets folder, to images,
07:54to thumbs and from there I can drag and drop directly from the operating system, I will select this one, crawfish.jpg,
08:02once again drag into the application and there is the image and I can keep doing that with as many images as I like.
08:10So that's a look at how to use Native Drag and Drop to move File References from the operating system
08:16or from applications that know how to provide this kind of drag and drop capability
08:20and to move those File References into an AIR application.
Collapse this transcript
Initiating native drag-and-drop
00:00In this video, I'm going to describe how to initiate a Drag and Drop operation from an AIR application that allows you
00:06to transfer data from an AIR application to another AIR application
00:10or to any other application running in the operating system.
00:14For this demonstration, I'll use an application file named DragOut.mxml.
00:19If you are following along with the exercise files, you will find this file in the Chapter 03 Begin Project.
00:25Open the file and then expand the Code to full screen.
00:29In the beginning version of the application, there is a simple Label and Image.
00:33The image control is displaying a graphic called yosemitefalls.jpg.
00:37It's listing for the mouse down event, and when the user clicks the mouse button while it's over the image,
00:43it will call the startDragDrop function, that's already been defined.
00:47Place your cursor within the function.
00:49The first step in transferring the Bitmap graphic to another application, that can accept Bitmap data in a Drag
00:55and Drop Operation is to transfer the image controls data to a Bitmap data object.
01:01I'll declare a new variable named BD and data type it as BitmapData.
01:08I'll initialize that using the BitmapData classes constructor method,
01:13and I'll pass in the two required values, the Width and Height getting them from the image control myImage.
01:25Next, I'll fill in the BitmapData by calling it Draw Method, and I'll pass in the image control,
01:32and that will transfer the image control's BitmapData over to this new object.
01:37In the previous chapter about the Clipboard, I only used the Clipboard Classes, General Clipboard Static Property,
01:44referring to the singleton instance of the system clipboard.
01:47When you do a Drag and Drop operation, you don't use the system clipboard, instead you create a single instance
01:53of a clipboard object, and then you push the data into that clipboard object and that's the clipboard
01:59that you'll pass around with the Drag and Drop operation.
02:02So my next step is to create a new variable data typed as a Clipboard.
02:06I'll name it Clip.
02:07And I will set its data type as Clipboard, and initialize it using the clipboard classes no arguments constructor.
02:16Now, just as I did with the general clipboard in previous exercises,
02:20I'll call it the clipboard objects set data method, and I'll pass in a format name.
02:26The name of this format will be one of the five standard formats in the clipboard formats class.
02:31I will select ClipboardFormats.BITMAP_FORMAT, and then I'll pass in the data object BD and close the method call.
02:41My next step is to initiate the Drag and Drop operation.
02:44For this purpose, I use the NativeDragManager class and it's doDrag Method.
02:49The doDrag method takes a number of arguments, some of which are required and some optional.
02:53The first two arguments that are required are the Drag Initiator and the Clipboard Object.
02:58The Drag Initiator for this application will be the application itself, which I'll refer to as this.
03:04Next, I pass in the Clipboard Object that contains the data.
03:08I named it Clip previously, and then optionally, you can add a drag image which is a BitmapData object,
03:15which is a graphical presentation that the user sees as the mouse moves across the screen.
03:20I have already created a BitmapData object that represents the image I'm moving.
03:24So I'll pass that in this position as well, making another use of that same object.
03:29That's it.
03:30Here are the steps I followed again.
03:32I have created the BitmapData Object, and filled in its data from the Image Control.
03:36I have constructed a Clipboard Object and filled in its data using the Set Data Method,
03:42and then I have initiated the Drag and Drop operation using the Native Drag Manager's Do Drag method,
03:48passing in reference to the Initiator, the Application, the Clipboard Object which I named Clip,
03:53and the BitmapData Object which I'm using as the image the user sees as they move the cursor across the screen.
04:00Here's the visual result.
04:02I run the application, and now as I Click and start to move the cursor,
04:07you will see a copy of the image show up on the screen.
04:10Notice that it's slightly transparent.
04:12I can see through the top level image that's being used to represent the Drag Operation, and see the background image.
04:19Now, as you move the image out of the AIR application, you will see the image goes away.
04:25That's because the other applications aren't capable of displaying it.
04:28That's okay though.
04:30Now, I'm going to show you some of the things you are able to do as you drop the image.
04:34If you have an Image Manipulation Application, that's capable of accepting this sort
04:38of Drag and Drop operation, you can start it up.
04:42For instance, I'm a fan of Adobe Fireworks.
04:44Fireworks is one of those applications that's capable of receiving a Drag and Drop operation.
04:50If you have Fireworks, open it up.
04:53You can also try any other graphical editing application you like such as Photoshop.
04:58Although, not all applications are able to do this.
05:00For instance, if you were to try using Paint, the very simple graphical application that comes with Windows,
05:06you would find that would not accept the Drag and Drop operation correctly.
05:09I'll create a new file in Fireworks, then I'll switch back to my AIR application,
05:18and I'll try dragging the graphic into the application.
05:21And you will see that it successfully transfers the BitmapData over to the graphical application.
05:27You can also try this if you are working on the Mac, dragging the image directly to the Mac desktop.
05:33You will see that the image is dragged onto the desktop, and it's created something called a Picture Clipping.
05:39If you are not working on the Mac, and you don't have any great applications that are able to accept this kind
05:44of operation, here's another application that's in the Chapter 03 Project.
05:49Open the application BitmapTarget.mxml.
05:53Take a look at its code.
05:54In this application, we first have a dragEnterHandler function that detects whether there is a Bitmap format
06:01in the clipboard, that's being transferred to it, and then it accepts the Drag Drop operation.
06:08Within the dragDropHandler function, we are calling the getData function, we are passing in Bitmap format
06:15as the format name, and we are extracting the data as a BitmapData object.
06:20Then, we are constructing an instance of a class called Bitmap wrapped around the BitmapData.
06:24And finally, I'm calling the stage object addChild method to add the Bitmap to the stage.
06:31I'll run the application, and then I'll position over it on the right side of the screen,
06:36go back to the DragOut application, position it on the left side of the screen, so I can see both applications.
06:42And then, I'll Click and Drag the image from the first application, drop it into the second application,
06:51and you will see that it's successfully being dropped in the target application.
06:55So again, you are not limited to dragging and dropping just between AIR applications.
07:00When you initiate a Native Drag and Drop operation from an AIR application,
07:04that data can be moved into any other application hosted by the operating system, that's capable of supporting
07:11that particular kind of Drag and Drop operation.
Collapse this transcript
4. Using the File System
Understanding file system access in AIR
00:00In this chapter of the video series, I'm going to describe how applications deployed
00:04on the Adobe Integrated Runtime can access the local file system and create, read and write files,
00:11and also create and manipulate directories.
00:15All applications deployed on AIR whether they are built in Flex, Flash or Ajax have the ability
00:20to read and write to the local file system.
00:23This is because applications deployed as native applications on the operating system aren't subject
00:28to the same security rules as applications deployed through a web browser.
00:32When a Flex application is downloaded to the web browser and hosted by the Flash player.
00:37It's only allowed to operate within the web browser Sandbox and is not allowed to reach outside
00:42and touch the file system, local databases or printers.
00:46Applications installed locally can do all these things.
00:50When you work with the local file system, one of the choices you will need
00:53to make is whether you work synchronously or asynchronously.
00:57I'll talk about this concept in more detail in later videos, but briefly all file operations have
01:03to be handled either synchronously or asynchronously.
01:06When you handle a file operation synchronously such as reading or writing data, the application thread is suspended
01:13for as long as the file operation is being executed.
01:16Here's what this means to an AIR application.
01:18The Adobe Integrated Runtime has multiple threads, but only one thread that's dedicated to the front-end application.
01:25If you use synchronous file operations, any operations in the application itself such as animations
01:31or user interactions are suspended while the file operation is happening.
01:36If you are reading or writing a large amount of data,
01:38this can result in the application becoming temporarily unavailable to the user.
01:43So whenever you execute file operations, that might take more than an instant.
01:47You should always use asynchronous operations instead.
01:50The nature of an asynchronous operation is that it executes the file operation in the background.
01:56The front-end application thread is still available to execute animations and receive user interactions.
02:02And whenever the asynchronous file operation is complete, it will dispatch an event that reports to you
02:08that the operation is complete and you can react.
02:11All of this is made capable by certain Key ActionScript classes.
02:16The file class is designed to represent a single file or directory in the local file system.
02:21The file class executes tasks such as copying, moving and deleting files,
02:26and also has tools for browsing the local file system.
02:29When you use the file class to browse, you see the operating system's browsing interface.
02:34For example Windows Explorer's browsing dialog or on Mac OS X, the finder's browsing interface.
02:41The other Key ActionScript Class is the FileStream.
02:44This class is responsible for reading and writing data to the local file system, and it can read
02:49and write with multiple modes including UTF or Unicode text or Binary Streams.
02:56All of these abilities and rules apply to all AIR applications,
02:59regardless of whether these applications are built in Flex, Flash or Ajax.
03:04Flex developers however get some extra tools.
03:07There is a set of components based on the Flex List Controls.
03:11The ComboBox, DataGrid, List and Tree controls have been re-purposed into file system versions of the same controls.
03:19Whereas the Base List Controls deal with data in the form of array collections or XML list collections typically.
03:26The file versions of these controls get their data directly from the file system, and they allow the user to navigate
03:32and select files and directories from the file system visually.
03:36There is also a special component called the FileSystemHistoryButton that I'll be describing later.
03:41This button gives you a very easy way of linking into the data provider for a list control or a DataGrid control
03:48and letting the user move forward and back through the directory and file selections.
03:53So in the following videos, I'll demonstrate many of these capabilities.
03:57The ability to represent and manipulate files and directories on the file system, to copy, move,
04:01and delete these files, to select the files using the browsing interface or using the Flex components,
04:08and the ability to read and write data to files that are on the local system.
Collapse this transcript
Using directory aliases and the File class
00:00In this video, I'm going to describe the use of the ActionScript File Class, that points to individual files
00:06or directories within the local file system.
00:08For all of the demonstrations in this chapter, I'll be working from a project that's part of the exercise files.
00:14If you are following along with the exercises, go to Flex Builder Menu and select File, Import, Flex Project.
00:24Click the Browse button next to Archive file and select Chapter04BeginProject.zip.
00:31Notice that there is also a Chapter04EndProject.zip
00:34that contains the completed source code for all of these demonstrations.
00:39Select the File and then click the Finish button to Import the Project.
00:45Next, go to the Flex Navigator, View and open the Project and then open it's Source folder.
00:52You will find a number of applications that are ready to use, then locate the applications, DirectoryAliases.mxml
00:59and double-click it to open it in the Editor.
01:02If the application opens in Design view click the Source button to look at it in Source view
01:06and then I'll maximize my Editor, so I can see as much code as possible.
01:10This is a very simple beginning application that has a button
01:14which when clicked calls a function, called testAliases.
01:18Place the cursor inside the function and you will be ready to start coding.
01:22In order to represent a file or a directory on disk, you create an instance of the ActionScript File Class.
01:28As with all variables you can name the variable anything you want.
01:33In this case, I will declare a local variable to the function named f and data type it as a file.
01:39Notice that you don't need an Import statement to address the File Class.
01:43Now, I will instantiate the File Class by calling the Classes Constructor Method.
01:48When you create a new File object, you can pass in an initial path.
01:53The path is a string value, which can point either to a particular file or a directory on disk
01:59or to a directory file that hasn't yet been created.
02:02For this first example, I'm going to pass in a simple String of file:///.
02:08This is a special prefix that's used in the AIR applications,
02:14that addresses the root directory of the current volume.
02:17On Windows for instance, if I'm working on the C drive, it would address the C drive root, on Mac it would do the same.
02:24Now to determine what the current File object is pointing too.
02:28I'm going to trace a property of the File object called the nativePath.
02:32The nativePath property of the File object returns a string value.
02:37It's the location of the file or directory represented by this object, starting from the volume root.
02:43I'll save my changes, and now I'm going to Debug the application.
02:49Notice in the background I can see the Flex Builder console.
02:52When I click the button, I'll create an instance of the File object pointing to file:///
02:58and then I'll trace the actual location from its nativePath and you will see
03:04that the nativePath value returns a simple backslash ().
03:07If you are working on Mac, you should see a forward slash (/) instead and that represents a basic difference
03:13between the two operating systems that the Windows Operating Systems uses backslashes () to represents directories,
03:19well Mac and other Unix based systems use the forward slash (/).
03:23There are other string based prefixes that you can use, to address various key directories on the file system.
03:29For instance, two important directories are called the Application Directory and the Application Storage Directory.
03:35There are other important directories called the Desktop Directory and the User directory.
03:40Each of these can be addressed in one of two ways, either through a string base prefix
03:44or through a static property of the File Class.
03:48I will demonstrate the difference between the two using the Application Directory.
03:52I am going to create another File object, this time I'm going to name it appDir, type casted as file
03:59and once again I'm going to instantiate it using New File and I will put in a prefix of app:/.
04:05This is a reserved prefix in AIR which means the directory in which the application executable is stored.
04:13This is a reserved string based prefix which references he Application Directory that is the directory
04:19in which the application executable is stored.
04:23Now I'll trace the results of that expression using the syntax appDir.nativePath.
04:28I can address exactly the same directory using a static property of the File Class named Application Directory.
04:37I'll name this variable appDir2, once again data type it as a file and this time I'll get a reference
04:44to that directory using File.applicationDirectory, then I'll copy and paste the trace command.
04:53I'll change the second trace command to output the nativePath of appDir2.
04:57I will Save my changes and Debug again I will click the button to execute the function and you will see
05:04that the two coding approaches give you the same result.
05:08In either case, you have created a new File object, which points to the location
05:12of the application that is where it's running from.
05:15In this case it's the Output folder of the Flex Builder Project than Debug.
05:20There are three other special directories that you can address in this manner.
05:24The User Home Directory is a directory that's unique to each individual user on the local file system.
05:30The actual location of the user directory will differ depending
05:32on whether you are working on Mac, Windows Vista or Windows XP.
05:37I am working on Windows Vista in this demonstration.
05:39So I'll show you what it looks like when I run it on this system and then describe what happens on the others.
05:44I'll create another variable.
05:46This time they will be named userDir, I'll set it as a file and this time I'll get a reference using File.userDirectory
05:55and then once again I'll trace the result userDir.nativePath.
06:02I run the application in Debug mode, click the button to test and you will see that the User Directory
06:08on my system Windows Vista points to C:Usersdavid in a very similar fashion on Mac,
06:17you would see a named a directory under the Users folder.
06:20Well, on Windows XP, it would be under the Documents and Settings folder
06:24and again the subdirectory would be named for the user name.
06:27There are other directories that you can address directly within the Home Directory of the user.
06:32I'll create two more and then trace them.
06:36The first will be for the Desktop Directory.
06:44This variable will address the Desktop Directory that is the directory that represents the Visual Desktop
06:50that you work with on either Windows or the Mac.
06:53I'll trace the nativePath of the Desktop Directory and then I'll do something very similar
07:00for something called the Docs Directory, that is to save the users own documents area.
07:10Once again I'll trace, I'll save and run the application in Debug mode.
07:20Test and you will see that I'm pointing out to the Desktop Directory
07:25and the Documents Directory under my User Directory.
07:30There is one other critical directory that you work with.
07:33It's called the Application Storage Directory.
07:35This Directory is once again unique to each individual user,
07:39but it's designed to also be unique to the particular application.
07:43I'm going to create one more variable and I'm going to call this storageDir, data type it as a File and reference it
07:52from File.ApplicationStorageDirectory and then once again trace its actual location.
07:58I run the application in Debug mode.
08:09Test the application and this time you will see a much longer nativePath.
08:13I will maximize the console, so we can see the entire path.
08:17Once again the actual location of this folder will differ,
08:20depending on whether you are working on Windows XP, Windows Vista or Mac.
08:25Working on Windows Vista, the Applications Storage Directory shows up under an AppData folder.
08:30On Windows Vista, the folder shows up under the User's Home Directory under that in AppData sub-folder.
08:37Under that a directory named Roaming and then a directory which is named for the application id.
08:44Notice that the full application id is used in this case com.lynda.airflex.chapter04 and then the name
08:52of the application DirectoryAliases and then finally under that directory another directory named Local Store.
08:59The Local Store directory is always named the same regardless of which operating system you are on,
09:04but the rest of the actual location of the this directory will again differ from one operating system to another.
09:10So that's basically how you address the various directories.
09:14Once again, there are string based prefixes that you can use instead
09:18of these static properties, but they give you the same result.
09:22They allow you to address the special directories that are either unique
09:25to the user or to the user and the application.
Collapse this transcript
Comparing synchronous and asynchronous file operations
00:00In this video, I'm going to describe and demonstrate the difference between synchronous and asynchronous file access.
00:07As I described in the first video in this chapter synchronous file operations are executed
00:11as part of the main application thread.
00:14For the period of time it takes to execute a file operation, the application thread is suspended and any animations
00:21or user interactions are prevented during this period.
00:24Asynchronous file operations allow the main application thread to keep executing,
00:29while the file operation is executed in the background.
00:32To demonstrate the difference, I'll be working with two applications.
00:35The first is named SynchronousFileAcess.mxml.
00:39If you are following along in the exercises, go to Flex Navigator view and open SynchronousFileAccess.mxml.
00:47The beginning application has a button that calls a function named Copy File
00:52and then it has instance of a component named Animated Component.
00:56I will run the applications so you can see what the Animated Component is doing.
01:01It uses a timer to simply move an object to cross the screen every tenth of a second.
01:06It's a very simple animation that was done completely in Flex.
01:10If you are curious about how that animation was done, just take a look at the Source code for the Animated Component.
01:16It uses a timer object to make a call to a function, ten times a second to move a simple rectangle across the screen.
01:23Now go back to SynchronousFileaccess.mxml,
01:26all file operations can be executed either synchronously or asynchronously.
01:31For instance, in order to copy a file there are methods called copyFile and copyFile async.
01:38The copyFile method executes an operation synchronously and copyFile async does the same thing asynchronously.
01:44For this demonstration, I'm going to create two file objects.
01:49One pointing to a Source file, that's fairly large and the other pointing
01:52to a destination to which we want to copy file.
01:55The first variable will be declared within the function copyFile.
01:58I will name the variable fSource, data type it as a File and instantiate it, using new File
02:07and then I'll use the string prefix that points to the Application folder app:/ from there to the assets folder
02:15and from there to a file called largecontacts.xml.
02:20This is a file that has something like 10,000 records in an XML file.
02:24So it's going to take a couple of seconds to copy even on a fast computer.
02:28Now, I'll create another variable named fDest for the destination file.
02:32Once again data type it as a File, and I will point this file to a location within my application storage area,
02:40app-storage:/ and I'll name the destination file simple contacts.xml.
02:48Now, I'll copy the source file to the destination file.
02:51The code will look like this, fSource.CopyTo once again notice that there is a CopyTo and a CopyToAsync
03:00and I'll pass in the following values, fDest which is the destination location and then a value of true,
03:07which basically means if the file is already there just overwrite it and then a I'll pop-up an Alert dialog
03:14that tells the user that the copy operation is complete.
03:20I'll save the changes and run the application.
03:24Notice that the application starts its animations as it starts up.
03:27That's because the animated component launches itself upon Application Startup.
03:32Now I'll click the button and notice that for the duration of the operation that is for as long as it takes
03:38to move the content from one location to another.
03:42The animation freezes.
03:45I will run the copy operation again and once again you will see
03:50that the little box freezes its position, during the copying operation.
03:55Now I will go to another application, this one AsynchronousFileAccess.mxml
04:01and it's very similar to the version that I just created.
04:04This time before I execute the copying functionality, I have added an event listener for an event named complete.
04:12Notice that when the complete event occurs, I'm calling a function called fileCompleteHandler.
04:18That function has been declared below it's name is fileCompleteHandler,
04:22it receives an event object as an argument and returns void.
04:26I'm going to make two changes to this file.
04:29I'm going to move the Alert.show call that is the dialog box that tells the user
04:34that the operation is done into the function fileCompleteHandler.
04:38By the way, I did that by dragging and dropping the code.
04:41Something you can do now in Eclipse 3.3 and then I'll change the function that I'm calling
04:46from this source file from CopyTo to CopyToAsync.
04:53Now, whenever the file operation is completed, I'll get the complete event dispatched
04:58and that will cause my handler function to be called.
05:01I will run the application and let's watch happens.
05:04I once again click the Copy File button and you will notice that the box continuous to move
05:13across the screen even the while file operation is in progress.
05:17I will execute the command again and once again the animations continues.
05:23So that's the difference between synchronous and asynchronous file operations.
05:27Throughout the rest of this chapter, I'll be using synchronous operations, just for their code simplicity,
05:33but it's worth knowing that whenever you start dealing
05:35with large files you should probably move over asynchronous operations instead.
Collapse this transcript
Browsing for files and directories
00:00In this video, I'm going to describe how to use the File class to allow the user to browse for
00:05and select a file from the local file system.
00:08For this demonstration, I'll use an application named Browsing.mxml.
00:13That's in the chapter04 Begin Project.
00:16If you are following along with the exercises open that application in Flex Builder from the project,
00:21then I'll expand the Code Editor to full screen, so we can see all of the code.
00:25This application has an empty function named browseForFile.
00:29The function is being called when user clicks the Browse button.
00:32There is also an HBox container that contains the label and the text control.
00:36I'll use the text control to display the path of the file selected by the user.
00:43In order to initiate a browsing operation create an instance of the File class.
00:48I'm going to declare the File object outside of any functions,
00:52so that I can address it from any function in the application.
00:57I'll declare a private variable named browseFile and I will data type it as a File.
01:03Then I'll initialize it using the File class' Constructor method and I'll pass in the location
01:09of the Application Directory as a string prefix and then point to the assets folder under that.
01:16Now, when I tell the File object to start a browse operation the browsing interface will start at that directory.
01:22Within the browseForFile function, I'm first going to add a couple of event listeners.
01:27The first one will be for an event called Select.
01:33The select event generate an event object typed simply as the event class.
01:37So I'll use the constant Event.SELECT and then I'll call a function
01:42that I'm going to have to create called selectHandler.
01:48I'll copy and paste that code and then I'll also listen for an event called CANCEL.
01:53If the users cancels the browser operation.
01:57The Cancel event will dispatched.
02:00Once again the event object will be data typed as a standard Event class and the name
02:05of the eventHandler function for this event will be cancelHandler.
02:08Next, I'll create those two functions.
02:15The first one will be named selectHandler, it will receive an event object as an argument,
02:21data typed as the Event class and return void and within this function,
02:28I'll output the path of the selected file using the text control that's already been declared
02:33with an id of selected text.
02:36So the code will look like this, selectedText.text=browseFile.nativePath
02:46and this will report the full path of the selected file.
02:49If the user cancels the operation, I will call this function cancelHandler.
02:56Once again the event argument will be typed as a standard Event class and I'll return void
03:02and this time I'll pop-up an Alert dialog and I'll report to the user Browsing operation was canceled.
03:14Finally, I'll go backup to the browseForFile method and now initiate the browsing operation like this.
03:21I'll call the File object browse method.
03:24Notice that there are a number of different methods here.
03:27I'm going to use the simplest version in this demonstration simply browse.
03:31The browse method allows you to pass in a typeFilter as an array.
03:35This is an array of valid file types, for instance you might limit the type
03:40of file the user can select to graphics JPGS or GIFS.
03:45I'm just going to make a very simple call.
03:47I call the browse method and now when the user selects a file.
03:51I'll get a select event and if they cancel the operation I'll get a cancel event.
03:56I'll test the application now.
03:59When I click the Browse button the Browsing dialog is popped up.
04:04If you are working on Windows, you will see a Windows Explorer dialog box
04:07and if you working on the Mac you will see a Finder dialog.
04:10I'll select the file from the assets folder of the application directory and click Open,
04:15and I see the result, the nativePath of the selected file.
04:19I'll start the browsing operation again and this time I'll cancel the operation by clicking the Cancel button
04:25and I get the cancel event resulting and showing the Alert pop-up.
04:29Now, I will go back to the code and I'll show you that in the selectHandler function, you can refer to the File object
04:35that initiated the browsing function either by its variable name, as I have done here or if you don't have direct access
04:42to that you can address the same object using the syntax event.target.
04:48event.target always points to the object that dispatched in the event originally.
04:53In this case it was the browse File object that dispatched the event resulting and calling this function.
04:59I'll save the changes and run the application again.
05:02I'll browse, once again I'll select the file.
05:06This time ATextFile.text and click Open and you will see
05:10that once again the nativepath of the file is correctly displayed.
05:15As I mentioned, there are also methods that allow you to select the multiple files and also to select a directory.
05:21They are all methods of the File Class and you call them by first instantiating the File Class,
05:27pointing to the folder where you want to start the browsing operation and then calling the appropriate method
05:33and adding the appropriate event listeners to handle whatever happens
05:37when the user either selects a file or cancels the operations.
Collapse this transcript
Working with Flex's file access visual controls
00:00In this video, I'm going to describe the use of visual controls provided in Flex that allow you to navigate
00:06and select files and directories from the local file system.
00:09These visual controls were described briefly in the first video in this chapter.
00:13They are based on the existing list based controls that are part of the Flex framework,
00:18the List, the ComboBox, the DataGrid and so on.
00:21To demonstrate these controls, I'm going
00:23to use an application named VisualControls.mxml, that's a part of the Chapter4 project.
00:29If you are following along in the exercises, open the application in Flex Builder now.
00:34I will expand the Source Code to full screen.
00:36You'll see that this is a very simple application that just has an HBox container, a label and a text control.
00:44To allow user to navigate and select files and directories, use one of these controls.
00:49I'll start with the simplest stuff then, the FileSystemList control.
00:52I'll declare the FileSystemList control using an MXML tag.
00:56I will give it an id of fsList and then I'll set its initial directory.
01:02The directory property points to a File object, that we first do in actual directory.
01:07In this example, I'll use a binding expression that points to the static property, Files.applicationDirectory.
01:17Then I'll create a Button control, I'll give it a label of Show selected and then a click event listener.
01:26Within the click event listener, I'll call a method called clickHandler.
01:30I'll close the Button tag.
01:34Then I'll create a Script section and create the function, clickHandler.
01:40The clickHandler function will receive an event object typed as a MouseEvent and return void.
01:48Within the function, I'll go and get the selected value from the FileSystemList control
01:54and I will display the selected files, nativePath in the text control with an id of selected text.
02:01I'll start with the code, selectedText.text equals (=)
02:06and then I'll get the selected File object, fsList.selectedItem.nativePath.
02:13In the clickHandler method call, I'll pass in the event object and then I'll test the application.
02:24Notice that as the application starts up, it points to the directory
02:27or folder that contains the application executable.
02:31The contents of the listcontrol will differ depending on whether you are running in Flex Builder or in Debug mode
02:36or you run the same application after packaging and installing it.
02:40In this case we're pointing to the bin-debug outlet folder, that's part of the Flex Builder Project.
02:46Notice, that I can click on any item and then click the Show selected button
02:51and I'll see the native path of the selected folder or file.
02:54I'll double-click into the assets folder and that will take me into its contents.
02:59I'll select one of the files, largecontacts.xml.
03:03Click the Show selected button and now I will see the full native path of that file.
03:08Let's try another one of the visual controls, this time I will replace the FileSystemList with the FileSystemDataGrid.
03:15I'm also going to expand the width of the application as follows,
03:20I'll set the width to 600 pixels and the height to 500.
03:26I'll save the changes and run the application and you'll see that the reason I set the windowed application
03:32to a little bit larger width is because the DataGrid control is going to take a quite a bit more horizontal space.
03:38Once again I can double-click down into the assets folder, I can press the Backspace key to return and I can pick an item
03:46out of the DataGrid and click the Show selected button and I'll see the items native path displayed.
03:52Notice that if I go into an area and I click to Show selected button,
03:55without first having selected something, I'll get a runtime error.
03:59Indicating that I'm trying to refer to an object that's null, that's because the current code assumes
04:05that I have selected something from the DataGrid.
04:07To prevent that behavior, I'll add an enabled property to the Button control,
04:12and I'll set the value of the property using a binding expression that looks like this,
04:16fsList.selectedIndex not equal to minus one (!= -1).
04:25As with the core corollary visual controls in the Flex framework, if the user has not selected an item
04:30from the DataGrid, the list or other visual control,
04:34the selected index property returns a value of negative one (-1).
04:38So this expression if the user hasn't selected something will return false
04:42and the button will not be enabled and the user won't be able to click it.
04:46I'll save and test the application again and you'll see that as the application opens up,
04:50once again it's showing the contents of the initial folder, the application folder,
04:55but because I haven't selected anything from the DataGrid, I can't click the button.
05:00When I click on an item, the button becomes enabled and I can click it.
05:04If I double-click into a folder, you'll see that nothing is selected and therefore once again the button is disabled.
05:11I will select an item and click the button and once again you can see the contents.
05:16There are two other visual controls worth looking at.
05:19The next one is the FileSystemComboBox, the FileSystemComboBox is a pull down list.
05:25As with the list control, it shows a list of all the items in the current directory.
05:30It shows the current directory name of bin-debug and then it shows the tree style control, that lets you drill upwards,
05:37but the ComboBox doesn't allow you automatically to move downward, through the tree.
05:42If you want that sort of functionality, instead use a FileSystemTree.
05:47I will replace the existing FileSystemComboBox with the FileSystemTree and once again run the application.
05:54This time you'll see that I can navigate upward and downward through the file tree.
05:59Once again I can select a file, click the Show selected button and see its native path, but because I'm starting off
06:06at a root folder, I have access if to everything from that root folder on down.
06:10Unlike the list control, pressing the Backspace button in this control doesn't take me upward.
06:16If I wanted to navigate upward from this root folder up to its parent directory, I'd have to do that programmatically.
06:22But because I'm in a tree control, once I started at one directory,
06:26I have access to everything under that directory automatically.
06:29There is one other visual control worth knowing about.
06:32It's called a FileSystemHistory button.
06:34The FileSystem history button works like this, I'm going to put a FileSystemListBack in this time and then right
06:41under that I'll add an HBox control and within the HBox control,
06:47I'm going to create two instances of the class, FileSystemHistory button.
06:52The first one is going to be used to navigate backward to the history of selections in the FileSystemList.
06:59I'll set its data provider as follows, I'll use a binding expression of fsList.backHistory.
07:07I'll add an item click event listener.
07:15When the user clicks on any item in the History button, I'll call this function,
07:20fsList.navigateBack and I'll pass in a value of event.index.
07:28This means, go back the number of times based on which item in the list I selected.
07:33Now, let's take a look at the result.
07:35I'll run the application, I'll double-click down into the assets folder and then pull down the list
07:42of available history and you'll see that bin-debug is in the History list.
07:47I'll click to select it and that moves me back to that step.
07:51Now, I will close the application and I'm going to copy and paste the FileSystemHistory button.
07:57So I have two of them within the HBox control.
08:00For the second one, I'll change the data provider from fsList.backhistory to fsList.forwardhistory
08:08and I'll change the item click EventListener, so that instead of calling
08:14to navigateBack function, it calls the navigateForward function.
08:19Once again I pass in event.index, I'll run the application, I'll double-click down into the assets folder,
08:28take a look at the back button and you'll see bin-debuggers listed there.
08:32I'll go back there, now look at the forward button and you'll see that the assets folder is listed there.
08:39So the FileSystemHistory button is most useful, with the FileSystemList and the FileSystemDataGrid.
08:45Neither of which controls have the ability to navigate forward and backward on their own.
08:50The History button is less useful with the tree control, because the tree control already offers you the ability
08:56to see all parts of the root folders, sub-folder structure.
09:00If you use the History button control, it typically uses two.
09:04One to go back in the history and one to go forward, so that's a look at all of the different visual controls
09:10in Flex and AIR that give you direct access to navigating and selecting files
09:15and directories from the local file system.
Collapse this transcript
Creating and deleting directories
00:00In this video, I'm going to describe how to use the ActionScript File Class
00:04to create new directories in the local file system.
00:07As I've described previously, the File Class can reference either a file or directory in the local file system
00:14and it's responsible for creating new directories.
00:17You all see as the File Class to move, copy and to lead directories, I'll show that in the later video.
00:22For this demonstration, I'll use an application named Directories.mxml, if you are following along
00:28with the exercises, you can open this application from the Chapter 04, begin project.
00:34I'll open the application in Flex Builder and then maximize the Code Editor.
00:39This application uses a FileSystemTree, with its directory bound to the applicationsStorageDirectory.
00:45Remember that this is the directory that's unique for each individual user and for each application.
00:51Its actual location differs depending on the operating system on which the application is running.
00:57Upon opening the application, the FileSystemTree will appear to be empty, it's actually pointing at the location
01:04of the applications towards directory on the user's local system.
01:08Our goal is to use the FileSystemTree component, to allow the user to select a parent directory.
01:15A place where they want to create a subdirectory.
01:17Then we will use the File Class to do the work of creating the new directory.
01:21Place the cursor inside the Create Dir Function and declare a new variable named parentDir, data typed as a File.
01:30The first step before you create an actual directory, is to determine what the parentDir will be.
01:36We'll examine the FileSystemTree component selectedIndex property.
01:40To find out whether the user has selected anything.
01:43Put in a conditional block, that uses this Boolean expression.
01:48If fsTree.selectedIndex is not equal to minus one (!= -1) and this would be the condition
01:56where the user has not selected anything from the tree.
01:59We'll set the parentDir file objects reference to the selected item from the tree.
02:07We use the selectedItem property and explicitly cast it as a File object.
02:13In the else clause, set the location of the parentDir to the application directory itself.
02:20The syntax for that is the static property, file.applicationStorageDirectory.
02:26So now the logic is that if the user has selected something, we'll use that as the parent directory,
02:31otherwise we will use the applicationsStorageDirectory.
02:35The next step before creating a subdirectory is to determine whether the user has chosen a directory or a file.
02:41If the user chose a file, we can't create a subdirectory under it.
02:45For this purpose, user property of the File Class named isDirectory,
02:50this is a Boolean property that returns true or false.
02:53If the File object points to a directory that returns true, otherwise it returns false.
03:00Also put in else clause, and we'll come back to the else clause in a moment.
03:04I'll scroll down a bit so we can see this part of the code.
03:07Then place the cursor back in the if clause that only will be activated
03:11if the user has chosen a directory as the parent.
03:15Now, the next step in creating a new directory is to create a new File object that points to the location
03:20where you want to create the subdirectory.
03:23I'll create a new variable and I'll name it newDir and I'll data type it once again as a File object.
03:29To set the physical location of this File object, I'll use a method of the File Class named resolvePath.
03:36The resolvePath method works like this, I'll put in the name of the parentDir object.
03:42Then call the resolvePath method and I'll pass in the name
03:45of the subdirectory I want to create, which I'll name newDir.
03:50Whatever value you pass into the resolvePath method, is appended to the nativePath of the parent object
03:57and it becomes a new nativePath the you can refer to.
04:00To see the result of that action, I'll trace the newDir objects, nativePath and I'll run the application
04:09in debug mode and we will see what the trace statement says.
04:13I'll run the application in the debug mode.
04:16As the application starts up once again, it's showing the FileSystemTree component and it's pointing
04:21to the applicationStorageDirectory, I'll click the Create Directory button
04:26and then close the application and maximize the Console view.
04:31The Console view shows the result to the trace statement,
04:34displaying the location of the directory I'm about to create.
04:38Notice that it's underneath my applicationsStorageDirectory.
04:41Once again the actual location of the directory will differ depending
04:45on whether you are running on Windows XP, Windows Vista or Mac.
04:49Notice that the end of the expression is Local store/newDir, a backslash () if you are on Windows and a forward slash (/)
04:57if you are on Mac and that's the directory I would like to create.
05:01So I will restore the size of the Console.
05:03If you are still in debug mode, you can click the little button that will show red right here
05:08and then that will terminate the debugging session and you are ready to start coding again.
05:13Go back to the MXML Editor, place the cursor after the call to the trace method.
05:19Now it's time to actually create the directory, I'll do this by calling the NewDir objects, createDirectory method
05:27and that actually creates the directory on disc.
05:30Next, I'll refresh the FileSystemTree, I'll use this in text fsTree.refresh, ending with the semicolon.
05:38Finally I'll use the Alert class to tell the user, that the operation was successful.
05:47I'll call the Alert class a show method and pass in a literal string as a message Directory created.
05:54I also need to handle the condition that can happen, if the user chooses a file from the FileSystemTree.
05:59If they choose a file, we can't create a directory underneath it.
06:03So all I'll do in the else clause of the conditional block is use the Alert class to show a pop-up message
06:09that tells the user, Please select a directory.
06:12Now, the application should be complete.
06:17Going back up to the top of the code, in the first conditional clause I check
06:21to see whether the user has selected an item from the tree control, if they have selected an item,
06:27I use the selectedItem property cast as a File and set the parentDir from that,
06:33otherwise I set the parentDir to the applicationStorageDirectory.
06:37Then, assuming that they've chosen a directory which is enforced
06:41by this conditional block, then I create a new file object.
06:45I set it's location with the resolvePath method in the name of the directory I want to create
06:50and then I create the directory, refresh the tree to show the result
06:54and also pop-up a window telling them that the action was successful.
06:58I'll run the application, I'll click the Create Directory button.
07:03I see the alert message saying that the directory was created
07:06and the FileSystemTree shows me that I did successfully create it.
07:10I'll click into the FileSystemTree and select that now as the new parentDir, click the button again, click OK.
07:19Open the NewDir as the parent and I'll see another NewDir under that and I can keep
07:24on doing this operation as long as I want to.
07:27It's also worth noting, that if you go over to the FileSystem now,
07:31you'll find that you have this whole hierarchical set of directories.
07:34A NewDir inside a NewDir, inside a NewDir.
07:38Now if you were to call the Create Directory function again,
07:41on a directory that was already created, nothing would happen.
07:45You won't get back any bad response, you won't see a runtime error, the command is simply ignored.
07:51So that's how we create directories using the File Class, using the Create Directory Method,
07:56but first ensuring that the parent directory that we're using is a directory and not a file.
Collapse this transcript
Creating and manipulating files
00:00In this video, I'm going to describe how to use the ActionScript File class
00:04to manipulate files in the local file system.
00:07How to copy, move, delete and move files to the trash or the recycle bin.
00:12For these demonstrations, I'll use an application in the Chapter04, Begin Project named filemanipulation.mxml.
00:20If you are following along with the exercises, open this application file
00:24in Flex Builder and then run the application.
00:27The application presents a file system list control, before the user can use any of the features of the application,
00:33they have to indicate where the exercises directory is.
00:37Click the Select Exercises Directory button and then browse to and select the Exercises folder,
00:43which I've installed in my desktop directory.
00:46I will then click OK and then the file system list control displays the contents of a subdirectory
00:53of the exercises folder named Assetsfiles.
00:56The status area of the application indicates the physical location of this directory
01:01and it should contain a single initial file, a text file .txt.
01:06I'll close the application and take a look at the code, there is bit of code in here that's controlling
01:11that initial selection process, including checking to see whether the directory exists
01:16and whether the exercises directory is selected by the user has the correct structure.
01:21In the bottom section of the script area, there are four functions named copyFile, moveFile,
01:26deleteFile and trashFile, which in turn are being called by four buttons in the panel's control bar.
01:33In this first demonstration, I'll show you how to copy a file, from one file name to another.
01:38Place the cursor inside the copyFile method, the first step in copying a file is to create two file objects,
01:45one pointing to the source file and one pointing to the destination where you want to copy the file to.
01:52Declare variable named SRC, data typed as a File and get its reference from FS list,
01:59that's the id of the file system list control dot selectedItem as File.
02:07Next create another variable named dest, also data typed as a file and point to a location within the files directory,
02:15which was represent by a File object named, filesDir.
02:19Call it resolvePath method and pass in the name of the new file you want to create.
02:25ANewFile.txt.
02:28Now, whenever you execute any of the file manipulation functions,
02:32you can use either a synchronous or an asynchronous version.
02:35If you use the asynchronous version, you need to listen for the complete event and react whenever the operation is done.
02:42To do that, call the source object addEventListener method and dedicate
02:47which event you are listening for Event.COMPLETE.
02:50When that event is dispatched, you call a method called completeHandler,
02:55which is already declared in this application.
02:57Then after the event listener has been created, copy the file like this, src.copyTo --
03:05notice that there are two versions of this method, copyTo which is synchronous and copyToAsync which is Asynchronous.
03:13Use the Asynchronous version, copyToAsync, pas in the destination file object dest and then a bullian value,
03:22indicating whether you want to overwrite the destination file if it already exists.
03:27I'll put in a value of true.
03:29Now go down to the completeHandler method, in the completeHandler, refresh the file system list control
03:35like this, fsList.refresh() and that will cause the list control to reread the contents
03:41of the directory and display it to the user.
03:44Save your changes and run the application.
03:47When the application starts up, once again you'll need to indicate where the exercises directory is,
03:53click the button and select the directory and click OK.
03:56Then select the file you want to copy and click the Copy button,
04:01you should see that the new file is created immediately.
04:04Next, you will learn how to move a file from one directory to another.
04:08Close the application and place the cursor in the code inside the moveFile function.
04:13In order to move a file, you first need a destination directory, to make sure you have a place
04:19to move the file too, create a new variable named destDir, data typed as a File and get the reference
04:26to the new directory, using the syntax filesDir.resolvePath and pass in the name of the destination directory DestDir.
04:35Now this directory doesn't exist yet, so we need to create it using the syntax destDir.createDirectory().
04:44You could also wrap this line of code inside a conditional clause.
04:47Checking first to see whether the directory already exists, it's really not necessary though
04:52because the createDirectory function, if it tries to create a directory that already exists does nothing,
04:57it doesn't throw a runtime error or cause any other problems.
05:01Now, we'll get a reference to the file we want to move.
05:04I have code to do that already in the copyFile function.
05:08So I will go up to that function and copy the line of code that creates the source variable
05:13and I'll paste it into the moveFile function.
05:16I'll also copy and paste the addEventListener call right after the creation of the variable.
05:23Now, I'll also create a destination file object that indicates where I want to move the file too.
05:29You can't just pass in a directory here, you have to pass in an actual file name that indicates where you want
05:35to move it to and what the new file will be.
05:37I'll use the syntax, I'll create a new variable named destFile data typed as a File and I'll get its location
05:45and file name from this syntax, destDir.resolvePath and then I'll pass
05:51in the existing name of the file like this, src.name.
05:55The name property returns just the filename without its location information.
06:00Finally, I will move the file by calling the syntax src.moveToAsync.
06:07I will pass in the location I'm moving it to destFile and a value of true indicating
06:12that if the file already exists, I'll overwrite it.
06:16The code for the completeHandler is already filled in, because we did that in the previous demonstration.
06:22So I'll save and run the application, once again select the exercises directory,
06:29select the file that I want to move and click the Move button.
06:33You'll see that the file no longer exists in this directory, instead there is a new directory named destDir.
06:39I'll double-click on that directory and you'll see that the file has been moved correctly.
06:44Next, I'll show you how to delete a file.
06:46Go back to the code and place the cursor in the deleteFile function.
06:50The first step as before is to get a reference to the file that's currently selected.
06:56I'll go back to the moveFile function and I'll copy and paste these two lines of code.
07:01The line of code that creates the SRC variable and the one that adds the event listener
07:06and I'll paste those lines of code into the deleteFile function.
07:09Before you can delete, you have to determine whether the user has selected a file or a directory.
07:15Put in a conditional clause and this Boolean expression, src.isDirectory.
07:21If the user selected a directory, I'll use a function called deleteDirectoryAsync.
07:28If they selected a file, I'll choose src.deleteFileAsync like this.
07:34In the if clause, I'll call the syntax src.deleteDirectoryAsync and I'll pass
07:42in a Boolean expression indicating whether I want to delete all of the contents of the directory
07:46if it contains anything and I'll pass in a value of truth.
07:50In the else clause, I'll call a function called deleteFileAsync.
07:54This function doesn't receive any arguments and it simply deletes a single file and in either case
08:00when the completeEvent is dispatched, the completeHandler method will refresh the list control.
08:05I'll save and run the application, once again when the application starts up, I'll select my exercises directory,
08:12I drill down into the destination directory, select the file and click the Delete button
08:19and you'll see that the directory is emptied out.
08:22Now, with the list still having focus, press the Backspace key and that will take you up one directory.
08:28Now select the destDir directory and click Delete and once again the directory is deleted.
08:35Now let's do all the functions, click ATextFile.text click Copy, click the File, delete it.
08:45Select a ATextFile.txt again, copy it, select the NewFile and Move it and this time remove the destination directory
08:56by clicking Delete and you'll see that you are deleting not just the directory but all of its contents.
09:03Finally, there is one more feature to talk about, moving a file to the Trash or on Windows into the Recycle Bin.
09:10For this purpose, you can once again select from synchronous or asynchronous versions.
09:15This time of a function named Move to Trash.
09:18In the trashFile function, I'll once again copy and paste the code
09:22that gets the source file reference and sets up the event listener.
09:31Now, instead of deleting, I'm moving to the Trash and whereas with the Delete functionality,
09:37there are two different versions of functions.
09:39One for directories and one for files.
09:41When you move to the Trash, it's all the same thing.
09:44So I will call src.moveToTrashAsync () and once again when the complete event is dispatched,
09:51the completeHandler, method will refresh the list control.
09:54I'll run the application, select the exercises directory when the application opens up, select the file
10:02and this time click the Trash button, you'll see that the file is no longer displayed in the list control.
10:07Now, I'm going to minimize everything and go back to my desktop and take a look at my Recycle Bin and you'll see
10:14that the text file has been moved to the Trash.
10:17I'll reopen the application, move it over to the side, go back to the Recycle Bin and I'm now going
10:24to restore the file to its original location.
10:27On windows you can do this by right-clicking and selecting Restore.
10:31On Mac, you'll need to actually drag the file to the appropriate location.
10:35Then I'll go back to the application still running and click the Refresh button and you see
10:40that the file has been moved back to its original location.
10:43So these are the four major features of file manipulation in AIR.
10:47You can do all four features on either directories or files, copying, moving, deleting and moving to the trash
10:54and for each operation there are two versions for synchronous and asynchronous operations.
Collapse this transcript
Reading data from a text file
00:00In this video, I'm going to describe how to read text contents from a file on the local disk.
00:06For this demonstration, I will use an application named ReadingText.mxml from the Chapter04BeginProject.
00:13If you are following along with the exercises, open the file in Flex Builder now.
00:17This is a very simple beginning application.
00:20It has an empty function named readText and a button control whose click event results in calling the function.
00:26I will expand my Editor to full screen so we can see as much code as possible.
00:30To read text from a file on disk, you need two objects.
00:35A File object that points to the file and a FileStream object that opens and reads its contents.
00:41Start by the declaring a variable named F data typed as a File.
00:45Get its location, using this syntax File.applicationDirectory.resolvePath,
00:53and then pass in this location Assets/ATextFile.txt.
00:59Next, create a FileStream object.
01:05Declare another variable named FS, set its data type as FileStream,
01:11and instantiate it using the FileStream classes no arguments constructor.
01:15The file classes constructor method just not receive any arguments.
01:20You simply instantiate it and then you connect it up to the file object,
01:24using one of two methods, either Open or open Async.
01:28As with all file manipulation functions, you can read the contents from a file either synchronously or asynchronously.
01:35I will be working synchronously in this exercise.
01:38But if you are working with a very large file, you may need to use the asynchronous version to make sure
01:43that you don't suspend the main application thread, while the file reading process is happening.
01:47To open the file synchronously, call it the FileStream objects open method and pass in two arguments.
01:53A reference to the file you want to open, and then a mode value.
01:57The file mode argument is a string value.
02:00There are four constants you can use, that are members of the class FileMode.
02:05Their values are APPEND, READ, UPDATE and WRITE.
02:09If you are just getting a value out of the file, use the Read mode.
02:14Now the file is open for reading.
02:17Now, declare a variable typed as String that will receive the value from the file.
02:21I will name this variable simply TXT, data type it as a String, and then you call it a method
02:28of the FileStream object named readUTFBytes.
02:32There are actually two methods that are available named readUTF and readUTFBytes.
02:37The readUTF method requires a particular end of file marker at the end of a file which isn't always present.
02:42The readUTFBytes method is a bit more reliable and it works like this.
02:47You call it the FileStreams readUTFBytes method, and you pass in a length value which you read dynamically,
02:56using the FileStream object's bytesAvailable property.
02:59This is an unsigned integer value that tells you how many bytes or characters there are in the file.
03:05Close the method call and now the data has been returned to the text variable.
03:10Finally, and very important, you should always explicitly close the FileStream when you are done with it.
03:16This ensures that any of the application's file locks have been removed.
03:20Now, we have the value from the text file in the TXT variable.
03:24I will use the alert class and display the results by calling Alert.show.
03:29I will pass in value of the text property, and then in the second argument,
03:34the title of the pop up window, a value of Read from file.
03:40That's all the code.
03:42Let's review the steps.
03:43First you create a file object pointing to the file you want to read, then you create a FileStream object.
03:48You use the FileStream object to open the file working either synchronously or asynchronously.
03:54I'm using synchronous operations here, and indicate what mode you want to open the file in.
03:59I have indicated here that I'm opening it in Read mode.
04:02Next, you call the readUTFBytes method and pass in the FileStream object's bytesAvailable property.
04:09That returns the value from the text file into the String variable.
04:13Then you explicitly close the FileStream and then you have a value that you can work with.
04:19I'll run the application to test this.
04:22I will Click the button, and you will see the contents of the text file are read and displayed.
04:28If you are working with an XML file, the steps are very similar, but you also then take the String value
04:35that retrieved from the XML contents and you pass it into an XML object.
04:40I have another couple of files in the source area that I can work with.
04:44Here's a file named contacts.xml which contains a thousand rows of XML formatted data.
04:51I'm going to change the contents of this file like this.
04:55First of all I will change the name of the file I'm reading from ATextFile.txt to simply contacts.xml.
05:02The next set of steps are exactly the same.
05:05I create the FileStream, open the file, read its contents and save it all as a String.
05:10Then, once I have the XML formatted text as a String, I can parse it by passing it
05:15into the constructor method of a new XML object.
05:18I will create a variable named contacts.XML data typed as an XML object,
05:25and I will construct it using new XML, and I will pass in the text value.
05:31This time l don't want to use the Alert class to display the contents of the file.
05:35So I'm going to comment that out, and then put a break point on the last line of the function.
05:40When I reach the break point, that will suspend the application, and I will be able to inspect this XML object.
05:46I will save the changes, and this time I will run the application in debug mode.
05:51When the application opens, I will Click the Read File button.
05:56In the background, Flex Builder presents a message, asking me to switch to the debugging perspective.
06:01I will accept the prompt.
06:03I will double-click the Variables Tab to inspect my data, and then take a look at contacts.XML.
06:10It may take a few seconds for this to open on your system depending on how fast your system is,
06:14how much memory, how much resources you have.
06:17But after the data has been parsed, you should see that you can inspect the data
06:21and drill down through its contents in the Variables view.
06:26Now, I'll restore the Variables view and terminate the debugging session.
06:31So that's a look at how to read text files into memory.
06:34You use a file object and a FileStream object,
06:38and read the value into a String based variable making sure you have closed the FileStream when you are done.
06:43And then if you have simple text, you can simply display it to the user or do anything else you want with it
06:48or if you have XML formatted text, you can use the XML object to parse the data,
06:53and make it available to E4X expressions.
06:56Now, if you are not familiar with E4X, which is known as ECMAScript for XML, it's a great technology to get to know
07:03and you can check out the demonstrations of using E4X in the other videos about Flex 3.
07:08Flex 3 Beyond the Basics and Flex 3 Essential Training.
Collapse this transcript
Writing data to a text file
00:00In this video, I'm going to describe how to write text to a file in the local file system.
00:05For this demonstration I'll use an application in the Chapter04BeginProject named WritingText.mxml.
00:13If you're following along with the exercises open the application in Flex Builder.
00:18The beginning application has an empty function named writeText, a button whose click event calls the function
00:24and the TextArea control with an ID of taSource that will provide text to be written to the file.
00:30Just as when reading a file you need two objects, a file object that will reference the file you want to write to and
00:37the FileStream that will actually open and write the text.
00:41To get started place the cursor inside the writeText function.
00:46I'll expand the editor to full screen to see all of the code.
00:49Declare a variable named f data typed as a file
00:53and indicate its target location.
00:55You can't write a file to the application directory; the application doesn't have permissions to write content to that area.
01:02You aren't allowed to directly modify the contents or files that are in the application directory,
01:07that is, the directory for the actual application is stored or its subdirectories.
01:12So instead I'll create a file reference that points to a location in my desktop directory.
01:17I'll set its location and file name with this syntax,
01:20File.desktopDirectory.resolvePath and then I'll pass in the name of the file that I want to create, DestFile.txt.
01:31Now I'll create a FileStream object. As when reading the file, as I demonstrated in the previous video,
01:37you declare the variable typed as a FileStream and then construct the object
01:42using the FileStream class's no arguments constructor method. Next open the file.
01:47As when reading the file you can select from synchronous or asynchronous operations.
01:52Because I'm working in a very small text file and it will take very little time to do,
01:57I'll work synchronously this time. I'll open the file
02:01I'll call the open method of the FileStream object and pass in the target file reference
02:06and then pass in a FileMode of FileMode.WRITE.
02:11You can also select APPEND or UPDATE. You use UPDATE if you're overwriting the contents of an existing file and APPEND if you're
02:19adding text to the end of a file.
02:21Because I'm creating a new file from scratch, I'll choose FileMode.WRITE.
02:24Next I'll write the contents of the TextArea control to the file.
02:29I'll use a method called writeUTFBytes.
02:35And I'll pass in the value as a string that I want to write to the file
02:39and I'll get the value from taSource.text.
02:43Then I as indicated in the previous video you always close the FileStream when you are done.
02:48Then I'll use the Alert class to display a pop up window and tell the user that the operation is complete. I'll pass in
02:55strings of File writing complete and then for the title of the pop up window, Write to File.
03:03I'll save the changes and run the application.
03:08I'll click the button.
03:10I should see an immediate message indicating that the operation is complete.
03:14I'll minimize the application and Flex Builder, so I can see my desktop.
03:19I'll see that the new file now exists
03:21and I'll open the file in TextEdit, which is my favorite text editor. You can use any text editor you like for this operation,
03:29and you'll see the text that was written to the file is displayed.
03:32Now to show that we're actually overwriting and creating a new file from scratch each time, I'll close the text editor and
03:39move the file to the Recycle Bin
03:41or if you are on the Mac, to the Trash Can.
03:43I'll go back to the application that's still running,
03:46this time showing the desktop in the background
03:49and I'll type in some additional text.
03:59I'll click the Write to File button.
04:01I'll get the message that the file writing is complete and I'll see the file appears on the desktop immediately.
04:08I'll once again open the file in my favorite text editor and you will see all of the contents displayed.
04:14So this is once again how you write text to a file.
04:17You call the writeUTFBytes method. You pass in the string value that you want to place into the file and then you make
04:23sure that you close the FileStream when you're done.
04:25When you use the writeUTF method, the string that you write to the file is prefixed with the numeric value that indicates the
04:32number of bytes in the file and then when you read the file instead of using readUTFBytes you can instead use the simpler
04:39method readUTF. But both approaches work
04:42and in either case you can select from either synchronous or asynchronous file operations.
04:48If you're working with larger amount of text that might take more than an instant to write to disk, you should always use
04:54asynchronous operations, so that the file operation doesn't result in suspending the main application thread.
Collapse this transcript
Using temporary directories
00:00In this video, I'm going to describe how to create and use temporary files and directories on the local file system.
00:07The location of temporary files and directories is different depending whether you are working on Windows XP,
00:12Windows Vista or the Mac, but the API in AIR allows you to use exactly the same code to work with these files
00:19and directories, no matter which operating system the application is deployed on.
00:23For this demonstration I will use an application file in the Chapter04BeginProject named TempDirsAndFile.mxml,
00:31if you are following along with the exercises open the file and the Flex folder.
00:36The existing application has three methods called closingHandler, createTempDir and createTempFile.
00:42The createTempDir and createTempFile functions are being called upon the click event
00:47of two buttons at the bottom of the application.
00:50Applications can create temporary directories the whole content that is unique to the individual user
00:55and also unique to the current application session.
00:58If you are planning on creating more than one temporary file,
01:02it's a good idea to put them all in the same directory.
01:05Use this code to create a temporary directory as a file object.
01:08First of all, place the cursor above the functions
01:12and declare a private variable named TempDir datatyped as a file.
01:18Don't initialize the object yet, just declared at the top of the functions.
01:22Then go to the createTempDir function and add this code TempDir equals File.CreateTempDirectory.
01:31Now as I mentioned the actual physical location of this directory is determined partially by the operating system
01:37and partially by the Adobe Integrated Runtime.
01:41Now trace the location of the file that was created.
01:44Add a trace statement and pass in the value TempDir.nativePath.
01:50Remembering that the nativePath property always tells you the actual location and name of a directory or file.
01:56Now save and run the application in debug mode.
02:00Click the createTemDirectory button and you should see in the console
02:06in Flex Builder a listing showing you where the file was created and its name.
02:12I'm working on Windows Vista and on vista temporary files are created
02:16in an AppDataLocaltemp folder underneath my home directory.
02:21The name of the file starts with fla and ends with .tmp.
02:24If you are working on Windows XP the location will be similar, but the actual physical location will start
02:30with documents and settings instead of users and if you are working on Mac it will look very different.
02:37The path of the file starts in a directory named private which is under the volume route and then continues
02:42on with the completely randomized file and directory name.
02:46Now I'm going to be creating some spare files along the way, so you might want to make a note of these files
02:52and then go back later and clean them up manually because temporary directories
02:56and files are not cleaned up automatically by the runtime.
02:58It's up to you as the developer to take care of removing them when you are done
03:02and I will show you how to do that at the end of the exercise.
03:06Close the application and return to the source code.
03:09The code to create a temporary file is very similar.
03:12Place your cursor at the top of the functions
03:15and declare a private variable named Temp File once again datatyped as a file.
03:21Then go to the createTempFile method use this syntax to create a new file, tempFile = File.createTempFile,
03:32this not only creates a reference to the location of the file,
03:35but actually creates the file on disc at the same time.
03:38Then once again call the trace method and output to the console,
03:41the location of the new temporary file, using the syntax tempFile.nativePath.
03:47Run the application in debug mode, click the createTempFile button and you will see once again
03:56in the console the location and name of the newly created file, close the application.
04:02Now I'm going to go to my temporary directory and show you that the files have been created.
04:06I'm going to select just the directory location under which the file and the directory were created.
04:12Copy that to the clip board and then in windows I can find that file location easily by going to the start menu.
04:19If you are working on Windows XP choose the run option, if you are working on Windows Vista you can simply paste
04:25in the location and press enter and that will open the location of that directory in windows explorer.
04:32Here's the temporary directory that I created and here's the temporary file.
04:37If you are working on Mac OS X, you can follow the same steps.
04:42Run the application in the debug mode, then click the buttons to create a tempDirectory and a tempFile.
04:49Leaving the application open, go to the console and you will see the listing
04:53of the location of the Temporary Directory in file.
04:56Select the path that prefixes both of those file and directory names ending with the string temporary items
05:03and then copy that string to the clip board.
05:07Next switch to Finder, in Finder go to the menu and select to Go, go to folder.
05:15You can also press the associated keyboard shortcut.
05:18Paste that value into the dialogue box that appears by pressing Command V and then click Go.
05:24That should result in displaying the temporary items folder for the current user,
05:28you will see the name of the folder and the name of the file.
05:32Now as I mentioned, when you close down the application these temporary files and directories are not cleaned
05:37up for you, you are responsible for taking care of that.
05:40I'm going to manually remove these files from the tempDirectory
05:44and then close Windows Explorer and come back to Flex Builder.
05:51In order to clean up the temporary files and directories as you close the application you have
05:56to detect that the application is closing.
05:58You can do this through an event dispatched by the windowed application component named closing.
06:04I will be talking about this and other window based events a lot more in the later chapter all about native windows.
06:10For now just go to the code, place the cursor right at the end of the windowed application tag
06:16and add an event listener for the closing event.
06:19Make sure you have selected the closing event and not the close event.
06:23Call the method that's already been created closingHandler and pass the event object.
06:31Now go to the closingHandler method and add code
06:34to detect whether the temporary directory and temporary file still exist.
06:38For the directory use this syntax if tempDir.exists and then within the condition clause called tempDir.deleteDirectory
06:51and pass in a value of true meaning that you want to remove all of its contents if there are any.
06:58Do the same thing for the file, if tempFile.exists; and then within that conditional block call the delete file method.
07:09Finally at the end of both conditional blocks add a trace command and indicate
07:20when you are debugging temp file and dir delete.
07:27Save your changes and once again run the application in debug mode.
07:32Now to demonstrate this once I have created the Temporary Directory and Temporary File,
07:36I will open up windows explorer side by side with the application, so we can see the temporary directory and file
07:42and see what happens as the application closes.
07:45I will create the temporary directory and the temporary file.
07:50Next I will go copy the locations of the clipboard, navigate to that location, again I'm using Windows Vista,
07:58so I can simply paste the location into the start menu and I will sort so I can see the files listed.
08:05There is the temporary file on my system it was name flaBEC.temp and the directory was named fla38C.temp.
08:14Now I'm going to move my windows around so we can see both these Temp Directory and the application at the same time.
08:30Now I will close application so notice that the application closes and the file
08:35and directory created by the application are gone.
08:38So that's how you manage temporary files and directories.
08:41Now notice, in this particular temporary directory that there are bunch of files there that start with Flex2_,
08:47now those are temporary files that are actually created by Flex Builder and to show you to the behavior
08:53of an application that does a good job of cleaning up after itself I will now close Flex Builder,
08:59watching the temporary directory contents and you will see that as Flex Builder closes everything is deleted from disc.
Collapse this transcript
5. Working with HTML Content
Using the Flex HTML component to create a browser
00:00In this chapter I'm going to describe use of the built-in HTML web browser component,
00:05that's a part of the Adobe Integrated Runtime.
00:07I described this component briefly in the AIR 1.0 Essential Training title,
00:12the Adobe Integrated Runtime includes a built-in web browser kernel based on WebKit, the same kernel that's used
00:18in the Safari web browser built by Apple.
00:21This browser component is capable of rendering and displaying complex HTML
00:26that incorporates cascading style sheets and complex JavaScript code;
00:30in fact one of the most popular demonstrations you will see of AIR applications is the use of Google Maps one
00:36of the more complex and powerful Ajax based applications on the market rendered in the context of a desktop application.
00:42In this video, I will show you how to use the basics of that HTML component and then later
00:47in this chapter I will show you how to use the more advanced techniques.
00:51If you are following along with the exercises, to get started you will need
00:55to import a Flex Project archive from the Exercises folder area.
00:59From the Menu select File, Import, Flex Project, click the Browse button next to Archive file,
01:09go to your Exercises area which is on my Desktop and navigate to the Chapter05 folder; you will find two files
01:18with the .zip extension there Chapter05BeginProject.zip and Chapter05EndProject.zip.
01:25Select the BeginProject file and then when you come back
01:28to the Import Flex Project dialog box click Finish to import the project.
01:34Then go the Flex Navigator view and open the project, go to the source folder and open the file UsingHTML.mxml
01:43which you will see as an empty Flex application.
01:46Notice that the WindowedApplication tag in this application doesn't have a layout property;
01:51in AIR applications as with all Flex applications the layout property defaults to a value of vertical meaning
01:58that objects will stack vertically as we place them in the application.
02:02To get started in the application,
02:04add an ApplicationControlBar container and sets it dock property to true.
02:10The ApplicationControlBar is a special container that glues controls to the top of the application
02:16and it's a great place to put controls with which the user will interact.
02:19Now below the ApplicationControlBar add an HTML component, give it an id of web,
02:27sets it height to 100% and its width also to 100%.
02:34The result will be that the HTML component that is the web browser component takes
02:39up all available space in the application.
02:42Now go the ApplicationControlBar and add three components first Label, set the text property of the label
02:50to Enter URL then add a TextInput control, sets its id property to urlInput and finally a Button,
03:04give the Button a label of GO and a click event handler that executes a bit of ActionScript code that sets the location
03:13of the HTML component that is the web browser to the URL that's entered by the user.
03:18This can be done with a single line of ActionScript code,
03:21so I will do it with inline code rather than creating a separate function.
03:25The code looks like this, web.location = urlInput.text, that's it.
03:36You have just built a complete working web browser application, save and run the application.
03:41You will see that the three controls the Label, the TextInput
03:45and the Button appear in the top application control bar.
03:48The central flight area of the application is the web browser component
03:52which defaults to a background color of white.
03:55Click into the text input control and expand the size of the window so that you can see as much of the resulting web page
04:02as possible, then type in a complete URL starting with http:// and then type in any web address.
04:11I will type in www.adobe.com, then click the GO button and you should see if you have Internet access
04:20that the web page you requested is loaded in to the browser component.
04:25You should see that the browser is able to handle very complex presentations including cascading style sheets,
04:31any JavaScript code and of course Flash based presentations
04:35such as the Flash video that's currently playing on my screen.
04:39To see a more complex example switch to maps.google.com.
04:45One important note about entering the URL, you must enter the entire URL including the http:// prefix.
04:53This browser component unlike Internet Explorer or Firefox does not know how to notice
04:59that there is a missing prefix and add it for you.
05:02Once again click the GO button and you should see a fairly complex application, Google Maps up here.
05:08Type in any address, for instance I will type in the old headquarters of Macromedia, 601 Townsend St,
05:15San Francisco then I will click Search Maps and you should see that the map is loaded correctly.
05:23Close the application and now we will add a couple more tools.
05:28Place your cursor after the Button still
05:30within the ApplicationControlBar container, add a Spacer and set its width to 100%.
05:39A Spacer control is an invisible control that pushes other objects around the screen;
05:44by setting its width to a 100% it will take up all available space within the ApplicationControlBar
05:50and any controls we declare after the Spacer will be pushed all the way to the right.
05:56Now we are going to add back and forward buttons just like a real browser.
06:00Add another Button component, set its label to Back and add a click event listener
06:07and in the click event listener call web.historyBack(), the historyBack() function is very similar
06:14to a JavaScript command called history.back(); it moves the browser back one step in its history.
06:23Right after the back button, add another Button with the label of Forward, add a click event listener
06:30and when the click event for this button occurs call the web components historyForward() method;
06:36save your changes and once again run the application.
06:40You should now see that the controls in the application control bar at the top of the application include the label,
06:48the text input and the GO button and over there on the right the Back and Forward buttons.
06:53Click into the text input control and type in a complete URL to some web site; once again I will start at www.adobe.com,
07:02click GO and you should see the first site up here.
07:07Next type in another site, I will change www.adobe.com to www.lynda.com;
07:15once again click GO and you should see that site up here.
07:20Now try clicking the Back button and you should go back to the first site and click the Forward button
07:26and you should go forward to the second site.
07:29So that's the look at the basic features of the HTML component, there's a lot more you can do
07:33with this component including calling JavaScript code from your ActionScript code
07:39and that's what I'm going to show you in the next video.
Collapse this transcript
Using script bridging with ActionScript and JavaScript
00:00In this video I'm going to describe how to use the HTML component in the Flex application
00:06and call JavaScript based functionality that's hosted in the web page inside the HTML browser;
00:11you will be calling this functionality from your Flex ActionScript code emulating the JavaScript language.
00:17For this demonstration I will use two files an MXML application file named ScriptBridging.mxml.
00:25If you are following along in the exercises open that file now in Flex Builder
00:29and then a web page file named WebPageWithJS.html, right-click or Control click on the Mac on this file
00:37in the Flex Navigator view and select Open With, Text Editor.
00:42If you double click on the file you will probably end up opening it into Web Browser editor or instead
00:46in seeing the page rendered instead of seeing its source code.
00:50The web page with JS file contains a couple of simple functions,
00:54a sayHello function that contains the window.alert method to pop up a message from the JavaScript environment
01:00and a setNameValue function that receives a value argument,
01:04gets a reference to an input control and sets that controls value.
01:09Down below there is a heading one tag set with a simple string, a very simple web page,
01:14an input control who's click event calls the sayHello function, a small data entry form,
01:20another input control and another button.
01:23Go back to the ScriptBridging application and run it, then click into the URL text input control and type in the name
01:31of the HTML page WebPageWithJS.html, because you are loading this file
01:38from the local hard disk you do not need an http prefix or any other directory information.
01:44The HTML file is in the same output folder as your compiled application, click the GO button
01:51and you should see your local web page loaded right away.
01:56Now click the Say Hello button and you should see this JavaScript pop up window displaying the string Hello
02:02from JavaScript, click Okay then click the Fill Value button and you should see a string
02:09of My Name entered into the text input control.
02:12Both of these functions are being executed through JavaScript calls.
02:15Now I'm going to show you how to make the same calls from your ActionScript environment,
02:21close the application and return to Flex Builder.
02:24In order to make JavaScript calls to the web browser environment you reference a property
02:29of the HTML component named domWindow.
02:33This property references the document object that's at the root of your entire HTML environment in the web browser;
02:40so for example if you wanted to call the standard window.alert function that's a part of JavaScript
02:46but you want it to execute it from within your ActionScript environment, the syntax would look like this,
02:52you would start off with the id of your web browser object which I have called web
02:57and then reference its domWindow property.
03:00Notice it's spelled with an upper case W in the middle.
03:03Then call it whatever methods you want to, so for instance if I wanted to pop up a window directly
03:08and pass in a simple string I could call the alert method, type in a string, I will put in a string of Hello from Flex.
03:18This function is already being called upon the click event of the first Button down here labeled called JavaScript,
03:24I will save the changes, run the application.
03:29Once again I will type in the name of the file I want to view, WebPageWithJS.html, click the GO button.
03:39Now I will click the Flex Call JavaScript button and you will see the exact same behavior.
03:44A native pop up window displayed by the JavaScript environment,
03:48click Okay to clear the window and then close the application.
03:53You can also make calls to custom JavaScript functions, for instance in this page
03:58that we are loading there is a function named sayHello that calls the alert method.
04:02So I will go back to the Flex application, ScriptBridging.mxml.
04:09I locate the callJSFunction() method and I will put in this code web.domWindow.sayHello().
04:18Both JavaScript and ActionScript are case sensitive environments so you must make sure to spell the names
04:23and your method calls exactly the same as they are spelled in the web page.
04:27I will save my changes and run the application;
04:31once again I will load the page WebPageWithJS.html and click GO that loads the page.
04:41Now I will call the JavaScript function that's hosted by the page
04:45and you will see once again that the pop window is displayed.
04:48I will click Okay to clear the window and close the application.
04:52The web page also has a function called setNameValue, its getting referenced to an element by its id nameInput
05:00and setting its value; this is the equivalent in JavaScript of setting the text property of a text input control.
05:07In order to call this method I'm going to have to pass in a value, so I will go back to the callJSFunction method,
05:14add a line of code above the current call and now I'm going to call the method within the JavaScript code
05:20which is you remember is named setNameValue using the same syntax as before,
05:26web.domWindow.setNameValue and now I will pass in my name, David.
05:35I save the changes and run the application; once again load the page, click the GO button.
05:46Now I will click the Call JavaScript Function button and you will see
05:50that in the background my name has been filled in the browser hosted text control.
05:56So those are the basics of Script Bridging going between ActionScript and JavaScript.
06:01There are some limitations here, for instance you can't call the get element by id function directly
06:06from your ActionScript code because you don't have the ability to get a direct reference to objects
06:11within the web page but you can make most things happen that you might want by calling functions either that are built
06:18into the web environment or custom functions that you have added to the page yourself.
Collapse this transcript
Understanding AIR security in JavaScript
00:00In this video I'm going to describe some of the rules that govern security in AIR applications particularly in regard
00:07to which code you can execute and what assets or resources on the local system that code can access at runtime.
00:14Error is built around the concept of security sandboxes, the capabilities of a particular set of code are determined
00:21by the origin of the code and how that affects what's it allowed to touch in the application environment.
00:28Each security sandbox has equivalent permissions, for example dynamic code that's loaded at runtime
00:34from a web based resource cannot be allowed to touch the local file system, local database or other local resources
00:42because that code has not gone through your security framework and the user hasn't explicitly accepted
00:47that code during the installation process, its not allowed to touch that outer world,
00:52that's how security sandboxes are designed.
00:55In the classic world of the web browser for example JavaScript code that's loaded either as part
01:00or linked to a web page can touch anything within that web page and anything else
01:05within the web browser security sandbox but can't move outside the security sandbox.
01:11Now the reason this is so important in the world of AIR is because as soon as you start working
01:16with the web browser component you actually have the ability to download code and execute it at runtime.
01:22The question is what is that code allowed to do?
01:26There are five security sandboxes known as the application, remote, local-trusted,
01:31local-with-networking and local-with-filesystem sandboxes.
01:36I am going to describe each of these sandboxes, which code is considered to be a part
01:40of that sandbox and what that code is allowed to do.
01:44The application sandbox consist of everything within the application folder that is everything
01:50that you can reach either through the app:/ URI or through file.application directory.
01:57As I have mentioned within previous chapters, content within that folder cannot be modified
02:02by the Flex application itself at runtime but code within that folder does have access
02:07to all other local resources such as the filesystem and database.
02:11Application based code gives you access to all the privileged AIR system APIs;
02:16the APIs that modify the filesystem of the database and network communication capabilities.
02:22On the other hand you cant dynamically import code and execute it directly from within the application area
02:28and for the most part dynamic code generation techniques are disallowed as well
02:33because the application environment contains code that for the most part has been complied or otherwise checked,
02:39that code can touch the local filesystem but code that you download
02:43from outside the application domain cannot be allowed to do the same.
02:48The remote sandbox consists of all the code that's downloaded from the Internet at runtime
02:54such as JavaScript code that's a part of or linked to a web page.
02:58The rules for this code are pretty much the same as classic web browsers, there are actually a few more restrictions
03:04than in a classic web browser environment because the AIR environment does give you
03:08so much access to the local system.
03:10If you download Flash documents or Flex applications at runtime the rules for that code are the same
03:16as when the code is run in the Flash Player that is if you use the HTML component and download a Flex application just
03:24because that Flex application is running in an AIR environment doesn't mean the code
03:28within the downloaded application can get to the local filesystem, it cant and that's the way you want it.
03:34This means that any code that the user is running that's accessing their local resources is code
03:40that they have explicitly accepted during the installation process
03:43and not code that's just been arbitrarily downloaded.
03:47There are three other sandboxes that apply to locally stored content, local-trusted content is stored locally
03:54and has been explicitly marked as trusted using either the Flash Player Settings Manager or trust configuration file.
04:02These files can read from local data sources and can communicate with the Internet and don't have
04:07to be loaded into the application directory.
04:10On the other hand there are some limitations to the privileges accorded this code
04:14that are only available through the application sandbox.
04:18The next sandbox is called local-with-networking.
04:22This kind of content is made up of a SWF file that's published with a networking designation
04:28that is that's been compiled with networking built-in.
04:31Only SWF based content can be considered to be a part of this sandbox; it does have not to be explicitly trusted
04:38by the user to do what it does and it can communicate with the Internet but it cannot read
04:44from local data sources or the local filesystem.
04:48Finally, the local-with-filesystem sandbox, local scripting files are a part of this sandbox
04:54when they have not been published with a networking designation and have not been explicitly trusted.
04:59This includes JavaScript files that have not been explicitly trusted and are not a part of the application sandbox.
05:06These files can read from local data sources but can't communicate with the Internet.
05:11There's a lot to know about AIR security and there is some great resources to help you out with a lot of the details.
05:17Here are two article and documentation recommendations,
05:21first an article on the AIR Developer Center at introduction_to_air_security.html.
05:27This article covers the basic idea of sandboxes and describes at a high level what sandboxes are for
05:33and what they do and more detailed document air_security.pdf, at this URL which goes much more in-depth
05:41into the world of security in AIR applications.
Collapse this transcript
6. Using Native Windows
Defining and instantiating native windows
00:00In this chapter of the video series, I'm going to describe how to define and instantiate Window components
00:06that is components that implement the native window interface,
00:10and can float freely independently of the main application Window.
00:14I will be showing you how to create these Window components, how to instantiate them,
00:18how to control the Window appearance, control the order of display on the screen,
00:23and many other facets of Window management.
00:25If you are following along with the exercises, go to Flex Builder, and import Flex project archive.
00:31From the Menu, select File, Import, Flex Project.
00:36Click the Browse button next to Archive File, navigate to the Chapter 06 Folder underneath the Exercises area,
00:44and import the file Chapter 06 beginproject.zip.
00:49Once the project has been imported, open it in the Flex navigator view, open the source folder
00:57and then open the application file DisplayWindow.mxml.
01:02This is a beginning application with just a little bit of code.
01:05There are two empty ActionScript functions named openWindow and closeWindow,
01:10and two buttons whose click events result in calling these functions.
01:13To create a native Window in Flex, you create a custom MXML component that's extended from the Window class.
01:21The Window class is similar to the WindowedApplication class.
01:25It represents rectangular area that's actually an operating system's specific native Window rather
01:31than a simple Flex container.
01:33When you open a window component, it results in creating a pop up window
01:38that floats independently of the rest of the application.
01:40As with all custom Flex components, I recommend that you create these components in sub-folders
01:46of your project rather than in the project source route.
01:49In the project, Chapter 06 Begin, there is already a folder named Windows.
01:54All of the native window components I create in this chapter will be placed in this folder.
01:59To create a new native window component, go to the Project, Right Click on the Windows Folder or Ctrl+Click
02:05on the Mac, and select New MXML Component.
02:10As with all MXML components, the file name determines the class name.
02:15Give this new component a file name of MyNativeWindow.mxml.
02:20In the Based on selector, select Window.
02:24As with all Flex components, you can either set the width and height to absolute values or you can leave them blank.
02:30The window will set its height dynamically to accommodate its child objects.
02:35Also as with the Panel, Title Window, and the application component,
02:39the Window component supports the layout property, which you can set to values either absolute vertical or horizontal.
02:46For this first Window component, set the layout to a value of Absolute and Click Finish.
02:53Notice that the custom component code is simply an MXML component with the root element of mx:Window.
03:00As I mentioned earlier, the layout property and the height and width are set in the Window component.
03:05There is also a property you can set here called Title.
03:09The Title property determines the value on the Title Bar of the Window when it appears on screen.
03:14So give this Window a title property of My Native Window.
03:18Next, create a label component within the Window.
03:24Give it a text property once again of My Native Window, and set its Font Size to 14 pixels, and its Font Weight to Bold.
03:37Also, to make the label center automatically in the Window, use constraint properties of vertical center set
03:43to 0 and horizontal center also set to 0.
03:47Save your changes.
03:49That will be your first Native Window Component.
03:51Now go to the application DisplayWindow.mxml.
03:55Place the cursor in the openWindow function.
03:58I'm going to maximize the Editor to see all of the code.
04:01In order to open a Window, you first instantiate the component.
04:05In order to be able to control the Window object from any code in the application,
04:10declare the variable that references the Window outside of any functions.
04:14Place the Cursor above the openWindow function and make some space.
04:18Then declare a new private var named win and data type it as an instance of the class My Native Window.
04:26Notice, as I select the class from the list of available classes,
04:30Flex that are automatically create an import statement.
04:33As with all Flex components in action script classes, you can import the class
04:37and then you can reference it only by its class name.
04:40Now, go to the openWindow function.
04:42I have declared the win variable which is an instance of My Native Window, but I still have to instantiate it.
04:49So in the openWindow method, I'll call it this code, win = new MyNativeWindow, and I'll construct the object
04:58from the My Native Window components, automatic no arguments construct a method.
05:03Next, I'll open the Window on screen using this syntax win.open.
05:08The open method takes an optional argument, Open Window Active.
05:12If set to false, that means open the Window but don't make it the currently active Window.
05:16If you leave this argument out or you set the value to true, the Window opens and is automatically active,
05:22that is it automatically has focused in the Windows environment, because I do want the Window to be active
05:28and because that's the automatic default value of this argument, I don't need to pass the value in.
05:32I will save the changes and run the application.
05:36I will Click the Open Window button and you will see the Native Window appears on screen, and in contrast,
05:44a pop up Windows that are completely built within the Flex environment such as those that are produced
05:48by the Alert class or that you create as custom pop up Windows using the Title Window or Panel containers,
05:55this native Window floats independently of the rest of the application.
06:00I will close the Window and then close the application.
06:04Now, let's add code to close the Window.
06:06I will go to the closeWindow function, and call the method win.close.
06:11Now, after I close the Window, I'm also going to set the reference to the Window to a value of null.
06:17This one is sure that I'm cleaning up after myself closing down and then destroying references to any existing Windows.
06:24This sort of good clean up architecture prevents memory leaks in your application.
06:28Save the change, run the application once again, try opening the Window, move it off to the side.
06:36Click back on the application and Click Close Window and you should see that the Window closes.
06:42Finally, go back to My Native Window and go onto Design View.
06:48I'm going to Restore the Design View Editor, and then go to the Components View,
06:53and drag in a button component and place it right under the label.
06:57I will change the label on the button to close, and then I'll go back to Source view.
07:03I would like to show you that a Window can also close itself by calling its own close method.
07:10I will add a click event handler to the button component, and then call Close.
07:16Save the change, go back to the application and run it.
07:21Once again I will open the Window from the application, and this time I will close the Window
07:26from the Window itself, and then close the application.
07:30You can see there would still be some more work to do.
07:32For instance, in the closeWindow method, if you try to close it and it was already closed, you might actually have
07:38to check first to see whether it was visible or whether it had been instantiated.
07:43Similarly, in the closeWindow method, if the user has not opened the Window yet, you have to do a little bit more work
07:49to make sure you are not trying to reference a null object.
07:52But, those are the basics of how to construct a Native Window and then how to open it
07:56and close it using code that's both in the application and in the Window component itself.
Collapse this transcript
Controlling native window appearance
00:00In this video, I'm going to describe how to control the visual appearance of native Windows that you define
00:06and instantiate in your AIR applications.
00:08For these demonstrations, I'll use an application named windowappearance.mxml in the Chapter 6 Project.
00:16If you are following along with the exercises, open that application now.
00:19I will also use a custom component in the Windows Folder named MyNativeWindow2.mxml.
00:26Once again, if you are following along with the exercises, open that source code file as well.
00:30MyNativeWindow2.mxml is a custom component that looks pretty much like the version I created in the previous video.
00:37It uses MX Window as its root element, has its layout property set to Absolute, and positions a label
00:43and a button control in the center of the Window.
00:46The Window appearance application instantiates the component and opens it
00:51and then in the Close Window function this time,
00:54checks to see whether the Window component is null or not, and then closes it.
00:59I'll run the application, so we can remind ourselves of the appearance of a default native Window.
01:04I will Click the Open Window button, and you will see that the Window adopts the chrome
01:09or the visual appearance of the hosting operating system.
01:13I'm running on Windows Vista.
01:14So the Window has an appearance that's provided by the Vista operating system.
01:19I see the Application icon in the upper left hand corner.
01:22If I Click the Icon, I get the Control menu.
01:25And I also see the various controls in the upper right corner of the Window
01:29to Minimize, Maximize and Close the Window.
01:32This chrome or visual appearance will look different depending on which operating system you are running on.
01:38If you are running on Windows XP, then number and positions of the control should be about the same,
01:43but the visual appearance will be a little bit different.
01:46And if you are running on Mac OS X, the number and presentation of the controls will be quite a bit different.
01:51It will essentially be a Mac OS X Native Window.
01:54I will close the Window and the application, and return to the code.
01:59In order to control the appearance of the native Window component, you can set properties either declaratively
02:05in the MXML declaration of the component or programmatically at run-time before you open the Window.
02:11I'm going to show you in this demonstration, how to set these values using MXML attributes.
02:16The default appearance of a Window uses a property called system chrome set
02:20to a value of standard, and a type set to normal.
02:26When you run the application with these settings active on Windows,
02:29you will notice that the native Window is represented by its own icon in the Task Bar, and you can switch back
02:36and forth between the main Window and the additional native Window by Clicking on those Icons.
02:43In this example, I'm going to set the type of the Window to a value of utility.
02:49A utility Window has fewer controls than a normal Window.
02:53In Windows, it's also not represented on the Task Bar.
02:56I will save the changes, go back to the application, and run it again.
03:01I will Click the button to open the native Window again.
03:04And this time, the native Window has a different appearance.
03:07In the upper right corner on Windows Vista and XP, there's only a Close icon
03:11where before there was a Minimize, Maximize and a Close.
03:15And the upper left corner, you don't see the Application icon anymore.
03:19Also, if you look down at the Task Bar in Windows,
03:22you will see that the Utility Window is not represented by a separate icon.
03:25I will close the Window and close the application, and once again return to the component code.
03:32Here's another property that you can set to get a different look to your Window.
03:36The systemChrome property can be set to one of two values.
03:40The default value of standard means that the operating system chrome is used to decorate the borders of the Window.
03:46If you instead set the value of systemChrome to none, that means take away the operating system chrome
03:52and just show the chrome that's provided by the underlying Flex framework.
03:57I will go back to Window Appearance and run the application again.
04:00I will open the Window, and this time you will see that the look of the Window is dramatically different.
04:06I still have Minimize, Maximize and Close buttons, but their appearance is quite a bit different.
04:11Also, if I Click in the upper left corner which I just did, I don't get a Control menu.
04:16That's provided only by the operating system.
04:18Once again I will close the Window and the application, and return to the component code.
04:25The next property I will show you is called showFlexChrome which I'll set to a value of false.
04:30I will also at the same time set systemChrome to none.
04:34I'm going to set three values together, showFlexChrome = false,
04:39systemChrome = none, and this time Type = lightweight.
04:46I'll save the changes, run the application again and once again open the Window, and this time you will see
04:54that the native Window shows up as just a white background without any chrome on the outside.
04:59I can still close the Window by pressing the appropriate keyboard shortcut or by Clicking the Close button.
05:05So I will close the Window, close the application one more time,
05:09then I'll come back to native Window, and set some styles.
05:12Finally, I'm going to set one more property transparent, set to a value of true.
05:18When showFlexChrome is false, systemChrome is none, type is lightweight and transparent is true, here is the result.
05:26I will run the application.
05:27I will open the Window, and all I'm seeing now is the actual Label and Close button that are a part of the Window.
05:35I will close the Window, close the application, come back to the component again.
05:41And this time, I'm going to wrap the label and the button in a V Box with a background color and a border.
05:47I will set the background color to an off white of # EEEEEE.
05:53Give the V Box a Border Style of Solid and a Border Color of Black which is #000000.
06:06Then, I'll move the label and button inside the V Box, give the V Box some padding settings, padding top of 10,
06:15padding bottom of 10, padding right of 10, and padding left of 10.
06:23And I'll also set the horizontal align to center, and the vertical align to middle.
06:31Because I'm placing these objects now within a V Box which automatically lines
06:35up its object in a single column from top to bottom.
06:39I'll remove constraint and absolute layout properties.
06:43Such as X, Y vertical center and horizontal center.
06:47I will save the changes, run the application again, open the Window.
06:53And this time, you will see that the Window appears as a transparent object without any system chrome.
06:59Now, in the next video, I will show you how to work with the transparent Window,
07:03and make it move across the screen when the user Clicks on it and Drags.
Collapse this transcript
Using transparent windows
00:00In this video, I'm going to describe how to initiate movement with the transparent Window.
00:05When you takeaway the system chrome from a Window, you remove the ability to capture mouse down events
00:11and initiate tracking of the Window position with the mouse movement.
00:15If you want the user to be able to move a transparent Window, you have to program it.
00:20It's a small amount of code, but it's something you become responsible for as the developer.
00:24For this demonstration, I'll use an application named UsingTransparentWindows.mxml that's
00:31in the Chapter 6 Project.
00:33I'll also use a component that's in the Windows folder named MyTransparentWindow.mxml.
00:39The code for my transparent Window is pretty much the same as myNativeWindow2 as it was at the end of the last video.
00:46It presents a transparent window that contains a V Box with a certain color and background.
00:51Mouse down events on the V Box will be handled correctly, but because the outer window is transparent,
00:58any mouse down events outside the V Box will be ignored.
01:01I'll run the application, and Click the button to open the Window.
01:07When the Window opens, it appears in the upper left hand corner of my screen.
01:11It may appear in a different position depending on your operating system.
01:14If I Click down on the Window, as I'm doing now,
01:17and then start to initiate mouse movement, notice that nothing happens.
01:21Also notice that if I Click off the V Box, the background application takes focus.
01:27I will come back to the Main Window, Click the Close Window button to make sure
01:31that the top level Window has been closed and then close the application.
01:35One issue that you might run into when you are working with Native Windows in Flex is that sometimes you end
01:40up with an invisible Window, and you don't even know it's present.
01:44When there is an invisible window present, you won't be able to launch another application because the AIR Debug launcher
01:50which is running the application in the background is still in memory.
01:53If you have this symptom that you are not able to run an application, go to the Task Manager on Windows,
02:00and check the processes list, and look for something named ADL.exe.
02:05Now, I don't have that as an issue right now.
02:07I don't see ADL.exe listed here, but if I did, I would select it, and then Click End Process.
02:14If you are working on Mac, you can Click on the Apple menu, and then select Force Quit,
02:19and once again look for the ADL application.
02:22And if you see it, Click that application, and then you will be able to launch your next application.
02:28Now, I would like to be able to move the Window across the screen when the user Clicks and Drags.
02:33I showed how to do this technique in the AIR 1.O Essential Training video series.
02:38I did it in that case with a full application.
02:41Here, I will do the same thing with the native Window.
02:44I will go to the MyTransparentWindow.mxml code, and I will add a mouse down event listener to the Window component.
02:54When the user presses the mouse button while the cursor is over any visual part
02:58of the Window, I will get a mouse down event.
03:00I will react by calling this code this.stage.nativeWindow.startMove.
03:11Notice that I'm calling the start move method from the native window object of the current stage
03:16that is the visual presentation area of the current Window.
03:20When the user clicks down, I will start the move operation.
03:23As long as the user keeps the Mouse Button pressed, and they move the Mouse around, the position of the Window
03:28on the screen will track with the mouse movement.
03:31When the user releases the Mouse button, the movement will stop,
03:35and you don't have to do any programming to make it stop.
03:37I will save the change, and run the application again.
03:41I'll once again open the Window, and this time I can Click on the Window,
03:47and drag it around the screen as much as I want to.
03:49Once again when I release the Mouse button as I will now, and then move the Mouse again,
03:54you will see that the Window stops moving by itself.
03:57So that's how we handle transparency and window movement in AIR.
04:01You handle the mouse down event on the Window level, and then you call that start move method
04:06as a method of the stages native Window object.
Collapse this transcript
Working in Full Screen mode
00:00In this video, I'm going to describe the use of Full Screen display when working with native Windows.
00:05All native Windows including an AIR application Window and any other native Windows that you instantiate and display
00:12in an AIR application can be spread out to take up the entire screen space.
00:17When you set a native Window to Full Screen, it gets rid of all of the system chrome that is the Title Bar
00:22and any other controls around the Window, and expands to fill your whole screen.
00:27For this demonstration, I'll use an application named FullScreen.mxml
00:32which you will find in the Chapter 06 Begin Project.
00:35If you are following along with the exercises, open the application in Flex Builder.
00:39I am also using a component in the Windows folder named MyFullScreenWindow.mxml.
00:46This component has two empty methods named displayFullScreen and displayNormal.
00:52Each method is called upon a click event of a button.
00:55I will go back to the application and run it, and then Click the button to open the native Window,
01:01and show you that it looks like a normal Window with complete system chrome.
01:05I will close the Window and close the application.
01:08Then, I'll go back to the component MyFullScreenWindow.mxml.
01:13To change Window to display in Full Screen mode, you set the Windows stage object's display state property
01:19like this this.stage.displayState, and then you set it to one of three values,
01:28Full Screen, Full Screen Interactive and Normal.
01:32These String values will represent those constants in a class named Stage Display State
01:38which you call like this StageDisplayState.Full_Screen.
01:43I will also go down to the function Display Normal, and put in similar code.
01:50This time change it back to a normal display,
01:53this.stage.displayState = StageDisplayState.Normal, and that's all you have to do.
02:04Now, when the user Clicks the Full Screen button, this Window will expand to take up the entire screen,
02:09and when they Click the Normal button, it will showing back down to its original size.
02:13I will save the changes, and return to the application and run it.
02:18I will Click the Open Window button, and there's my native Window.
02:21Notice, like all native Windows, I can drag it around the screen.
02:25I will Click the Full Screen button, and the Window expands to take up the entire display.
02:31Now, I'll Click the Normal Display button, and it returns to its original size.
02:36The user can also control and turn off the Full Screen display.
02:40I will Click the Full Screen button again.
02:42It expands to take up the entire display.
02:45And now, I'll press the Escape key and notice that the behavior is the same.
02:50It returns to normal.
02:51Again, you can do this with any native Window, the application or any other native Window that you pop
02:57up from the application simply by setting its stage object's DisplayState property.
Collapse this transcript
Changing the order of multiple windows
00:00In this video, I'm going to describe how to control of the order of Windows in an AIR application.
00:05When you open multiple native Windows, they sometimes overlap each other
00:10and they are presented in what's called the Z order.
00:13Z order is the relative depth of Windows relative to each other that is.
00:17The reason it is called the Z order is because it is one of the three dimensions,
00:21X being Horizontal, Y being vertical and Z being the depth.
00:25You can control the order of the native Windows using methods of the Window object named order to front,
00:31order to back, order to front off, order to back off and activate.
00:36So in this video, I will demonstrate a couple of these methods,
00:39I will be working in an application named OrderingWindows.mxml.
00:45If you are following along in the exercises, you can open this application from the Chapter6 Project.
00:51The application declares three instances of native Windows,
00:54one for each of three components OrderedWindow1 OrderedWindow2 and OrderedWindow3.
01:01These three components are very simple Windows that are almost identical to each other,
01:05the only difference being their titles and background colors, one is red, one is green and one is blue.
01:10I will run the application and show you that when I click the Open Windows button, all three Windows are opened.
01:19Window 1, Window 2, and Window 3.
01:23The application is set up to handle an event called closing
01:26and when that event happens it automatically closes all of its native Windows.
01:31So all we have to do to close all the Windows is just close the application Window and I'm back to the start.
01:37Now, I would like to control the order programmatically of these Windows.
01:42In the application display area, down at the bottom
01:44of the code there are three buttons labeled Window 1, Window 2, and Window 3.
01:50And for this demonstration when the user clicks each button, I want to bring that Window up to the front.
01:56So I will add a clickEventHhandler for the first button and when the user clicks the button,
02:01I will call this code win1.orderToFront().
02:07I will do the same thing for each of the other two buttons.
02:09Click equals (=) win2.orderToFront() and for the third button click equals (=) win3.orderToFront().
02:19I will save the changes and run the application.
02:24Once again, when the application opens up I will click the Open Windows button,
02:27I will get all three Windows open on the screen.
02:30I will move them around a little bit so we can all three of them.
02:33Then I will come back to the application Window and click each of the buttons.
02:38Clicking Window 1, Window 2 and Window 3 and once again
02:44when I close the application, all of the Windows close automatically.
02:48Now, I will change the code so that instead of orderToFront() I use orderToBack().
03:00I will save the changes and run the application.
03:06Once again opening the Windows and then moving them around on the screen so that I can see them all
03:12and now I will click the buttons in reverse order this time sending each Window
03:16to the back, Window 3, Window 2 and Window 1.
03:21Notice that the Window Z order takes into account not just AIR-based Windows, but all native application Windows
03:27and because I have Flex Builder already running on the screen, the other Windows are ordered behind that Window.
03:33So I will close the application again.
03:36This time I will use a function called orderInFrontOf and I will pass in a value of (this), meaning the current Window,
03:43and I will do the same thing for all three Windows.
03:54I will save my changes once again run the application.
03:58I will open all three Windows, once again I will move them around so that I can see them all on the screen.
04:05And now when I click each button, notice that the order of the Windows is changing in a minor way.
04:10I will click Window 1, Window 2, and Window 3 and you will see each time,
04:17I click the button the Window order is changing, but the Windows are not disappearing behind Flex Builder.
04:22Once again, you can use the activate function as well and that also has the meaning of bringing a Window up to the top
04:29of the Z order so that it overlaps any other Window.
04:32So those are some methods of the Window Class that you can use to control the order
04:37of multiple native Windows in an AIR application.
Collapse this transcript
Handling window events
00:00In this video I'm going to describe the events that are dispatched when you manipulate native windows.
00:05I will be using the application WindowEvents.mxml, this application creates an instance of a native window based
00:12on the OrderedWindow1 component that was used in a previous video.
00:16I will run the application and show that right now all it does is open the window so that we can then manipulate it.
00:23I can then close the window by clicking the Close Window button or by clicking the controls on the window itself.
00:29I will close the application and return to Flex Builder.
00:33You can listen for and react to any of the events that occur as the user manipulates the native window.
00:39It is worth looking at the help system for the Window class.
00:42This class dispatches many events having to do with window manipulation.
00:46For instance when the window is closed there are two events that are dispatched,
00:50one named closing which is dispatch before the close happens and one named close
00:55which happens after the window has been closed.
00:58Similarly, there is one called Display State Changing, for when the display state is changing to Minimize,
01:03Maximize or restore and one that occurs named Display State Change that is dispatched after the change has happened.
01:09There is a Resizing and a Window Resize.
01:12Now many of these events are dispatched as simple event objects.
01:17For instance the Close event is dispatched as flash.events.Event.
01:22The same thing is true for the Closing event but not all native window events are equal.
01:28Some of these events dispatch very specialized event objects.
01:31For instance Window Resize dispatches an event object named FlexNativeWindowBoundsEvent.
01:37This event object has properties called the afterBounds and beforeBounds which return rectangle objects
01:44and you can determine from the rectangle that was returned, the dimensions of the object and the size.
01:50So let's take a look at listening for particular events.
01:53I will go back to the WindowEvents.mxml application and place the cursor inside the openWindow method,
01:59opening up an empty line of code after the win variable has been instantiated and before it has been opened.
02:05I will call win.addEventListener and first I'm going to listen for the event Event.CLOSE.
02:13When this event is dispatched I will call the method that is already been declared
02:16in this application call winEventHandler.
02:20I will do the same thing for the Closing event, I'm going to copy that little bit of code that sets up the Event Listener
02:28and then paste it right below and change the second one from Event.CLOSE to Event.CLOSING.
02:36Since both events dispatch the same kind of event object, I can reuse the EventHandler function.
02:42Then in the EventHandler function I will add a bit of tracing code.
02:45I will put in a trace function call, a literal string as a label
02:50and then the type of the event which is the event name.
02:53Now I will run the application in Debug Mode, I will click the button to open the native window,
03:00now watch what happens in the Console View below as I close the window.
03:04First I get the Closing event and then I get the Close event.
03:09You will always get the events in that order and that will be critical when you want to try
03:12to prevent certain behaviors as I will show you in the next video.
03:16Let's take a look at another one of these events.
03:20This time I'm going to listen for the event window_resize, this is the event that occurs
03:25when the user has just resized the window.
03:28The event object for this event is not a standard event class,
03:32instead it is an instance of FlexNativeWindowBoundsEvent.
03:35So once again I will listen for the event and this time I call the method boundsEventHandler.
03:42Then I will go down to the function that has already been declared
03:46in the application and once again I will do a trace.
03:56I will save the changes and once again I will do a trace to output the event type.
04:00I will run the application in Debug Mode, open the Native Window and this time watch what happens as I resize,
04:09I'm going to move the cursor to the border of the window, click down and then resize just a little bit and notice
04:17that every time I resize even just a pixel that event is dispatched again.
04:22There are many other events you can listen for and you can look at the documentation to find
04:26out which events are dispatched and what data type the event object will be when each event occurs.
Collapse this transcript
Preventing default window behaviors
00:00In this video, I'm going to describe how to prevent default behavior
00:04when certain events of the native window class occur.
00:08I use the application PreventDefault.mxml.
00:11If you are following along in the exercises, you can open this application in Flex Builder.
00:17In this version of the application, we are still listening for various events,
00:22but notice that at line 16 the addEventListener is listening for the closing event and dispatching the event object
00:29to this specific eventHandler function, closingHandler, this is an empty function.
00:34For each event that ends with ing such as resizing, closing and so on,
00:41you can prevent the default behavior whenever you want to by calling the method
00:45of the event object called preventDefault.
00:48Not all events can be prevented.
00:50For instance, if it's an event that simply reporting that something already happened like close or resize,
00:56then it's going to be too late, the event will have already occurred,
00:59but for those events that are predicting future behavior, the preventDefault method
01:03in most cases prevent the behavior from occurring.
01:07Before I fill in this method, I'm going to add a visual control to the application.
01:12I'll place the cursor after the buttons and add a CheckBox control, the CheckBox control reflects a Boolean state,
01:20its selected property returns either true or false depending on whether the user has selected the control.
01:26I'll set the CheckBox controls id as okToClose and give it a label of OK to close?.
01:35Now, I will go back to the closing handler method.
01:39In order to decide what to do I'll take a look at the selected property of the check box,
01:44if not okToClose.selected, so I'll ask the question, is it okay to close the native window
01:55and I'll use the syntax, if not okToClose.selected.
02:00So if user has checked the check box, I'll allow the closing behavior to happen, but if it isn't selected,
02:06I'll prevent the behavior like this, I'll call the method event.preventDefault,
02:12I'll save the changes and run the application.
02:16I'll open the native window, move it to the side so I can see the applications interface and now I'll try
02:23to close the native window by clicking the Close button in the upper right corner.
02:27If you are working on the Mac click the Close button in the appropriate location.
02:31Notice that the window won't close, I'll go back to the application and try to close it
02:36from the button and again it won't close.
02:40Now I'll check the checkbox and close the window by clicking the button which executes some ActionScript
02:47to close the window and the native window closes.
02:50I'll open the window again and then once again uncheck the checkbox, try to close the window from its own interface
02:58and it won't work, come back to the application, click the checkbox go back to the native window
03:04and close it from here and now it closes correctly.
03:07The ability to prevent this default behavior is important because for example,
03:12if the user closes the application window before we've closed all the other windows
03:17that can cause certain problems leaving invisible windows in memory and so on.
03:21By selectively listening for the closing event and other events that you may want to prevent, you can handle them
03:28and then checking your conditions, call the event objects preventDefault method
03:33to stop that future behavior from happening.
Collapse this transcript
7. Using Native Menus
Creating native menus
00:00In this chapter of the video series I'm going to describe the use of Native Menus.
00:05A native menu is a menu component that's hosted and presented
00:08by the hosting operating system of the AIR application.
00:11In contrast to pure Flex based menus which are always presented inside the Flex window,
00:17a native menu is presented either as part of the native menu that wraps the Flex application or for example in Mac OS X
00:25as part of the native operating system interface.
00:27If you are following along with the exercises
00:29in this chapter you can import the Flex project that contains all of the starting code.
00:34From the Flex Builder menu select File, Import, Flex project, click the Browse button next to Archive File,
00:43navigate to the Chapter07 folder under the Exercises area and select Chapter07BeginProject.zip, open the project
00:54and click Finish and that will import the project into Flex Builder.
00:59Then go to the Flex Navigator view, open the project, open it's source folder
01:04and then open the application file UsingNativeMenu.mxml.
01:09This application has two empty methods named init and selectHandler.
01:13The init method is being called upon the applicationComplete event of the application,
01:18the selectHandler is an event handling function that I'll use later in this exercise.
01:23When you create a menu you always start off by creating an instance of the NativeMenu class,
01:28this class can be added either to a Windows or to a Mac environment,
01:32but you add it differently depending on which operating system you are in.
01:36In this video I'm going to show you how to use the particular code for your operating system
01:41but then in the next video I'll show you how to dynamically determine
01:45which operating system is currently hosting the AIR application
01:49and execute the correct code for the current user.
01:52To get started, place the cursor inside the empty init method and add an extra line of code.
01:57The first step is to create a menu object, declare a local variable named Menu, data typed as the NativeMenu class
02:06and instantiate it using the NativeMenu class's no arguments constructor method.
02:12I'll expand my editor to see as much code as possible.
02:16Now for each item you want to add to the menu, create an instance of the NativeMenuItem class.
02:22When you instantiate this object and call the constructor method you can pass
02:26in a string value which will be the menu item's label.
02:29Create a new menu item like this, var menuItem1, data typed as a NativeMenuItem.
02:39Then instantiate it using =new, then call the constructor method of the class NativeMenuItem and then pass in a label.
02:49I'll put in a label of File.
02:52Next you'll listen for the Select event, when the user selects a particular menu item it dispatches a Select event
02:59and you'll pass the event object to the predeclared selectHandler method like this, MenuItem1.addEventListener,
03:09listen for the event that's represented by the constant Event.SELECT
03:14and pass the event object to the selectHandler method.
03:19Now add the menu item to the menu like this menu.addItem and pass in the menu item.
03:27Now you will create another menu item.
03:33Declare another variable named menuItem2 once again data typed as a NativeMenuItem object and constructed
03:41from the class's constructor method and this time pass in a label of Edit, the next two steps are the same
03:50as for the first menu item, so I'll go up to the previous two lines and select the code that adds the event listener
03:57and adds the menu item to the menu, copy that to the clipboard and then paste it at the end of the method,
04:06then I'll go back and change menuItem1 to menuItem2 for both bits of code.
04:12Now the next step is to actually add the menu to your application.
04:17The code for this will look a little bit different depending on whether you are working on Windows or the Mac.
04:22For Windows, you add the menu to the actual native window that wraps the application.
04:27The code looks like this, stage.nativeWindow.menu=menu.
04:34Now if you are working on Mac and I'm not, so I'm just going to comment this code out once I've typed it in,
04:41for Mac OS X you use a bit of code that looks like this, NativeApplication.nativeApplication.menu=menu.
04:53When you code this code on the Mac it replaces the standard File, Edit menu that displays
04:59on all Mac native applications, it's also possible to add menu choices to a Mac menu if you want and I'll talk
05:06about that a little bit more in the next video.
05:08Now again I'm running on Windows here, so I'm going to comment that code out and I'm only going
05:12to use the Windows version, stage.nativeWindow.menu=menu.
05:17Now I will go down to the selectHandler method and I will add a call to the trace method to detect
05:23and report when the user selects a menu item.
05:26I'll pass in a literal string Menu item selected and then I will concatenate the label
05:35of the selected menu item like this event.target.label.
05:42Now I will run the application in Debug Mode.
05:45When the application appears it displays my two menu items at the top, now again if you are working on Mac OS X
05:54and you used the Mac specific code that I showed you, then you'll see the menu choices appear at the top of the screen.
06:00Select either of the menu items and you should see in the console in the background
06:05that the trace method is outputting the selected menu's label.
06:08There is the File and there is the Edit menu item.
06:12Now again in the next video, I'll show you how to determine which kind of menu is supported
06:17and then add it to the right place dynamically.
Collapse this transcript
Adding native menus to windows and applications
00:00In this video, I'm going to describe how to dynamically determine
00:04which operating system the application is currently running in and then how to use the appropriate code
00:09to add a native menu to either the native window or to the native application.
00:14For this demonstration, I'll use the application AddingMenu.mxml.
00:19In this version of the application the code that constructs the menu sets
00:24up event listeners has been wrapped into a function called createMenu.
00:28This function returns a native menu object and then in the init method,
00:33the returned object from that function is passed to the menu object of the native window.
00:37Once again the application in its current state only works correctly on Windows and if you are running it
00:43on Mac you'd right now want to comment out the line of code at line 11 and uncomment the code at line 13.
00:50But in order to dynamically determine where to place the menu,
00:53we can use a property named supportsMenu that's implemented
00:57on both the native window class and the native application class.
01:01In both cases, it's implemented as a static property meaning that you call the property as a member
01:06of the class definition rather than an instance of the class.
01:10To make sure that you are only trying to add a menu to a native window where it's supported,
01:15wrap the existing line of code in a conditional block that looks like this.
01:19if (NativeWindow.supportsMenu) then put in a pair of braces and move the code that's currently adding the menu
01:29to the native window into the braces that follow the Boolean expression.
01:33Now, you'll only be adding the menu where it works.
01:36You can do something very similar for the Mac, place the cursor after the comment for Mac
01:42and add a conditional clause if (NativeApplication.supportsMenu).
01:49Once again, add a pair of braces after the if clause.
01:53Now move the commented code into the if clause, remove the comments and change the code so that instead of trying
02:03to retrieve a menu object, we're simply taking the value from the createMenu function
02:08and passing that to the native applications menu.
02:11Now, here is a very important note about working on Mac OS X,
02:15native applications in Mac OS X already have a standard menu.
02:20When you pass a native menu to the menu object in this fashion, you are replacing the standard menu.
02:27The standard menu has many choices like File, Edit and so on.
02:31If instead you want to add items to the standard menu, using method of the menu object called Add Item
02:38and then you'll be adding the menu to the existing menu.
02:41This code however should work for this demonstration.
02:44I'll save the changes and run the application and you'll see on Windows once again that the menu appears correctly
02:51and if you are working on Mac OS X, you should see that the menu works there correctly as well.
Collapse this transcript
Using submenus and keyboard shortcuts
00:00In this video, I'm going to describe how to add submenus to native windows and also how to use keyboard shortcuts.
00:07For this demonstration, I will use an application named SubmenusAndShortcuts.mxml that's
00:13in the Chapter07, Begin Project.
00:16If you are following along with the exercises open the application in Flex Builder.
00:20In this version of the application, I'm once again creating a menu and then adding it either to the native window
00:27or the native application depending on the operating system.
00:31In the createMenu method, I'm now adding submenus.
00:35A submenu is a menu that appears when the user clicks on a top level menu item.
00:39For instance, if the user clicks on the FileMenu item, I would like to display a submenu that includes item
00:45such as Open, Close and other file related actions.
00:49Currently, I'm getting the submenu from a method named createFileMenu,
00:54which is declared a little further down in the code.
00:56To see this behavior, I have placed the cursor after the line of code
01:00that creates the menu inside the createFileMenu method.
01:04Then I will add a couple of new items to the menu.
01:07I will call menu.addItem and then I will pass in a new NativeMenuItem and I will add
01:16in a string of Open, as the MenuItem' label.
01:19I will add another item, once again adding the NativeMenuItem,
01:25using its constructor method and this time the label will be close.
01:32I need to make sure that I have added the right number of parenthesis at the end
01:35of each line of code, that code should now work.
01:39Now, as you add more items to the menu, it becomes a little bit cumbersome
01:44to call the addEventListener method for each menu item.
01:47In fact, you can actually listen for an event at the top level menu rather than on each individual menu item.
01:54So that's what I will do.
01:56I will go back to the createMenu method and I'm going to take the addEventListener code that's currently listening
02:01on a single item, I'm going to cut it to the clipboard
02:06and then move it below the first line of code that creates the menu.
02:10I will paste it in and then I will change the member
02:14on which the addEventListener method is called from MenuItem1 to simply menu.
02:19Then I will go locate the addEventListener call for MenuItem2 and I will remove that.
02:25I now have a single event listener for the entire menu and it will work whether the user chooses a top level MenuItem
02:32without a submenu or individual submenu items.
02:35I will save the change and run the application in Debug mode.
02:40Now, watch what happens, when I click the top level item that has a submenu and select one of its items,
02:47I get feedback in the form of a trace output in the console.
02:51I will do that again, for File, Close and you should see the same reaction.
02:56Now, when I click Edit at this point, I'm not getting any feedback and that's
03:00because the Edit menu item also has a submenu, which is being created in the createMenu method
03:06and it's shown here currently on line 37 of my code,
03:10where I'm setting that top level object submenu using the createEditMenu method, so let's go to that method.
03:18This time, as I create an addItems to the menu, I'm going to return a reference to that item,
03:25so that I can modify its behavior a little bit.
03:28Within the createEditMenu, I'm first going to create a new variable named copyCmd, data typed as a NativeMenuItem.
03:38Then I'm going to call menu.addItem and as before, I will instantiate the object,
03:46using the NativeMenuItem classes constructor method.
03:52Now, that should be enough, but I would also like to add a keyboard shortcut.
03:57To add a keyboard shortcut to a MenuItem, set its key equivalent property like this, copyCmd.keyEquivalent = --
04:09and then the letter that I want to attach.
04:11The automatic behavior will be then on Windows, the user will be able to hold down the Ctrl key and press C
04:17and on Mac, they will be able to hold down the Command key and press C and that will have the same functional effect
04:23as selecting the menu from the item with the mouse.
04:25Now, I will do the same thing and I will create a paste command.
04:32Once again data typing it as an instance of NativeMenuItem, I will add the item to the menu
04:37and I will construct the NativeMenuItem and pass in a label of Paste.
04:48I will make sure I have added my closing parenthesis in both lines of code and then for the Paste command,
04:55I will once again add a keyboard shortcut using the key equivalent property
04:59and for this menu item I will choose the letter P. I will save the changes
05:06and run the application, once again in Debug mode.
05:13When the application opens up, I will open the Edit menu and select Copy and I should see the MenuItem is selected
05:21and then I will select to paste and I should once again see that the MenuItem is selected.
05:26Now, I will press the appropriate keyboard shortcuts.
05:29Here's Ctrl+P and here's Ctrl+C and you will see the trace output appear
05:35in the console and Flex Builder in the background.
05:38This should be working in the same way on the Mac OS X, instead of pressing Ctrl+C
05:42or Ctrl+P, you will press Command+C or Command+P.
05:46So that's a look at adding submenus and using keyboard shortcuts on NativeMenuItems.
Collapse this transcript
Using the FlexNativeMenu control
00:00In this video, I'm going to describe how to use a component named FlexNativeMenu.
00:05This is a Flex component that's wrapper for the standard native menu object, that makes it a lot easier to declare
00:11and use a native menu at the application level.
00:14For this demonstration, I will use an application named UsingFlexNativeMenu.mxml, if you are following along
00:20in the exercises, you can open this application file from the Chapter07 Begin Project.
00:27Open the application and take a look at the source code.
00:29There's an XML packet that has a root element and then two menuitem elements.
00:34The menuitem elements represent NativeMenuItems, each with a label.
00:38Within those, there are menuitem elements as well, this is just XML.
00:43But notice that the format attribute is set to e4x, this is going to allow us to address each of the items
00:49within the XML content using e4x expressions.
00:54Now, to take this XML structure and pass it into a NativeMenu,
00:59place the cursor after the windowed application tag and add a pair of mx menu tags.
01:05This will be the menu property of the windowed application component.
01:09There's a bit a magic that will happen here.
01:11You may remember if you watched the earlier videos that when you construct a NativeMenu using ActionScript code,
01:17you have to determine dynamically whether you are going to add the menu to the NativeWindow
01:22or to the NativeApplication, that is whether you are running on Windows or the Mac.
01:27When you use this architecture, you don't have to worry about that
01:30because the windowed application component takes care of it for you.
01:34Now, within the menu property declaration, declared instance of the FlexNativeMenu component,
01:40set its DataProvider using a binding expression to the XML object, myMenuData.
01:46You don't want to show the root element of the XML.
01:49So set a property named showRoot to a value of false.
01:53Also, you have to tell the FlexNativeMenu object, what element or attribute
01:58of the XML structure to use as its label.
02:01Set the labelField to the value of @Label.
02:05This is an e4x expression that says each element has a label attribute,
02:10from which we will get the label value, that should do the trick.
02:14Go ahead and close the tag and run the application.
02:17Now, if you are running on Windows as I am, you should see that the menu appears as a part of the NativeWindow
02:22and if you are running on the Mac, you should see the same menu appear at the top
02:27of the Mac interface as the Application menu.
02:29Now, close the application and I will show you how to handle the events that are dispatched
02:34when the user selects various items from the menu.
02:37When the user selects an item from the menu, you get an event named itemClick.
02:41Add an itemClick event listener attribute and put in some ActionScript code to call a new method that we'll create
02:47in a moment named itemClickHandler and pass the event object.
02:54Now, go down to the Script section and create that function, make it a private function.
03:00Once again its name is itemClickHandler and this time the name of the event class that will be used
03:07as the event object is FlexNativeMenuEvent typecast the event argument as FlexNativeMenuEvent and return void
03:16from the method and now place a breakpoint on the last line of the function,
03:22that is the function with the closing brace.
03:25Save your changes and run the application in Debug mode.
03:31Go to the menu and select any item, I will select the Copy item.
03:35In the background, Flex Builder may ask you to go into the debugging perspective, if so click Yes.
03:41If it doesn't prompt you to go into the debugging perspective, but you are still on a breakpoint,
03:46just go to the debugging perspective manually.
03:48Now, double-click the Variables tab to expand it to full screen and examine the event object.
03:54Notice that the event object is typed as FlexNativeMenuEvent and it has properties named index, item and label.
04:03The label property is the label that was applied to the item.
04:07The item is the XML note that generated this menu item and the Index is the ordinal position of this menu item
04:14within its submenu, in this case it's the first item.
04:17So index is set to a value of zero.
04:20Double-click the Variables tab again to restore to regular size and then terminate your debugging session.
04:26Go back to the Flex Development perspective and place the cursor inside the itemClickHandler method
04:33and put in your trace command this time and report the event objects label property like this.
04:39Item clicked: -- put in a literal string of Item clicked then concatenate to that event.Label.
04:49Save your changes, remove the breakpoint.
04:52Once again, run the application in Debug mode and then as you interact
04:57with the menu, watch the console in Flex Builder.
05:00I will select an item and I should see a trace message in the console reporting which menu item was selected.
05:10So that's how we use the FlexNativeMenu component to generate a native menu that's part of the application.
05:16?Its advantage over the standard native menu class is that you can declare it in MXML,
05:21whereas the standard menu object can only be declared in ActionScript.
05:25Also you can dynamically populate the NativeMenu object from XML formatted data that you can either hard code
05:31in your application or retrieve it run time perhaps using http service or some other data retrieval method.
Collapse this transcript
Using context menus
00:00In this video, I'm going to describe how to use the FlexNativeMenu object to create a context menu.
00:06That is a menu that appears when the user places the mouse cursor over an object
00:11and either right-clicks or on the Mac Ctrl+clicks.
00:14For this demonstration, I will use an application named UsingContextMenu.mxml, if you are following along
00:21with the exercises, you will find this application in the Chapter07, Begin Project.
00:26In this application, there is a simple label control at the bottom, it's positioned in the center
00:32of the screen and has a simple text value.
00:35There is also an XML structure with two menu item elements, one with the label of Upper Case
00:40and the other with the label of Lower Case.
00:43You can declare a FlexNativeMenu object either in MXML as I did in the previous video or in ActionScript
00:50because I already showed you the MXML version, this time I will use ActionScript
00:54and then you can choose whichever approach you like.
00:57In this application, there's already a variable named myMenu which is data typed as FlexNativeMenu.
01:03Place the cursor in the init method and initialize myMenu using the FlexNativeMenu constructor method.
01:14Next, set its dataProvider.
01:17I'm setting all of the same properties as I did in the previous video.
01:20This time just using ActionScript instead of MXML.
01:23I will set myMenu.dataProvider to the menuData XML object
01:29and as before I will set the menus, showRootProperty to false.
01:33This will prevent a menu item from appearing for the root element.
01:40Now, I will set its labelField, the labelField properties is string, so it gets wrapped in quotes.
01:47But I'm still using an e4x expression of @Label, this means that the label attribute of each element is used
01:55as the label for the menu item and then I will add an event listener.
02:00When the user select an item from this menu, I will get an event named itemClick,
02:06the itemClick event generates an event object typed as FlexNativeMenuEvent.
02:11So I will listen for that event using the itemClick constant and then I will pass the event object
02:17to the predeclared itemClickHandler method.
02:21Finally, I will associate this menu object with the label control as its context menu.
02:27To do that I will call a method of the menu control called SetContextMenu.
02:33I will pass in the visual control that I want to associate it with.
02:37In this case it's the label with an id of LBO, that's already declared
02:41at the bottom of the application, that's it.
02:44This function is already being called upon the creation complete event of the application.
02:49So as the application starts up, I create the menu, I set its data provider, set the show root
02:55and labelFfield properties to determine the structure and presentation of the menu at the event listener
03:01and then associate it with the visual control using the setContextMenu method.
03:06Now, I will go to the itemClickHandler method and add some code to determine what I'm going to do.
03:12I will put in a conditional clause and I will inspect the value of event.Label.
03:17As I showed in the previous video, this property is the label of the selected menu item.
03:22I will compare event.Label to a value of Upper Case.
03:27If the label property of the event object is Upper Case, I will transform the label's text property
03:35to an Upper Case value, using LBO.text=LBO.text.toUpperCase.
03:45Then I will put in an else clause, I will copy and paste that code into the else clause and I will change it so that
03:54if the user selects Lower Case, the only other menu item I will transform the text to Lower Case.
04:00I will save the changes and run the application.
04:03When the application opens, it displays the menu in the center of the screen, I will right-click on the label
04:09and select Upper Case and you will see its text is transformed.
04:13I will right-click again and select Lower Case and you will see that the text is transformed.
04:17Again, this should work exactly the same on a Mac.
04:21The only difference will be that if you are working with a Mac without a right mouse button,
04:25you should hold down the Ctrl key and click instead and you should still see the exact same context menu.
Collapse this transcript
Displaying menus in the system tray or Dock
00:00In this video, I'm going to describe how to apply a native menu to the system tray icon
00:06when you are running an AIR application in Windows or to the Dock when you are running in Mac OS X.
00:11For this demonstration, I will use an application named SystemtrayAnddock.mxml in the Chapter07BeginProject.
00:19If you are following along with the exercises, open the application in Flex Builder now.
00:23This is another version of the previous application that applies a native menu as a context menu.
00:30In the init method, an object named myMenu is created, datatyped is FlexNativeMenu
00:36and then the menus set context menu method is called to associate the menu with a particular visual control.
00:43In this application, we are going to take that same menu and apply it instead to the system tray icon
00:48in Windows or to the Dock icon on the Mac.
00:51To get started this version of the application already implements a system tray icon.
00:56Notice that lines 11 and 12 of the application there is an Embed metadata tag and associated variable named icon16.
01:04This results in embedding a 16 square pixel graphic in the application and associating it with the variable icon16.
01:12Then in the beginning of the init method, there is a bit of code that checks
01:16to see whether the current application supports the system tray icon.
01:20Switching over to Mac OS X, if you are running the same application on MAC OS X you'll be able to see
01:26that the application context menu appears when the user right-clicks or clicks
01:31and holds down their mouse button while the mouse is over the system Dock icon representing the application.
01:36The code that executes this functionality is down towards of the middle of the application where it says
01:42if NativeApplication.supportsDockIcon then dockIconMenu = myMenu.
01:49I will run the application and we'll see the behavior.
01:51As the application opens up, the Mac operating system automatically displays an icon on the Dock
01:58when you run this application from within Flex Builder you are actually running the AIR Debug Launcher
02:04in the background.
02:05And so the icon you see and any legend such as the one I'm showing right now will indicate ADL.
02:11When you run the same application after packaging and installing it using the AIR installer,
02:16you'll see the applications icons instead.
02:19Either way, the user can move their mouse cursor over the icon in the Dock and then either right-click
02:25or hold down their mouse button for a few seconds until the context menu appears,
02:29because I have a two button mouse I'll right-click and I'll see the customized menu
02:35and once again they are my custom functions to take the label in the middle of the application and change it
02:40to uppercase or to change it to lowercase.
02:44So you'll see that this same menu object can be used in many different ways, as a context menu for any visual object
02:51or as a system tray menu if you are running on Windows or as a Dock menu if you are running on Mac OS X.
Collapse this transcript
8. Monitoring Network Connections
Understanding network monitoring
00:00In this chapter of the video series, I'm going to describe the use of network monitoring tools that allow you to detect
00:06at runtime whether an AIR application has accessed to network resources.
00:11AIR applications are frequently designed to be occasionally connected, meaning that when they have accessed
00:16to the network they can get their data and the files from an application server
00:20and when they are not connected they can get their data and resources from the local file system.
00:25An application that's connected to the internet frequently gets its data through a middle way or application server
00:31that in turn tucks to a network hosted database.
00:34Other network resources that an AIR application might use, might include xml files or other content
00:40but when that same application is hosted on a computer that's currently disconnected from the network
00:45but for certain applications it can make sense to have the applications still be useful even when disconnected.
00:52For example, an AIR base client application might use the local file system and the local database.
00:58The network monitoring tools allow you to determine proactively whether the network resources are available
01:03at any given time and then you can make an intelligent decision as to which resources you will address.
01:10The network monitoring classes are implemented through a class called ServiceMonitor.
01:15This is a superclass that implements the entire network monitoring framework and then there are two subclasses
01:20which is the ones that you actually instantiate in your AIR application.
01:26The subclasses include the URLMonitor class that allows you to monitor endpoints or network resources
01:32that can be reached through HTTP and HTTPS communications
01:37and another component named SocketMonitor that's designed to be able to monitor other endpoints.
01:42For example, you might want to monitor whether an RTMP endpoint, that's used for messaging
01:47and the data management service might be available.
01:51Here are the steps you follow for setting up monitoring.
01:54First, you create a monitor object.
01:56The object should be typed as either URLMonitor or SocketMonitor.
02:00You typically don't use the ServiceMonitor class directly.
02:04You tell the monitor object as you set it up, what is the endpoint, that is what is the URL
02:09of the resource that you want to monitor.
02:12Then optionally set a pollInterval property to a set of milliseconds to indicate how often you want
02:18to monitoring object to ping the server and determine its availability.
02:22By default the pollInterval property is set to zero and in this case the status check only happens
02:28when the network availability changes as determined by and reported by the operating system.
02:33Alternatively, you can set pollInterval to a positive number in terms of milliseconds.
02:38For example, 2000 would mean that the pollInterval is every two seconds.
02:43Then the component that you are using for monitoring either URLMonitor or SocketMonitor will communicate
02:49with the server once each time that period elapses.
02:52Once you have set it all up you start the monitor object.
02:55Then each time the network status changes, you will get an event named status.
03:01So those are the steps and in the following two videos I will show you exactly how
03:05to implement this using both components URLMonitor and SocketMonitor.
Collapse this transcript
Using the URLMonitor
00:00In this video, I'm going to describe the use of the URLMonitor class.
00:04This class allows you to monitor the availability of the resource that you communicate with over HTTP or HTTPS.
00:12For the demonstrations in this chapter, I will be using a Flex Project that's available in the exercises area.
00:17If you are following along with the exercises you can import the project.
00:22Go to the Flex Builder Menu and select File, Import, Flex Project.
00:28Click the Browse button next to Archive file, navigate to the Chapter08 folder
00:32in the Exercises area and select Chapter08BeginProject.zip.
00:39Then, when you come back to Import Flex Project, click Finish.
00:43Go to the Flex Navigator view and open the project and open its source folder
00:48and then open the application UsingURLMonitor.mxml.
00:55This application has two embedded graphics named availableIndicator and notAvailableIndicator.
01:01These graphics will be used to display the availability of network resources at runtime.
01:06At the bottom of the application, there is an image component, the source property,
01:10is bound to the notAvailable image icon and a label control with an id of statusLabel.
01:15When you start up the application initially it simply displays the notAvailable indicator graphic
01:21and a message Checking URL status.
01:24Close the application and return to the code and then place your cursor above the init method.
01:29The first step in network monitoring is to create an instance of a monitor object.
01:34In this case, I will use the URLMonitor class.
01:37Declare a private variable name it monitor and data type it as URLMonitor.
01:44Now move the cursor into the init method.
01:46Now I will instantiate the variable using the URLMonitor class's Constructor method.
01:52This constructor method requires an instance of the URLRequest object.
01:57So I will add new URLRequest and then I will passing
02:02to that constructor method the actual location of the resource I want to monitor.
02:07In this case, I'm going to use http://localhost that is a service that's available on my local system.
02:15Next, I will start the monitor.
02:17Now as the monitor starts up it's going to send out an initial request to this location.
02:24When the response comes back it will determine whether it got back a valid response
02:29and at that point it's going to dispatch an event, named status.
02:33So now before I start the monitor, I will add an event listener.
02:36I will make a little bit of space before they call to the start method and add this code monitor.addEventListener
02:43and I will select the constant StatusEvent.STATUS to represent the status event.
02:50Then I will react by calling an event listener function that I will need to create, named statusHandler.
02:56Now create that function.
02:59Place the cursor after the init method and create another new function, name this one statusHandler.
03:07As with all event handler functions this will receive an event argument
03:12and this one will be data typed as StatusEvent.
03:16The function returns void and initially all we are going
03:20to do is trace the current availability of the network resource like this.
03:31I will put in a little string of Available then I will concatenate it to event.target.available.
03:39The available property is a member of the URLMonitor class and it's a boolean value
03:44that indicates whether the monitored resource is currently available.
03:47I will save my changes and run the application.
03:51Now notice initially that I haven't started up my web server even in fact you have WAMP or MAMP
03:57or any other web server currently running on the standard port 80 on your local machine, turn it off before this test.
04:03Now I will run the application in Debug mode.
04:07As the application starts up it sends out an initial ping and notice in the Console view at the bottom of Flex Builder
04:13that I get back a message Available: false.
04:17Now I'm going to close the application and I'm going to start up my web server.
04:21If you are working on Windows and you followed the earlier instructions in this video series,
04:25you have installed a product named WAMP and if you are working on Mac you might have installed MAMP.
04:31Go ahead and start up that server now.
04:33On Windows Vista, I will go into the Start Menu and type wamp and locate the menu choice start WampServer.
04:40I will wait for few moments until the server started and I will be able to tell on windows
04:46that the server is completely started by looking at the system tray icon in the lower right-hand corner.
04:51I should see that the indicator needle is all the way to the right and if I move the cursor
04:56over the icon I get a tool tip server online.
04:59Now I will run the application again, once again in Debug mode.
05:04I will wait a moment and this time I get back a message Available: true.
05:09Now I'm going to add some logic to the statusHandler function
05:13to manipulate the visual interface of the application.
05:16I have closed down the application and now I will go to the statusHandler method and I will add a conditional clause
05:23if (event.target.available) and now I'm going to make two changes to the interface.
05:31First I will set the imgIndicator.source
05:34to the bound availableImg object that's the embedded graphic represent availability and I will change statusLabel.text
05:44to Network available and in the else clause I will set imgIndicator.source to notAvailableImg and once again,
05:57modify the statusLabel's text property and I will put in the string Network not available.
06:06I will save the changes and run the application, noting this time that the WampServer is running.
06:13Notice as the application starts up initially it says it's Checking the URL and then it reports Network available.
06:19I will close the application.
06:22Now I will go down to the WAMPSERVER and turn off the services.
06:25You can do the same thing at the MAMP server if that's what you are using.
06:28For WAMP, I will click on the icon in the system tray and select Stop All Services, then I will wait a moment
06:35for the service to shutdown then I will run the application again and after a few seconds,
06:40you will see the message Network not available.
06:42Now in the next video, I will show you how to set the polling interval
06:46so that you can control how often you are rechecking network availability.
Collapse this transcript
Setting the pollInterval property
00:00In this video, I'm going to describe the use of the pollInterval property.
00:04This numeric property allows you to determine how often a monitoring object checks
00:09for the availability of a network resource.
00:12By default, the pollInterval property is set to a value of zero
00:16and in this case a monitoring object will check availability upon starting
00:20and then only will be retriggered whenever the operating system informs the monitoring object
00:25of a change in network availability.
00:27For this demonstration, I will use an application named UsingpollInterval.mxml.
00:34This is the same application as was built in the previous video.
00:37It creates a URLMonitor object.
00:40It starts the monitor object and then listens for the status event which occurs whenever network availability changes.
00:48Now because I'm working with an application server on my local system, it will always be available or unavailable,
00:54but its availability won't be effected by general network availability.
00:58So the default behavior of the monitor object that is
01:00to check its availability whenever the operating system network capability is turned on and off,
01:06won't be useful for this example, instead I will set the pollInterval property.
01:10So I will go to the init method and I will add this code monitor.pollInterval = 2000.
01:19The pollInterval property is measured in milliseconds.
01:22So this means I want to monitor to recheck availability every two seconds.
01:26I will save my changes and run the application and on my system I first made sure that I'm running WAMP,
01:33my application server with the integrated web server.
01:36As the application starts up, it initially reports that the network is available.
01:41Now I will go down to the system tray and if you are running on Mac you want instead to go
01:46over to the MAMP application or you can follow a similar operation.
01:50I will click the System Tray icon and select Stop All Services.
01:54It takes a few moments for the service to shutdown but you will see that the application reacts almost immediately.
02:00Now I will go back to the WAMP System Tray icon, once again click it and this time select Start All Services
02:07and once again the application reports that the network is now available.
02:11So the advantage of the pollInterval property when you set it to a very tight time frame such as two seconds is
02:17that you will be notified of changes in network availability almost immediately.
02:22The disadvantage of this approach is that you are using up network in application server resources
02:27because every two seconds you repinging the server and if you have hundreds or thousands of clients
02:33out there, you might overload your server.
02:35So if you use the pollInterval property just be aware that it is creating network in application server traffic
02:42and you should balance the use or overuse of those network resources against the need for the local client application
02:48to know when network availability has changed as quickly as possible.
Collapse this transcript
Using the SocketMonitor
00:00In this video, I'm going to describe the use of the SocketMonitor component,
00:04that allows you to monitored network resources other than those that you communicate with over HTTP or HTTPS.
00:12For this demonstration, I will use the application UsingSocketMonitor.mxml.
00:17If you are following along with the exercises you can open this file in Flex Builder.
00:22This is the same application that I was working on in the previous videos.
00:27It currently uses the URLMonitor class.
00:29To check for a resource at localhost under http it gives an event listener to listen for the statusEvent
00:36and when that event occurs, it reports current network capability.
00:40Because I have set the pollInterval property at two seconds, it rechecks every two seconds.
00:46Now for this demonstration, instead of checking for the availability
00:49of the Apache web server, that's living at port 80 on local host.
00:53This time I'm going to check for the availability of MySQL, which operates on and listens at port 3306 by default.
01:02The URLMonitor class won't be able to do this.
01:04It only communicates over HTTP.
01:06So I'm going to make a few changes.
01:08First I will go to the import statement at the top of the scripting section and I will change the import
01:13from air.net.URLMonitor to air.net.SocketMonitor.
01:19Then I will go to line 19 and change the data type of the monitor variable from URLMonitor to SocketMonitor
01:27and then I will go down to the instantiation of the object at line 23
01:32and change the constructor method in the same way.
01:34Now the SocketMonitor constructor method takes two arguments instead
01:40of the single argument I passed into the URLMonitor constructor.
01:44The first argument is a string which is the host I want to communicate with.
01:48You no longer use URLRequest in this case.
01:51So I'm going to change this first argument.
01:54I will take the parenthesis, I won't be instantiating URLRequest and I also won't prefix localhost with http.
02:03I'm now only indicating where is the server I want to communicate with.
02:07Then I will move over to after the declaration of the host and I will add the port number which is 3306 and again,
02:15this is the port number that MySQL listens on by default.
02:19The rest of the code is exactly the same.
02:21You are listening for a StatusEvent, you are still starting the monitor
02:26and in this example I'm still polling every two seconds.
02:30Now I have started up WAMP already.
02:32My server is running including both Apache and MySQL so I can now run the application and as the application starts
02:39up the SocketMonitor component makes an initial check and finds that MySQL is available.
02:46Now I will turn off the MySQL service.
02:48If you are working on Windows with WAMP, you can get to the service administration tools to the system tray icon.
02:54If you are working on the Mac with MAMP, go to the MAMP application
02:58and click on the MySQL tab and turn off the service from there.
03:03In MAMP, we turn it off like this.
03:05I will go to MySQL, Service, Stop Service.
03:11It should take less than two seconds for the application to determine that MySQL is no longer available.
03:17Now I will turn MySQL back on.
03:19I will go back to the system tray icon, I will select MySQL, Service, Start/Resume Service and once again
03:29within two seconds the application reports availability.
03:33Now again, if you are working on the Mac and you are using the MAMP integrated server bundle,
03:37you will go to the MAMP application and shutdown MySQL from there.
03:41Either way the application should correctly determine that MySQL is either turned on or turned off
03:47and it can then make an intelligent decision as to whether it should communicate
03:51with the network or with the local database.
Collapse this transcript
9. Using the Local Database
Understanding the integrated SQLite database
00:00In this chapter of the video series, I'm going to describe how
00:03to integrate the local database that's a part of AIR into your applications.
00:08The Adobe Integrated Runtime includes an embedded database engine based on the SQLite open source database.
00:15When you create a new database you stored on the local system as a file with the .db file extension.
00:21You will use classes that are a part of the AIR libraries to create the database
00:26and communicate with it with SQL statements.
00:29The location of each database file and its name is up to you.
00:33The only requirement is that the database files must be placed in a folder
00:36to which your AIR application can read and write the content.
00:40For example, you might placed the file in the Application Storage folder.
00:44That's the folder that's unique to each application and to each user on the local system or you might place it
00:50in a specific location under the user's home directory,
00:53represented in AIR by the userDirectory property of the File class.
00:57Here are the basic steps for using a local database.
01:01First you designate the location and name of the database file by representing it in a file object.
01:07Then you connect to the database with a class called SQLConnection.
01:11You will take the file class and pass it to the SQLConnection's Open method.
01:15Then you will create a statement represented by an SQL Statement object
01:19and connect the SQLStatement to the connection.
01:22Finally, you will execute the statements.
01:25All database operations can be either synchronous or asynchronous in much the same way as file system activities.
01:32The implications of synchronous versus asynchronous operations are the same as with file system activities.
01:39If you execute a long-running operation synchronously, it results in suspending the main application thread
01:45and any animations or user interactions are prevented for the duration of the database operation.
01:51If you instead use asynchronous operations, the application thread can continue to operate independently
01:57or the database operation runs in the background.
02:00When you work with the SQL connection and SQL Statement classes,
02:04you communicate with the database using SQL, Structured Query Language.
02:08The implementation of the SQL language and SQLite is not as extensive or deep as it is in say Oracle or SQL Server,
02:17but you will find that all of the standard SQL Statements that you might expect are supported.
02:22For example, basic statements such as Select, Insert, Update and Delete allow you to add,
02:28maintain and retrieve data from your database at runtime.
02:31You will also have a very strong implementation of data definition language statements including the ability to add
02:38and drop Tables, Indexes, Views and Triggers.
02:42There are certain things that are not available in SQLite.
02:45For instance, Foreign Key Constraints, another more advanced database functionality is not available.
02:50To find out more about what you can and can't do in SQLite, check the Flex 3 documentation,
02:56specifically section labeled local database SQL support.
03:00In the remaining videos of this chapter, I will show you how to create a database, add data, maintain the data,
03:07retrieve the data and how to maintain transactions and at the end of this chapter,
03:12I will talk about how to create an occasionally connected application that gets its data primarily
03:17from a network based database and then when the network isn't available instead can move to using the local database
03:24and then when it's connected again, can synchronize and move that data back into the network.
Collapse this transcript
Creating and connecting to a database
00:00In this video, I'm going to describe how to create a new database using a combination
00:05of the File class and the SQLConnection class.
00:08For all the demonstrations in this chapter, I will be using a Flex Project that's part of the Exercises area.
00:14If you are following along in the exercises you can import the project now.
00:18From the Flex Builder Menu, select File, Import, Flex Project.
00:24Click the Browse button next to Archive file, navigate to the Chapter09 folder under the Exercises area
00:31and select the file Chapter09BeginProject.zip.
00:35As with all chapters there is also a project that contains the ending code for all demonstrations in the chapter.
00:41After you have finished importing the project, go to the Flex Navigator view,
00:46open the project and open the project's source folder.
00:49Then open an application named CreateDatabase.mxml.
00:54This beginning application has an empty function named createNewDatabase
00:58and a button whose click event handler calls the function.
01:02In order to create a new database, you will first instantiate a file object and point the file objects path
01:08to the location of the database file you want to create.
01:11Then you instantiate an SQLConnection object and call its Open method.
01:15There are two versions of the open method, one for synchronous operations and the other asynchronous.
01:20For this demonstration, I will use synchronous operations
01:23and then I will show you the asynchronous version in a later video.
01:27Place the cursor above the createNewDatabase function and make some space.
01:31You typically declare the SQL Connection object outside of any functions
01:36so that you can then address the object from any function in the application.
01:40I will declare the variable like this, private var sqlConn, data typed as SQLConnection.
01:47I will also declare a variable named SQLFile, data typed as a File class.
01:54This is the same file class that you used in file management operations that I demonstrated in an earlier video.
02:02Now move the cursor to the createNewDatabase function.
02:05You can place the database anywhere on disk as long it sits in a folder to which your application has read/write access.
02:12The most common place to create a local database is somewhere within the user's home directory.
02:17For instance, you could use the userDirectory property of the File class and then use its resolvePath property
02:23to designate the name and location of the database under there or if you want to bury the database
02:28in the application storage area, you could place it in the app storage folder.
02:33For this demonstration, I'm going to place the database on the user's desktop,
02:37so that we can easily see when the database has been created.
02:40Within the createNewDatabase function, set the reference of SQLFile as follows, File.desktopDirectory.resolvePath
02:51and then passing the name of the database you want to create.
02:54I'm going to call it Contacts.db.
02:58Next, instantiate the connection, sqlConn = new SQLConnection.
03:06The SQLConnection class's Constructor method doesn't receive any arguments.
03:10Now you will open the connection using the file objects as follows, sqlConn.open and then pass in sqlFile
03:19as the reference, that is the location of the file that you are connecting to.
03:24The second argument of the Open method is the mode in which you are opening the database.
03:29There are three available modes represented by constants in the class SQLMode.
03:34The modes are Create, Read and Update.
03:36If you want to create a brand new database call SQLMode.CREATE.
03:41That's also the default value.
03:43So if you didn't pass this argument at all it would have the same result.
03:46It's also worth mentioning that if you call this code passing in the create mode and you connect
03:51to a database file that already exists it will be the same thing as opening the mode as Update.
03:57So you won't actually be overwriting or creating a brand new database if you called the create mode again.
04:03Now, I'm going to close the database so that I can show you
04:06that simply opening the database actually creates the database file.
04:10Then I will add a trace method in so that when I run the application in Debug mode,
04:15I will see that the function executed successfully.
04:18I will save the change, run the application in Debug mode.
04:24Now I'm also going to restore the size of the Flex Builder so that I can see my desktop in the background.
04:30I will move the application off to the side.
04:32I will click the Create Database button and you will see two things.
04:37First of all, in the Flex Builder Console view, I see the trace output Database created
04:43and on my desktop I see the new database file has been created, Contacts.db.
04:49Now again, if you call the same code again using the mode of SQLMode.CREATE, it won't recreate the database.
04:58It will detect that the database already exists
05:01and it will simply open the database and allow you to read and write data.
05:05So that's how you create a database using synchronous operations.
05:09In the next video, I will show you how to do the same thing using asynchronous operations.
Collapse this transcript
Using asynchronous database operations
00:00In this video, I'm going to describe how to use asynchronous operations when working with the local database.
00:06Just as when working with the local file system, synchronous operations can have a result
00:11of suspending the main application thread.
00:13If you execute a long-running query this can freeze the applications animations, user interactions and anything else
00:20that you might want the user to be able to see.
00:23To prevent this from happening, you can asynchronous operations and then the SQL operations will run
00:28in the background freeing the main application thread to remain interactive.
00:33For this demonstration, I will use the application AsynchronousSQL.mxml in the Chapter09Begin Project.
00:41If you are following along with the exercises, you can open this application now.
00:45This is the same application I built in the previous video.
00:48It currently opens the SQL database synchronously and then immediately response by closing the connection.
00:55I am going to change this version of the application to create a new copy
00:59of the database which we will now call ContactsAsync.
01:03Go to line 13 where the name of the database is determined and change the name
01:07of the database file from Contacts.db to ContactsAsync.db.
01:14Next, go to line 15 that calls the open method and change from the open method to openAsync.
01:20When you open a database asynchronously, the operation will happen in the background.
01:25When the operation is complete the connection object dispatches an event called open.
01:30This event and most of the others that are the part of the local database system
01:34in AIR is dispatched as an event object typed as SQLEvent.
01:38Place the cursor above the Async method and make an extra line of code and add a call to the add event listener
01:44like this, sqlConn.addEventListener listen for SQLEvent.OPEN
01:53and then call a method called openHandler which we will need to create.
01:57Now place the cursor at the bottom of the script section below the existing function
02:02and create a new function named openHandler, which receives an event argument, data typed as SQLEvent.
02:11Return void and add the braces.
02:15Now move a little bit of code around.
02:17Go back to the createNewDatabase function and locate the code sqlConn.close.
02:23Because we are now opening the connection asynchronously we shouldn't immediately close it so cut
02:28and paste that code and move it into the openHandler method.
02:35Similarly, we only want to notify the user that the database has been created when this event is handled.
02:41So go back to the createNewDatabase and comment out the trace method call.
02:46Go back to the openHandler method and add a call to Alert.show.
02:51Remember to always select the Alert class from the list of available classes and that will ensure
02:57that the appropriate import statement is added.
02:59In the Alert.show method pass in two strings Database successfully created and Opened.
03:12Save your changes and run the application, this time in Normal mode.
03:19Click the Create Database button and you should see the message appear, Database successfully created.
03:25I will close the application, minimize Flex Builder and show you
03:31that ContactsAsync.db was successfully created on the desktop.
03:35So that's a look at how to use asynchronous database operations.
03:39For simplicity, I will primarily use synchronous operations in all these demonstrations but I will also say
03:45that most application deployed using the Adobe Integrated Runtime, use asynchronous SQL operations to ensure
03:52that the main application thread isn't tied up while the database is active.
Collapse this transcript
Creating database tables
00:00In this video, I'm going to describe how to create a Database table in the local database.
00:06I'll be using the SQL connection class again to open the Database and then I will use a class called SQL statement
00:13to encapsulate an SQL command and execute it against the local Database.
00:17For this demonstration I will use the application CreateTable.mxml,
00:22that you'll find in the Chapter09BeginProject.
00:25If you are following along with the exercises, you can open this application now.
00:29In this version of the application, the code to open the database has been moved into a function named openDatabase.
00:37As in the earlier video that opened the Database synchronously.
00:41I use an SQL File object to define the location of the Database as Contacts.db on my desktop.
00:49Then I create a SQLConnection object and open the Database.
00:54That function is in turn being called by function called create NewTable
00:58and that's where I will execute the new code.
01:01Place the cursor in the create NewTable function and then make a little bit of space after the call to open Database.
01:08The first step is to create an instance of the SQL statement class, declare a local variable named stmt for statement,
01:18datatyped as SQL statement and instantiate it using the SQL statement classes no arguments constructor.
01:26Next, Set the statement objects SQLConnection property to the connection that's already been opened.
01:33stmt.sqlConnection = sqlConn.
01:38The Next step is to add a text property.
01:42The statement's text property is the SQL statement that you want to execute.
01:46I'm going to use some Data definition language to create a new table named Person.
01:52The code will look like this.
01:54Stmt.text = then I will add a command to create a table.
02:00I'll add clause named if not exists.
02:04This means that if the table I'm about to create already exists, I shouldn't recreate it.
02:09Next I will put in the name of the table and an opening parenthesis.
02:13I'll close that little string then add a plus operator to concatenate me to the next value.
02:20Now, I'll add each of the columns one at a time.
02:24The first column will be the primary key named person id.
02:27Each column gets the name, a data type and any modifiers.
02:34For the primary key I will use an integer column.
02:37I'll declare that it's going to be the primary key and also that it's an Auto Incrementing column.
02:44So that as I add new records to the database table, if I don't indicate a person id value,
02:49the database will simply assign the next available value.
02:53It's worth mentioning that SQL light allows you to add explicit values
02:57to primary key columns, even if they marked as Auto Increment.
03:00That isn't the case for all Databases.
03:03I'll put in a comma, close this string and add a plus operator and go to the next line to add the next column.
03:11The rest of the columns are all going to be string values,
03:15which in SQL Light as implemented in AIR is datatype called simply Text.
03:21So, each Database column will have a name.
03:23The first one will be Firstname and a Data type of Text.
03:31The Next, we'll have a data type of lastname and data type of Text and so on.
03:38Now to speed up this operational a little bit, I'm going to clone this line of code.
03:42In Flex Builder and all of the clips, you can hold down the Ctrl and Alt key on Windows or the Command and Option key
03:48on the Mac and press the down cursor key and that will copy and paste that line of code.
03:54I'll create a bunch of column definitions and then go through and change their names appropriately.
04:00Street address, city, state, email and phone, that'll be the last column, so, I won't put in a comma,
04:16instead I will put in a closing parenthesis and then I'll close the ActionScript statement with the semicolon.
04:25Now, I'll execute the statement for any SQL statement you simply call the SQL Statement Object's Execute method.
04:34There are some optional arguments including managing, fetching order and item responders.
04:40If you're familiar with how to use items responders for instance, when we're using RPC components
04:44such as remote object, you can use a similar architecture here.
04:48For this demonstration though because I'm working synchronously,
04:51I'll simply call the Execute method with no arguments.
04:54Every time you call the execute method of an SQL statement.
04:58It generates an internal object.
05:01You can retrieve the result object as a class named as SQLResult, like this; var result,
05:08datatyped as SQL Result equals and then you call the statement objects GetResult method.
05:20Finally, I'll add a Trace statement and indicate that the table was created.
05:28I'll save the changes and I'm going to place a break point right here at line 36, where I'm executing the trace method.
05:36This is after I've executed the statement and retrieved the result.
05:39This will allow me to debug the result object.
05:42I'll run the application in debug mode, click the create Database button, that will take me to the break point
05:51in flex builder, where all open the flex debugging prospective and then double click on the Variables tab
05:57to inspect the Data and take a look at the SQL Result object.
06:02The SQL Result object will differ in its content, depending on what kind of SQL statement you've executed.
06:09For instant, when you're creating a Database table.
06:12The Data property of the SQL Result object is no.
06:15On the other hand, if you retrieve data, the Data property will refer to the return Data.
06:20Similarly, If you were to execute an insert an update or a delete, the row's affected property would be the number
06:26of Rows that were effected by the operation.
06:29When you are executing the Data definition language statements such as a create table command.
06:33The Rows affected property returns zero.
06:36So, this is how you can find out what happened after an SQL statement was executed.
06:42I'll restore the size of the variables view and then click to resume the operation and in the console view,
06:49you'll see the message table was created.
06:51This Database now has a single table named person.
06:54It has the same structure as the Database that I demonstrated earlier in this video series.
07:00The contacts Database that was built in my SQL and in a later video I'll talk about how to replicate the Data
07:06from the network Database hosted in MySQL and make copies of that data
07:11in the local Database using simple insert statements.
Collapse this transcript
Inserting data
00:00In this video, I'm going to describe, how to insert data
00:03into a local database table using the SQL connection and SQL statement classes.
00:08For this demonstration, I will use an application named InsertData.mxml from the Chapter 09BeginProject.
00:16If you are following along with the exercises, you can open that application now.
00:21In this version of the application, all of the code to open the database and then create the percent table,
00:27if it doesn't already exist, has been moved in to a method named init.
00:32Then, that method in turn is being called upon the creationComplete event handler
00:37of the Windowed application component.
00:39So, as the application starts up, I'm already connected to the database and the table should already exist.
00:46There's also an empty method named createRecord,
00:49and a button component whose click event handler calls that method.
00:53Place the cursor in to the createRecord method and add some space.
00:57Start by creating a new SQL statement object.
01:00I will declare a local variable named stmt, datatyped as SQLStatement.
01:06As before, I will instantiate it, using the SQLStatement classes no arguments constructor.
01:13Then, I will set the object's sqlConnection property to my SQL connection, which I have named sqlConn.
01:21Remember that connection object is declared outside of any functions
01:25and then was instantiated and opened in the init method.
01:29I will go back to the method and continue the work.
01:33The next step is to create the text property of the statement object and as before,
01:39this is the actual SQL statement that you want to execute.
01:42I will build the statement one line at a time.
01:45INSERT INTO person and then an opening parentheses.
01:50Now, in flex builder, if you want to create a series of concatenated strings, just type in the first string
01:56and then before you put in to quote, press Enter or Return and you will see that Flex Builder adds a closing quote
02:02and a plus operator to the current line and then adds an opening quote to the next line for you.
02:07That makes a little bit easier to build these concatenate strings.
02:12Now, because I'm going to be inserting a new record, I want the data base to use the auto increment property
02:18of the primary key column Person ID to assign the next available numeric value.
02:23Therefore, I won't pass in the name of the primary key column.
02:27Instead I'm going to simply list the names of the columns, into which I'm adding my own literal data;
02:33these columns are, firstname, lastname, streetaddress and again as I start reaching the end of the line,
02:42I will just put in an extra space at the end and then press Enter.
02:46Then, city, state, email and phone.
02:51I will put in a closing parentheses to indicate that that's the end of the list of columns and then and extra space
02:58to separate the code from the next line and I will press Enter
03:02and put in the key word VALUES and again an opening parentheses.
03:07Now, I will put in a list of literal values that I want to insert into the table.
03:12These will all be string values and following standard SQL syntax, the values will each be wrapped in single quotes.
03:19So, the first name will be Joe, the second name will be Smith, the street address would be 123,
03:27Main St. and again any time I want to end that bit of literal text
03:32and start in a new line, I will simply press enter.
03:36Then, the city will be Seattle, the State will be Washington, WA, the email address will be joe@crazymail.com
03:49and the phone number will be 123-555-1111 or any other phone number you want to enter
03:57and I will close the SQL statement with a closing quote and a semicolon.
04:02So, that's my SQL statement.
04:04If you have long SQL statements like this,
04:07you can break them up into multiple lines consisting of multiple concatenated strings.
04:12They are all pushed together or concatenated into a single string and then assigned
04:16to the text property of the SQL statement object.
04:20Now, I will execute the statement to actually add the data to the database.
04:25I will call stmt.execute just as I did before.
04:29Then, I will get the result by declaring a variable name result,
04:34datatyped as SQLResult then I will set the result property by declaring a variable name result, datatyped as SQLResult
04:42and I will get a reference to that object from the statement object's' getResult method.
04:47I will add a call to the trace function and I will output a message of Data inserted and then,
04:55I will place a break point on the last line of the function where the trace method is being called.
05:00I will save the changes and run the application in debug mode.
05:04I will click the Create Record button and in the background you should see
05:09that the Flex Builder prompts you to go to the Flex Debugging perspective.
05:14I will switch to Flex Builder.
05:15Click yes to switch to the flex debugging perspective.
05:19Take a look at the variables' view and then look at the result object.
05:23You should see that the result object's complete property returns true.
05:28The rows affected value should be one, meaning that one row was inserted.
05:33So that tell you that this was a successful operation.
05:37Now, in the next video, I will show you how to retrieve that data from the database table and then store it
05:42in your Flex Air Application for use and presentation.
Collapse this transcript
Retrieving and handling data
00:00In this video, I'm going to describe, how to retrieve data
00:03from the local database using a standard SQL Select statement.
00:07I will show how the data is returned as an array and then how you can wrap that array inside an array collection
00:13for display and management in a Flex application.
00:17For this demonstration, I will use an application in the Chapter09BeginProject named RetrieveData.mxml.
00:25This is the same application I was working on in the previous video,
00:28but this version of the application has added an empty function named retrieveData and the button
00:33with a label of retrieveData that calls the function.
00:37Place the cursor inside the retrieveData method
00:40and just as before declare a local variable named stmt datatyped as SQLStatement.
00:48Instantiate the object using the SQLStatement class's no arguments constructor method.
00:54Then plug in the Statement object and the Connection object
00:57by setting the Statements object's sqlConnection property to sqlConn.
01:03As I described in previous videos, the connection is declared outside of any functions
01:10and then it's instantiated and opened as the application starts up.
01:14Going back to the retrieveData method, as before, set the Statement object's text property to the SQLStatement
01:23that you want to execute, this is going to be a very simple Select statement, SELECT * FROM person.
01:30Now, I will execute the Statement and once again declare a variable name result, datatyped as SQLResult
01:38and I will get the reference for the result from the Statement object's getResult method.
01:44Now I will set a breakpoint on the last line of the function, that is the line that has closing brace,
01:50save your changes and run the application in Debug mode.
01:57Click Create Record a few times, notice in the Console
02:01that each time you click Create Record, you will get the message, Data inserted.
02:05For now, you are inserting the same data over and over again.
02:10Now, click the Retrieve Data button.
02:12When you hit the breakpoint, Flex Builder might prompt you to open the Flex Debugging Perspective.
02:18If so click Yes, then open up the Variables view and inspect the SQLResult object.
02:26Locate the result property and open it in the Variables view and notice
02:31that the data property is now data typed as an Array.
02:34Open the array and you should see multiple data Objects.
02:39Each of the data Objects has the same set of data.
02:42But you will notice that each Object's personid property representing the primary key has a different value.
02:49Now, restore the Variables view to it's regular size and click the Resume button.
02:54Go down to where the breakpoint is and remove it from code, so we can continue running,
03:00go back to the running application, click the Create Record button a few more times, go back to Flex Builder,
03:08put the breakpoint back in, go back to the application and once again retrieve the data, go back to Flex Builder
03:16with the Breakpoints suspending the application and inspect the data again and you will see now,
03:22that there are many more rows of data in the application.
03:26So that's how you retrieve the basic result.
03:29Now terminate the Debugging session and return to the Flex Development Perspective.
03:34Now we know that the data comes back as a data property of the result object.
03:39It's an array and we would actually like to have that data stored as an array collection.
03:45So the next step is to wrap the data inside an array collection like this,
03:50go back to the top of the Script section and declare a new Bindable variable named acContacts,
04:01data typed as ArrayCollection.
04:03Now move down to the retreiveData method and instantiate acContacts like this, acContacts = new ArrayCollection
04:16and pass the array into the ArrayCollection constructor like this, result.data.
04:24An ArrayCollection is a wrapper around an array which provides dynamic access to the data at runtime.
04:31Now go down to the DataGrid component and add a dataProvider property and use a binding
04:37and bind to the acContacts array collection.
04:40Now before I continue, I'm going to check my Problems view and see if there are any issues and in fact there is one.
04:46I accidentally added a pair of parenthesis when I declared the ArrayCollection.
04:51I'm only declaring it, so I don't need the parenthesis there.
04:55I will save the changes, making sure that all the problems have been cleared up and I will run the application.
05:03Once again, I will click the Create Record button a few times and then I will retrieve the data and I will see
05:09that the data has been stored in the database persistently on the local system
05:13and that I can retrieve the data using a standard SQL Statement.
05:17So let's once again review the steps in retrieving data.
05:20You create an SQLStatement object.
05:24You set it's sqlConnection property to a connection that's already opened, you set the Statement object's text property
05:31to the SQL command that you want to execute.
05:34You call the Statement object's execute method to execute the SQLStatement, then you get the result back
05:40from the Statement object's getResult method.
05:42It comes back as an array and if you want to represent it as an ArrayCollection, you wrap the array inside a new instance
05:49of the ArrayCollection class and then you have data that you can safely bind to visual controls.
Collapse this transcript
Using SQL statement parameters
00:00In this video, I'm going to describe how to use parameterized SQL statements,
00:05that is SQL statements that have place holders for values that you can then fill
00:09in programmatically using a bit of ActionScript code.
00:12For this demonstration, I will use an application in the Chapter09BeginProject named UsingParameters.mxml.
00:21If you are following along in the exercises, you can open that application now.
00:25In this version of the application, we are once again creating a database in the applicationStorageDirectory
00:32that is the directory that's unique to both this application and to the current user
00:37and then creating the person table, if it doesn't already exist.
00:41There is already a createRecord method that inserts literal values into the person table.
00:47Each time it's executed we are creating a new row in the database table.
00:51There is also a function, now named emptyTable that executes a DELETE statement
00:56that clears all of the data from the person table.
00:59Use this function with some care, because it currently doesn't have any confirmation interface to allow the user
01:05to confirm or reject emptying the table once they call the function.
01:09Then there is a function named retreiveData that executes a SELECT statement and saves the data
01:15into a bindable ArrayCollection named acContacts.
01:18The user interface of the application includes a DataGrid to display the current data, this time only three columns
01:25of the data, the firstname, the lastname and email and then a couple of buttons labeled Retrieve Data and Empty Table.
01:33There is also an instance of a custom form component named PersonForm.
01:38This component has already been completed, it's a data entry form with input controls for each
01:43of the non-primary key values in the database table.
01:47When the user clicks a button to save the new data, it creates an instance of a value object class named Person,
01:54passes in the values from the data entry form and then dispatches
01:58that object inside a custom event named PersonEvent.
02:02At the application level, we then listen for that event using the save event handler,
02:07that's a custom event that's a part of the form component and we call the createRecord method.
02:12I will run the application initially and as it starts up, it should create a new empty database table in a new database.
02:20I will click the Save button a few times, one, two and three and then click the Retrieve Data button and you will see
02:28that I'm successfully adding records with literal values.
02:32Then I will click the Empty Table button and I will clear the database table.
02:37Now I'm finally ready to demonstrate the use of parameterized statements.
02:41Move to the createRecord function which currently executes an INSERT statement and adds literal values.
02:48Parameterized statements can be declared in a couple of different ways, but here is the most common syntax.
02:54I will remove the literal value and replace it with a parameter that starts with a colon
02:59and then assigns a parameter name, :firstname and I will do that for each of the values that I'm inserting, :firstname,
03:09:lastname and notice that I'm simply matching the names of the columns, you don't have to do that,
03:16you can use parameters of any name you like, however it does make it a lot easier
03:20if you simply match the parameter names to column names.
03:27So, now I have seven parameters, each named for the column into which their data will be inserted.
03:34Notice that the order of the parameters matches the order of the columns in the first list.
03:39Now, before I execute the statement, I have to assign values to each parameter.
03:44The SQLStatement class has a property named parameters which is a generic ActionScript object.
03:52Each time you create a new parameter, you do so with associative array style syntax.
03:58Put in a pair of brackets and inside the brackets,
04:01put in a string that matches the parameter name that you are replacing with a value.
04:06So, for instance to replace the firstname parameter, the syntax is, stmt.parameters, then open bracket((),
04:16then the name of the parameter as a string, close bracket()) and then assign a value.
04:19Notice that this createRecord function is receiving an argument named person
04:24which us data typed as the Person value object.
04:27So, I can assign the value like this, person.firstname.
04:33Notice that the use of the strongly typed person value object class, makes it a lot easier to type
04:38in the property names, autocomplete those values and make sure that you have typed them correctly.
04:44Now, I'm going to clone this line of code, remember,
04:47you can clone a line of code using either Ctrl+Alt+Down on Windows or Command+Alt+Down on Mac.
04:55I will end up with one line of code for each parameter I need to replace,
04:59then I will replace them one at time, the lastname.
05:08So, I first created the SQL statement with named parameters where I need to plug in the values,
05:14then I set each parameter individually, using the parametered name, prefixed with a colon(:) as a string.
05:21I pass that value into the parameter's object using associative array style syntax and I assign the value.
05:27In this case, from the value object that was passed in as an argument, then just as before I execute the method
05:34and this time after I have called the execute() method, instead of retrieving a result,
05:40I will simply call the existing retrieveData function and that will result in displaying the new data in the DataGrid.
05:46I will save the changes and run the application.
05:50I will start by clicking into the form and typing in some values.
05:56You can type-in whatever values you want into the form, then I will click the Save button to call the createRecord method
06:09and you will see that the data was correctly added to the local database, I will change some values in the form.
06:20Once again, I will click the Save method and you will see that I'm adding new records each time I click.
06:25So that's how we use parameterized SQL statements when working with a local SQL like database.
06:32Just to review the steps one more time, the statement itself is constructed as standard SQL statement.
06:39You plug in parameters using the syntax, colon(:) and then the name of the parameter you want to use.
06:45The best practice is to use a parameter name that matches the column name.
06:49Then for each parameter, you replace the parameter with a value, by setting it's value in the parameter's object
06:55of the SQL statement, then as before you execute the statement and the result is passing
07:02in parameterized SQL statements without having to worry about concatenating all of the strings together yourself.
07:07c
Collapse this transcript
Using transactions
00:01In this video, I'm going to describe how to use transactions with the local database.
00:05For this demonstration, I will use an application named UsingTransactions.mxml,
00:11that's part of the Chapter09 Project.
00:14If you are following with the exercises, you can open the application now.
00:18This version of the application is much the same as in the previous video.
00:22The data is provided by the user through a data entry form.
00:25This version of the application has a few other items that have already been coded.
00:30Down at the bottom of the Script section, there are three empty functions named beginTransaction,
00:35commitTransaction and rollbackTransaction.
00:38And then, there are two additional buttons labeled Commit and Roll Back that call two of the functions.
00:44Go back to the function, beginTransaction.
00:47In order to begin a transaction, you call a method of the SQL connection class called Begin.
00:53It looks like this, sqlConn.begin.
00:57There are some optional arguments that you can pass in,
01:01in particular the responder object can be used, if you are working asynchronously.
01:05In this demonstration though I'm working synchronously and I don't need any options.
01:09So I will simply call the method with no arguments.
01:12I would also like to track from moment to moment, whether a transaction is pending.
01:17I will go back to the top of the script section and I will add a new Bindable variable.
01:28I will name the variable, transactionPending and datatype it as Boolean value
01:35and initialize defaults as the application starts up.
01:38Then I will go back down to the beginTransaction method and I will set the value
01:42of that variable transactionPending to True.
01:46Now I will go back down to the buttons, I would like to set the Commit and Roll Back buttons in enabled states,
01:52so that they can only be clicked when there is a transactionPending.
01:56So I will go to each of the buttons and add an enabled property and I will set the value of the enabled property,
02:02using a binding expression that binds to this new variable.
02:06I will do the same thing in the Roll Back button.
02:09Because I only want the user to be able to click either of these buttons
02:12if in fact, there something to Commit or Roll Back.
02:14Now, we will go to the commitTransaction method, in order to commit a transaction that is to save the results permanently
02:23to the database, you call a method of the SQL connection object named Commit.
02:30As with the begin method, there is an optional responder object.
02:34If you are familiar with item respond of Design Pattern that allows you to setup an object
02:38that has various event handlers you can use this feature, if you are working asynchronously.
02:44Because I'm working synchronously, I will just call the Commit method directly and then I will set the value
02:49of transactionPending, back to a value of False.
02:53In the rollbackTransaction method, I will do the same thing, I will call the connections rollback method.
02:59Once again, I'm working synchronously, so I don't need the responder object and as with commitTransaction method,
03:06I will reset the value of transactionPending to false.
03:12Finally, I will go back to createRecord method and place the cursor above the existing code
03:18and I will call the beginTransaction method.
03:21Now, each time the user tries to add a new row to the database, I will begin the transaction and go ahead
03:27and execute the parameterized Insert statement to add the row to the database table.
03:32You will see when I run the application that the data appears immediately in the table.
03:37But it's only saved permanently, if explicitly commit the transaction,
03:41but then if I rollback the transaction that new data will be removed.
03:45I will save the change and run the application to demonstrate the results.
03:50I will click into the form and type some values, I will click the Save button and watch the Commit
03:58and Roll Back buttons over on the right side of the application,
04:01because the call to the beginTransaction method,
04:04change the value of the transactionPending variable to true, now those button are enabled.
04:10Now I will click the Commit button, you won't see any change in the data, but the data has been saved permanently
04:16to the local database and the two buttons are now disabled.
04:19I will empty the table by clicking the Empty Table button, then I will go back to the form and Save again.
04:26This time I will click the Roll Back button and then click Retrieve Data
04:30and you will see that the database table is empty again.
04:34This is because, when you roll back the transaction, any statements that you executed
04:38after you started the transaction are treated as though, they essentially never happened.
04:43There is a lot more to learn about transaction behavior using the local database.
04:48For more information, check the documentation for different isolation levels and other tricks that you can do,
04:55when Committing or Rolling Back transactions.
Collapse this transcript
Creating an occasionally connected application
00:01In this video, I'm going to describe encode review, a completed application that's designed
00:06to be occasionally connected to the network.
00:08The application is named ContactManager.mxml, and you will find it in the Chapter 09_Begin folder
00:14if you are working along with the exercises.
00:16Now, for those of you, who don't have access to the exercise files, let me precaution you that in this video,
00:21I won't be able to show you all of the code on the video screen because it's quite extensive.
00:26But, I will show you the key methods and describe how the application is running and then if you have access
00:31to the exercise files, either through a premium membership in the online library, or through the DVD version
00:37of this title, you will be able to explore the code more completely.
00:40I will open up the application code to full screen.
00:44This application, as you can see, declares an array collection named acPerson that holds data in memory
00:50and when I run the application and then click the Get Data button, it retrieves data from a network resource.
00:57Now, if you are following along in the exercises, before you try to run the application in this mode,
01:01make sure that you started up WAMP or MAMP, one of the two server bundles that I described how to install
01:07in the first chapter of the video series.
01:10Also make sure that you have imported the database table that comes with the video series exercises
01:15and you have installed the PHP files that are used to retrieve the data from the network.
01:20So, this is what the application looks like when you are connected to the network.
01:24But, this application has been designed so that the user wants to save the data locally,
01:29they can do so through a single click of the button.
01:32And then when they start up the application later on and the network resource isn't available,
01:37they'll be able to instead retrieve the data from their local resource, the local database.
01:41Let's take a look at how that works.
01:43When the application is connected to the network, the user is able to click a button
01:48that calls a method named saveToLocal, which is right down here.
01:53The saveToLocal method sets a Busy Cursor, which means it start an animation of a clock, whose hands are spinning.
01:59And then it calls a method of a class named PersonManager named saveToLocal
02:05and passes the array collection of data that it got from the network.
02:08Let's take a look at that method.
02:10In the saveToLocal method, there's an SQL Statement
02:13that first empties a local database and then it adds an EventListner.
02:18Now, I should mention that all of the code
02:20in the PersonManager class is executing SQL Statements asynchronously.
02:25That's because, when you move the data from the network to the local database, there are thousand records to import,
02:31and that's going to take more than a second.
02:33So, by using asynchronous operations, we allow the user to continue to interact with the application
02:39and we don't freeze any animations such as the Busy Cursor, the animated clock.
02:43After the saveToLocal method, executes the first statement, DELETE FROM person,
02:48it then daisy-chained to the next method, emptyTableHandler.
02:52Because of the addEventListener method, that's called at line 74, within the emptyTableHandler method,
02:58I'm setting a recordNumber variable which has been declared global to the class to zero,
03:03and then calling a method called createRecord.
03:05In the createRecord method, I retrieve the person at the current index of the recordNumber
03:12and save it as a local variable named Person.
03:15Then I create and execute a parameterized insert statement to insert that record's data into the local database.
03:24Before I execute the SQL Statement, I add an EventListener to call a method called nextRecord.
03:29Then I execute the statement and insert that row.
03:32In the nextRecord method, which is called upon that resultEvent occurring,
03:37I first check to see if there are any records left.
03:39If the current record number doesn't match the length - 1 of the NetworkData, then I increment the record number by 1
03:46and then call the createRecord method again.
03:49So, this code loops around for as long as there are items in the array collection
03:53or if I have already inserted all the data, I dispatch an event from this class named SAVE_COMPLETE,
04:00and this constant SAVE_COMPLETE is declared as part of the PersonManager classes of public static constant.
04:06They can be referred to both, within this code and in the main application code.
04:09Finally, back at the Contact Manager.
04:11If you go back to the top of the application to the init method, you will see that in the init method,
04:17there's an addEventListener function being called on the PersonManager object to listen for the SAVE_COMPLETE event
04:23and then dispatch that event to saveCompleteHandler and at that point, I remove the busy cursor
04:29and give the user a message indicating that the data has been copied from the network to the local database.
04:35So, let's run that part of the application.
04:38Wait for the monitor to indicate that the network is available and then I will click the Get Data button.
04:43The data comes back from the network fairly quickly.
04:46Now, I will save the data from the network data to the local data.
04:49I will click the button and once again, we see the clock cursor.
04:54This time because of the explicit call to the cursor, manages setBusyCursor method.
04:58Notice that even though the SQL Statements are still running in the background, I still see animations
05:03and I can still interact with the application.
05:06Now that the data has been copied from the network data source to the local data source,
05:10I get a message saying that the operation is complete.
05:13Okay, so now the data has been saved locally.
05:15Let's take a look at what happens when the user starts up the application and they don't have the network available.
05:21Go back to the init method of the Contact Manager application.
05:26Notice that in the init method, we set an event listener for the statusHandler and once again in the statusHandler,
05:32we're indicating and in the statusHandler method, we determine whether we're going to get our data
05:36from the network or from the local database.
05:39If I'm disconnected from the network, I'll have to get the data from the local database.
05:43So, let's make that happen.
05:44I'll go down to my WAMP icon in the system tray, if you are working on Mac instead go
05:49to the MAMP application and shut down services.
05:53And if you are working on Windows, click on the System Tray icon, and select Stop All Services.
06:00Wait a moment for the services to shut down then run the application again.
06:04This time as the application starts up, the monitor determines that the network is not available.
06:09I'll click the Get Data button again but this time the data is going to come from the local database and notice
06:15that it appears much more quickly than it did, when it came from the network.
06:19Let's take a look and see how that's happening.
06:22Go to the Contact Manager application code again and take a look at the getData method.
06:26Within the getData method, there is a call to the getAll function of the PersonManager class.
06:32They get all function, executes a Select statement, retrieves the data
06:36and then listens for a result event internally.
06:39When that event happens, a getAllResultHandler method is called internal to the class and in that method,
06:45the data is transformed from an array of objects and in that method, the data is transformed from the array
06:51of generic objects that's returned from the local database into an array collection of strongly typed value objects.
06:58Finally, at lines 158 to 160, an instance of a class called LocalDataEvent is dispatched.
07:06The LocalDataEvent custom class is designed to hold an instance of the ArrayCollection as a data object.
07:12Back at the application level, we are listening for that event to occur and when it occurs,
07:18we call a method called localResultHandler as a result of an event listener, here is the method
07:23and in the method we remove the Busy Cursor and save the events data object
07:28to the global ArrayCollection and it's displayed in the application.
07:32So, let's run all three features one at a time.
07:35I'll restart WAMP, wait a moment for the services to start up, then go back and run the application again.
07:43As soon as I get a notice that the network is available,
07:45I'll click the Get Data button and retrieve the data from the network.
07:49Then I'll click the Save to Local button and it will take four or five seconds at least to save to the local database
07:55and how fast it happens really is depended on the processor speed of the local system.
07:59Once the Save to Local operation is complete, I'll see this notification that the date has been saved locally.
08:05Now keeping the application open, I'll clear the data, I'll go back to my WAMP interface.
08:11If you're working on Mac, go to MAMP, I'll stop all the services and wait a moment for the application to detect,
08:18as you'll see in the status bar that now we are working with the local data source.
08:22I'll click the Get Data button and the data is retrieved from the local database.
08:26So this is an occasionally connected application.
08:28There is clearly a lot more that you could do with this, including being able to create new data or modify data
08:34on the client and then when you are reconnected, automatically synchronize it back to the network database.
08:39That's all work that you can do, but it takes a bit of coding,
08:42but this finished application should give you a model of how you can integrate data that starts off on the network
08:48and then is saved locally, so that the user can still use the data even when they are not connected to the network.
Collapse this transcript
10. Encrypting Local Data
Understanding the EncryptedLocalStore class
00:00In this chapter of the video series, I'm going to describe how to encrypt data and store it locally,
00:06so that is only available to AIR applications and only available when the user
00:10who created the data and stored it is logging on that system.
00:13This is a capability that's built into the Adobe Integrated Runtime.
00:17Each AIR application has the ability to save a small amount of data that's encrypted and stored locally.
00:23The data that you store is unique to that application and to the current user.
00:28This feature leverages capabilities of the local operating system, an API called DPAPI on Windows and Keychain
00:35on the Mac, so that the data is stored in the best encryption possible for that particular operating system.
00:41Regardless of which operating system the application is going to run on though, you program the tasks of setting
00:46and retrieving data using exactly the same code.
00:49The encrypted local store function is only available to application code that's in the application sandbox.
00:55For example, if you were to run an AIR application that use JavaScript code and that JavaScript code was downloaded
01:01from the web at runtime, that code would not have access to this capability.
01:06The EncryptedLocalStore class is an ActionScript class that's the part of the AIR Libraries and is available
01:11to you always when you are working on AIR applications in Flex.
01:14This class has methods to set and retrieve data from the EncryptedLocalStore.
01:19In order to add data, it must first be stored as byte array.
01:23In order to translate a simple string value into a byte array, follow these steps:
01:27Instantiate a ByteArray object using the ByteArray classes no arguments constructor method,
01:32then call the object writeUTFBytes method and pass in the string value,
01:36the ByteArray will now contain the string value in the proper form.
01:40Next, to save the data locally in an encrypted format call the EncryptedLocalStore static method setItem,
01:47pass in a key value in the first argument.
01:50The key is a string value with which you are associating your data, then pass in the ByteArray.
01:55The data will now be stored and encrypted locally.
01:59Later when you want to retrieve the data, once again use EncryptedLocalStore class, call it static getItem method
02:06and once again pass in that same key value.
02:08You will get back a ByteArray, just like the one that you passed in earlier and then you will translate it
02:13to a simple String using the ByteArray object's readUTFbytes method.
02:18The numeric value that you pass into this method is the number of bytes in the array
02:22which you can get from its length property.
02:25So the syntax you see on the screen, readUTFbytes passing in storeValue.length means take the bytes,
02:31takes this many bytes and translate those to a string.
02:35So in the next couple of videos, I'll show how to do this in an actual application.
02:40Taking data and storing it locally using the EncryptedLocalStore class
02:44and then retrieving the data in a different application session.
Collapse this transcript
Inserting data into the encrypted local store
00:00In this video, I'm going to describe how to add data to the encrypted local store.
00:05If you are following along with the exercises, you can import the Flex Project
00:08that I'll be doing these demonstrations in.
00:10From the Flex Builder Menu select File, Import, Flex Project, click the Browse button next to Archive File,
00:19navigate to the Chapter10 folder under the exercises area and then select Chapter10BeginProject.zip,
00:27finish importing the Project, then go to the Flex Navigator View and open the Project Source Folder
00:34and open an application named SetEncrypted.mxml.
00:39This application has a simple data entry form wrapped in a panel.
00:43I'll run the application so we can see what it looks like, it asks the user to type in a username and a password
00:49and then has buttons labeled Save Credentials and Load Credentials.
00:52These buttons respectively call functions named setCredentials and getCredentials, that are already created.
00:59Place the cursor in the setCredentials method and follow these steps.
01:02First create a ByteArray, declare a local variable named bytes data typed as a ByteArray
01:09and instantiate it using the ByteArray class's, no arguments constructor method.
01:14Now, you'll be taking the value that the user has typed in, in the text input control with an id of usernameInput.
01:21Go back to the code and call this method, bytes.writeUTFBytes and pass in the value that you want
01:30to place into the ByteArray, usernameInput.text.
01:34Now you are ready to save the user's information to the EncryptedLocalStore.
01:38Call the EncryptedLocalStore class's static setItem method, pass in a name which is the key.
01:46I use a key of username and then I'll pass in the bytes.
01:50Then I'll use the Alert class, I'll type in the word Alert then press Ctrl+Space and select the class
01:56to cause it's import statement to be added.
01:59Then I'll call the show() method and I'll display a message in the pop-up window that says Data Saved
02:04and I'll put a title on the pop-up window of Encrypted Local Store.
02:12I'll save the changes and run the application.
02:15I'll click into the username text input control and type in my name and then I'll click the Save Credentials button
02:25and I'll get the message that the Data has been Saved.
02:27Now there is no way to verify that, that data has been saved other than by retrieving it from the same application.
02:33So, in the next video, I'll show you how to retrieve that same data by once again using the EncryptedLocalStore class.
Collapse this transcript
Retrieving data from the encrypted local store
00:00In this video, I'm going to describe how to retrieve encrypted data from the EncryptedLocalStore.
00:05For this demonstration I'll use an application named Getcrypted.mxml in the Chapter10BeginProject.
00:12If you are following along with the exercises, open the application now.
00:16This is the same application that I created in the previous video
00:19that currently can save encrypted data to the local store.
00:23Place the cursor in the getCredentials method, the fist step in retrieving data is to declare a ByteArray.
00:30We can reuse the variable named bytes because both variables are declared local to the functions.
00:35I'll data type it as a ByteArray and then I'll fill in the ByteArray
00:39by calling the EncryptedLocalStore's, static method, getItem.
00:43The I'll pass in the same key, that I used in setting the item previously, username.
00:49Next, I'll translate the ByteArray to a string value var username.String typed as a string = bytes.readUTFBytes
01:03and as I described earlier, you pass in the length or the number of bytes in the ByteArray
01:08by using the ByteArray's length property.
01:13So, now the encrypted value has been decrypted and saved back to a simple string.
01:19I'll now save that to the usernameInput control and I now I'll test the application.
01:32I'll run the application, I'll click into the username text input control
01:37and type in a value davidG and click save credentials.
01:42I get a message that the data has been saved, I'll click OK and then manually clear out the username
01:50and then click the loadCredentials() method and you'll see that the data is retrieved.
01:54Now the data is actually stored persistently on the local system.
01:58So, now I'll be able to close the application completely and then reopen it again and this time
02:04when the application opens I immediately click the Load Credentials button and you'll see
02:08that the data is still there in the local system.
02:11So this is sort of like cookies and also very similar to the local shared object architecture,
02:16that's been available in the Flash Player for a long time.
02:19But unlike these architectures, it involves strong encryption and that means
02:23that you can safely safe these kinds of values on the local system and you'll know
02:27that you are using the strongest possible encryption that's available with the current hosting operating system.
Collapse this transcript
11. Invoking an AIR Application
Using command-line arguments with AIR
00:00In this chapter of the video series, I'm going to describe various aspects working
00:04with AIR applications during the start up phase of running the application.
00:09I'll be talking about using Command Line Arguments, detecting the application directory upon startup,
00:15launching the application from the web and other advanced approaches to working with the start up phase.
00:21For all of the demonstrations in this chapter, I'll be using a Flex project from the exercises area.
00:27If you are following along in the exercises, you can import the project.
00:31From the Flex Builder menu select File, Import, Flex Project.
00:38Click the browse button next to Archive File, go to the Chapter11 folder
00:42in the exercises area and select Chapter11BeginProject.zip.
00:49Import the project in the Flex Builder, then go to the Flex Navigator View, open the project and open its source folder.
00:57Then open the application CommandLineArgs.mxml.
01:03This application has a simple text area control with an ID OWOUT and a font size setting that's applied
01:09to the global selector, setting everything to a font of 12 pixels.
01:14This will allow everything to be able to little bit more visible on the screen.
01:17Every time you start an application, no matter how it's started, the application dispatches an event named Invoke.
01:25This event dispatches an event object, data typed as something called Invoke Event.
01:30The Invoke Event class has access to information, such as Command Line Arguments
01:36and the current directory in which the application is starting.
01:39To get started, go to the WindowedApplication tag, go to the end of the tag and add a line feed at the end
01:47of the tag before the closing greater than symbol.
01:50Then add an invoke event handler.
01:54When this event is dispatched, I'll call an event handler function named invokeHandler that I'll need
01:59to create, and I'll pass the event object.
02:04Now go to the Script section.
02:07Declare private function named invokeHandler; its event argument will be data typed as InvokeEvent.
02:15Return void and put in a pair of braces.
02:20Then place a break point on the last line of the function, save the application
02:25and then run the application in debug mode.
02:27As the application starts up, the invoke event is dispatched immediately.
02:32This gives you an opportunity to handle the event and see what's in it.
02:37If you're prompted to open the flex debugging prospective as I am,
02:40click Yes and then within the Flex debugging perspective, go to the Variables view.
02:46Double click its tab to expand it to full screen and then open up the event object to inspect its values.
02:54Notice that there are two properties of this event object that can be useful.
02:58The Arguments property is in Array and it will contain any values
03:02that were passed to the application on the command line.
03:05There is also a property named currentDirectory.
03:09So, these are the two properties we have available.
03:11Here is what we are going to do with them.
03:14Double click the Variables tab to restore to its original size and then terminate the Debugging session
03:19and then go back to the Flex Development Perspective.
03:23When the application starts up, you'll add code into the invokeHandler function
03:29to output the current command line arguments as a string.
03:33Also we'll use the current directory property which is returned as a File object and I'll put its native path.
03:40Within the invokeHandler method at this code out.text = Arguments, then add a + operator to concatenate
03:55and add this syntax, event.arguments.toString.
04:01This will take the array of arguments and output it as a comment to limited list.
04:06Also add a line feed like this, out.text += n, that's the escaped character for a line feed
04:17and then on the next line out.text += Current Directory as a literal string and then concatenate
04:28to that event.currentDirectory.nativePath, again remembering
04:34that the current directory properties returns as a file object.
04:38Save your changes and run the application, this time in normal mode.
04:42As the application starts up you should see that the Arguments value is blank,
04:48whereas the Current Directories is reported as the Flex Builder 3 installation directory.
04:53Now to really see this behavior, we're going to need to package
04:57and install the application and then run it from the Command Line.
05:01So, close the application and then export a released version of the application.
05:07Go to the menu and select File, Export, Release Built.
05:14Select the CommandLineArgs.mxml application from the Chapter11BeginProject,
05:21click Next and in the digital signature screen either create a new certificate
05:26or use one that you've already created previously.
05:29I'm using the certificate that I created in one of the early exercises in the video series and the password
05:35that I have put in was simply the word password.
05:37I'll click Next, and then Finish and that will create my AIR file so that I can install the application.
05:47Now go to the Flex Navigator View and open CommandLineArgs.air
05:52which you can do by double clicking on it.
05:55Once the application installer opens up click Install and then accept all of the options and click Continue.
06:02When the application starts up, you should see the current directory information again
06:07but once again No Command Line Arguments.
06:10Okay, now we're ready to see what happens when you do pass in command line arguments.
06:15If you are working on Windows, go to the Start Menu and if you are Windows Vista just type in cmd.
06:21If you are working on Windows XP, click Run and then type cmd into the dialog that appears
06:29and that will take to a CommandLine Window.
06:31If you are working on the Mac, open the terminal application which you'll find in applicationsutilities.
06:39Now if you are working on Windows, switch to the folder in which the application was installed.
06:44Type cdProgram Files and working on either XP or Vista you should be able to type in the first few characters
06:53of the directory and then press Tab to fill it in.
06:56Then put in a back slash and then the first few characters of the application, CommandLineArgs, and then Tab again.
07:05Press Enter and then type in Dir and Enter and you should see a listing of the files that were installed.
07:13If you are working on Mac, you don't need to change the directory, instead as you type in the name
07:19of the application that you want to run, start with the slash character,
07:23then applications, then CommandLineArgs.app.
07:26I'll get into the details of that in a moment for the Mac.
07:29Here is what it looks like on Windows though.
07:32Now I'm going to type in the name of the application, CommandLineArgs.exe,
07:37once again I typed the first few characters and press Tab and then Windows completed the file name for me.
07:43Now I'll put in a space and then a few command line arguments, arg1 arg2 and arg3.
07:51I'll press Enter to run the application and you'll see that, now the arguments are reported as a comment to limited list
07:59and once again the current directory is reported as the directory from which I launched the application.
08:05This time I'll close the application and change back to the root folder of the C drive.
08:11Now to run the application, I'll use the entire path, Program FilesCommandLineArgsCommandLineArgs.exe.
08:22Once again I'll pass in a few arguments, run the application and now notice
08:28that the current directory is the root folder from which I launched.
08:32So, the current directory that you get in the invoke event object is not the same thing as the application directory.
08:38Instead, it's the directory that was considered the current directory at the time that you started up.
08:45Now if you are working on Mac OS X, here is the path that you'll use.
08:49From within terminal, type in Applications, then CommandLineArgs.app just like in the command window
09:00in Windows, you can type in the first few characters of anything
09:04and then press Tab and terminal will complete it for you.
09:08But be aware that in terminal everything is case sensitive, so you have to type in the names
09:12of files using the correct case, upper case where it's needed.
09:16So it's applicationsCommandLineArgs.appContentMac OS and then once again CommandLineArgs.
09:29After that you can once again pass in argument values and you will be able
09:37to see the arguments displayed in the application as it starts up.
Collapse this transcript
Opening files with AIR
00:00In this video I'm going to describe how to use the Invoke event that's dispatched whenever you start
00:04up an AIR application, to capture information from the command line
00:08and determine what file you want to open as the application starts up.
00:12For this demonstration, I'll use an application named OpeningFiles.mxml from the Chapter11BeginProject.
00:19If you are following along with the exercises, open the file now.
00:23In this application, there is an Invoke event listener already created in the WindowedApplication tag
00:28and an event listener function named invokeHandler that handles the event.
00:33In some applications you want the user to be able to start the application from the command line and pass in the name
00:38of a file that they want to open immediately upon start up.
00:42As I showed you in the previous video, the InvokeEvent object contains information about both the arguments
00:48and the current directories that the user is starting from.
00:52You can use these two values in combination to figure out what file the user wants to open and then use the File
00:58and FileStream classes to open and read the file into the application's memory.
01:03Place the cursor into the invokeHandler function, the first question you need
01:07to ask is whether any arguments were passed in at all.
01:10So, put in an if conditional clause that asks this question, if (event.arguments.length) is greater than or equal to 1.
01:19If the user hasn't passed any arguments in, then you won't be able to open any files.
01:25Now assuming that they have passed in at least one argument, we're going to assume that the first argument they pass
01:30in is the name and location of a file relative to the current directory from which they started.
01:36Declare a variable link filename, data typed as a String and get it's value from event.arguments (0) as String.
01:48So, we're taking this value as a string and saving it into the variable filename.
01:52Next create a File object, I'll name my File object simply f and again data typed as a File and get the path
02:00of this file object using the event object's current directory property as follows,
02:06event.currentDirectory.resolvePath and then pass in the filename variable.
02:13Since the user will reference the file relative to their current directory from which they are starting up,
02:18this should give you the accurate location of the file they are asking you to open.
02:23Now ask whether the file actually exists, put in a conditional clause
02:27and use this expression, f.exists and then a pair of braces.
02:32If the file exists, you'll now open it and you are going to assume that it's a next file for this demonstration
02:39but of course in any particular application you'll read the file according to whatever format you're expecting.
02:45To read the contents of the file into memory, declare a variable named fs data typed as a FileStream object
02:52and instantiate it using the FileStream class's no arguments constructor.
02:58Now call the FileStream object's open method and pass in the File object and a FileMode of Read.
03:07Next create a variable named str data typed as a String,
03:10get it's value from the readUTFBytes function of the FileStream object like this.
03:17Call the readUTFBytes function and then pass in the number of bytes that you want
03:21to read using the expression fs.bytesAvailable.
03:26Now close the FileStream by calling the close method and then output the string value that you read from the file
03:32like this, out which is the id of the textarea control at the bottom of the application out.text=str.
03:41So, that's the basic code.
03:42You check to see whether you have got the argument you were expecting, if so you create a File object pointing
03:48to the file that the user asked you to open.
03:50You check to make sure the file exists and then you create a FileStream object and use that along with the file object
03:57to open the file and read it's contents into memory.
03:59Now if the user types in the name of the file that doesn't exist, you want to get them some feedback.
04:04So, put in an else clause that's a part of the nested if condition and in there use an Alert object,
04:11double make sure that Flex Builder adds an import statement for the Alert class, then call the show() method
04:17and then use this code, "File" + f.name + "not found" and then pass in a title of Error.
04:28Save your changes and try running the application.
04:31Now when you run the application from Flex Builder, you aren't passing in any arguments,
04:35so you won't see any feedback from the application.
04:38To see the feedback from the application, do this.
04:41Export the application as a Release Build.
04:44From the Menu select File, Export, Release Build, Select the OpeningFiles.mxml application and set the file
04:53that you are exporting as OpeningFiles.air.
04:56Click through to the digital signature screen and fill in any information you need for your self sign certificate
05:02and then click finish to package the application.
05:05You should now have a file named OpeningFiles.air, in your Flex Navigator View.
05:10Open the AIR file, you can do so by double clicking and then install the application to your system.
05:17As the application starts up once again, no command line arguments are being passed in, so you won't see any result.
05:23Close the application and then go to a Command window.
05:27Switch to the application directory, on windows this will be ProgramsOpeningFiles.
05:34Now on Windows, you'll notice that there is an assets folder with two files, one named ATextfile.txt
05:42and the other named My.customAIRFileType.
05:45So, now try opening the application like this, OpeningFiles.exe
05:49and again the syntax will be different on the Mac and then assetsATextFile.txt.
05:56Working on Windows make sure you use a backslash between asset and ATextFile.txt.
06:02Run the application and you will see that the content of the text file is opened
06:07and displayed in the application upon startup.
06:09Now again if you are working on Mac OS X, the installation architecture is somewhat different.
06:14Everything is packaged within an application package.
06:17So to see this behavior, you might want to instead copy the contents of the assets folder over to an area
06:23of your Mac disk, then go to terminal and run the application from the command line,
06:28opening files directly from the disk and not going through the application package to get to the text files.
06:33Regardless as long as you pass in a correct file name, you should see that the content is displayed in the application.
06:40Now watch what happens if you pass in a non existent file name.
06:44I'll try the same application again, but I'll change the name of the file to NoSuchFile.txt
06:51and as the application starts up, it displays the text file, File NoSuchFile.txt not found.
06:57So the application is correctly determining whether the file that's been requested exists or not and if it exists,
07:03it's opening it and reading it into memory and if it doesn't exist it's reporting the error to the user.
Collapse this transcript
Using custom file types
00:00In this video, I'm going to describe how to create your own custom file types and associate them with your application,
00:06so that, when the user clicks on a file, whose file extension is associated with your application,
00:12it results in opening the application directly and loading the file.
00:16The code for this application will be exactly the same as in the previous example.
00:20I will be using an application named CustomFileTypes.mxml.
00:24If you're following along with the exercises, you can open this file now
00:28and you will see that once again it uses an invoke event.
00:31It calls the invoke handler method and then checks for the file that's provided in the arguments.
00:36It then opens the file for reading with the file stream object and displays its contents on the screen.
00:42You associate Air applications with custom file tapes through the application descriptor file.
00:47Open the file CustomFileTypes-app.xml.
00:53Scroll down to the bottom of the file and locate the section labeled fileTypes.
00:58In a default application descriptive file, all of this content is commented out.
01:05In order to set up custom file types, remove the comments from the following elements.
01:10First, locate the start and end file types element and remove the comment tokens from there.
01:16Go to the start tag first and remove the comments from around that tag.
01:24Then, go to the matching end tag and do the same.
01:28Also, remove the comments from around the fileType element.
01:34Once again, you'll find comment tokens around both, the beginning and the ending tag.
01:43Now, for each file type that you define, there are a couple of required elements
01:46and then some optional elements that you can also use.
01:49We will be working with a custom file type with a file extension of customAirFileType.
01:55There's an example of this type of file in the assets folder and if you open this file up with a simple text editor,
02:01you'll see that it's really just a text file with some basic text.
02:05Go back to the application descriptor.
02:12Remove the comments from around the name element.
02:15The name of the file type can be anything you want, but it's commonly in dot format.
02:20So, I'll use this syntax; Custom.Air.File.Type.
02:27Now, put in the extension that you want to register.
02:31On both, Windows and Mac OS X, any file with this file extension, when opened,
02:36will result in opening the application itself.
02:39Notice, we're using the file extension CustomAirFileType.
02:43So, put in that extension between the extension tags and don't include a dot character.
02:48Those are all the required settings.
02:50You don't need a description and you don't need a MIME type, if you're just going to be opening files from the desktop.
02:56Save your changes and now, create a release build.
02:59From the Menu, select File, Export, Release Build.
03:04Select the application, CustomFileTypes.mxml and export to a file named CustomFileTypes.air.
03:12If you need to set up your digital security certificate, do so and then,
03:17export the Release Build by clicking the Finish button.
03:21Next, install the application to the operating system.
03:25You should now have a file called CustomFileTypes.air.
03:28Open that file from the Flex Navigator view.
03:31You can do this by double clicking on it.
03:33Click the Install button and click Continue and as the application starts up,
03:38you'll see that the Output region is blank, because we started it up without any arguments.
03:44Close the application and return to the Flex navigator view.
03:47Now, whenever you select a file that has the appropriate file extension such as the file My.customAIRFileType,
03:55and open that file say by double clicking it,
03:57it's the same thing as opening the application and passing in a command line argument.
04:02So, I'll locate the file My.customAIRFileType and I will open it by double clicking.
04:07Now, it may open in Flex Builder as you see here, but to open it with the application, right click on the file
04:13or Control click on the Mac and select Open with System Editor.
04:19That should result in opening the installed application and opening the file and displaying its contents in the screen.
04:25So, that's how we set up custom file types that are associated with their applications.
04:30The work is all done in the application descriptor file.
04:33This association can only be tested once the application has actually been installed on your operating system.
04:39You have a required name and a required extension and then, other optional values such as, the description,
04:45the MIME type and if you want, you can also associate graphical icons with these file types, so that,
04:51the files are displayed on the operating system and displayed with these graphic icons associated.
Collapse this transcript
12. Updating an AIR Application
Setting application version numbers
00:00In this chapter of the video series, I'm going to describe how to manage automatic updates for applications
00:06that are already installed on your system.
00:07When you build software applications and then want
00:10to upgrade the applications, there are a number of steps involved.
00:13First of all, in the application descriptor file, you control the version number.
00:17Then, at run time, you have to download the application installer from the website; then, compare the new version
00:23to the old version that's running on the system, and then finally, automatically do the update.
00:27Throughout the demonstrations in this chapter, I will be using a Flex project, that's a part of the Exercises area.
00:33If you are following along with the Exercises,
00:35you can import this project using the Flex Builder Menu selection; File, Import, Flex Project.
00:43Click the Browse button next to archive file, navigate to the chapter12 folder of the Exercises area
00:49and select the Flex Project archive file chapter12BeginProject.zip.
00:55Import the file, then, go to the Flex Navigator view and open the project and then open the source folder.
01:02You'll find that there's one very simple application named MyAIRApplication.mxml.
01:09Open the application and take a look at the code.
01:13There's an import for the Alert class, three empty functions named downloadUpdater, completeHandler and closeHandler.
01:20The two event handler functions use event objects, a label and a button control
01:26and the button control's click event calls the downloadUpdater method.
01:30Next, open up the application descriptor file.
01:35MyAIRApplication-app.xml.
01:38This is a standard default Air Application descriptor file with one minor change.
01:43The application version which is at line 27 has its version number set to a value of 1.0.
01:50I'm using a pure numeric value for the version numbers, because this will help me demonstrate later on,
01:55how you compare version numbers from an old version to a new version.
01:59Finally, go back to the application and run it and you'll see that it displays a very simple background
02:05with a label and the button labeled Download updater.
02:09Close the application and now I'm going to package the Application Installer.
02:13From the Flex Builder Menu, select File, Export, Release Build.
02:20Select the application MyAIRApplication.mxml from the chapter12Begin Project and change the name
02:26of the default air file from MyAIRApplication to MyAIRApplicationV1.air.
02:33This will help us distinguish between the version1 installer and the version 2 installer, which we haven't created yet.
02:40Click through the rest of the screens.
02:42If you need to set up a digital certificate, you can do it from this Digital Signature screen.
02:47I'll accept my existing certificate and then click Finish to package the application.
02:53In your Flex Navigator view, you should now have an installer package; MyAIRApplicationV1.air.
02:59Double click it to run it and then install the application,
03:03following all of the prompts and accepting all of the defaults.
03:07After the application has been installed, it should open on your screen.
03:11Close the application and then return to the application code.
03:16Now, we're going to create a version2 of the application.
03:21Save this file with a new name.
03:23File, Save As, and name this MyAIRApplicationV2.mxml.
03:30Make a couple of changes to the visual output of the application.
03:35Change the background color from aqua to red.
03:39Go down to the label component and change its version number to Version 2.0.
03:44Save those changes.
03:46Now, go back to MyAIRApplication-app.xml.
03:50Open that and save that as MyAIRApplicationV2-app.xml.
03:57The one thing you won't change here, is the identifier.
04:00In order to do an automatic update, the two versions of the application must have the same ID.
04:06So, even this one is named MyAIRApplicationV2.mxml, we leave the ID alone.
04:15But, we will change the version number, from version1 to version2.
04:20Save the changes to the application descriptor.
04:23Then, go back to the application MyAIRApplicationV2.mxml and run the application.
04:30When this version of the application opens on the screen, you will see that it now has a red background,
04:36so we can identify it easily and a label of version2.
04:41Close the application, and now, package the application.
04:46Select File, Export, Release Build.
04:52Select MyAIRApplicationV2.mxml and change the export file name to MyAIRApplicationV2.air.
05:02Click through the rest of the screens, selecting the digital certificate
05:06and including the required files and then click Finish.
05:10See, you now should have two copies of the application; MyAIRApplicationV1.air and MyAIRapplicationV2.air.
05:18They are both using the same application ID, so, if I tried to run the air application for version2 right now,
05:24the air installer will detect that the version numbers have changed from version 1, the installed version to version 2.
05:31Now, you could replace the existing application this way, but we're more interested in this chapter in seeing how
05:37to handle this update automatically, using ActionScript code to download the new installer
05:42and then inspect the version numbers and finally, automatically do the update.
05:47So, cancel this installation process and in the next video, I will show you how to take the version 2 air file,
05:53copy it to your website and then, how to download the air file,
05:57using ActionScript code in your version 1 application.
Collapse this transcript
Retrieving an installation package from a website
00:00Before you can automatically update an AIR application, you have to download the installer file from a website.
00:06You can't run the installer directly from the web, instead it has to be stored locally.
00:10So in this video I'm going to show you how to set up your installer on the website and then how
00:15to write the ActionScript code to download it and save it to the local disk.
00:18Then in later videos, I will show you how to compare the version numbers between the currently installed version
00:23and the installer that you just downloaded and then how to execute the update.
00:28First of all, in this chapter, unlike many of the others, you can't really step into each exercise individually,
00:34you have to go through the whole chapter one video at a time.
00:36So if you didn't go through video number one in this chapter, go back and run through those exercises first,
00:42so that you have two AIR installers, MyAIRApplicationV1.air and MyAIRApplicationV2.air.
00:49You should have installed version 1 on your system already.
00:52Now the next step you are going to follow is copying the version 2 AIR file to a location on a website.
00:58For this purpose I will be using WAMP, the Windows-based application server bundle,
01:03that includes Apache, MySQL, and PHP.
01:06If you are working on Mac OS X, you can use MAMP instead.
01:10Copy the AIR installer for version 2 to your clipboard.
01:14Right click on the installer, MyAIRApplicationV2.air, or Ctrl+click with the Mac, and select Copy.
01:21Now, navigate to a folder under your web server root.
01:25I will be using this folder, c:wampwww, that's the document root if you are using WAMP with its default installation,
01:37and under there I will go to the AIRFlex folder that was installed earlier in this video series.
01:42Now, I will paste the file into that folder.
01:45If you are working with MAMP on Mac OS X, the document root under MAMP is the, Applications/MAMP/htdocs folder.
01:55You can also go to the AIRFlex folder under there if you placed it there,
01:59and then copy your AIR installer into that location.
02:02Now your version 2 installer is ready to download.
02:06Close whatever windows explore or find a windows who might have open and return to Flex Builder
02:11and then open the application file, MyAIRApplication.mxml.
02:15This is the version 1 application we are working in.
02:18The first step in downloading the installer from a website is to declare a few variables.
02:23First declare a variable named urlString, datatyped as a String.
02:29This will be the location of the AIR installer as an absolute URL.
02:33Put in this URL, http://localhost/AIRFlex/MyAIRApplicationV2.air.
02:43Next declare a variable datatyped as a URL request.
02:51I will name it urlReq, datatyped as URLRequest
02:56and instantiate this object using the URLRequest class's constructor method and wrap it around the urlString.
03:07You now have a URLRequest object that points to the location of the your version 2 installer.
03:12Next declare a variable named urlStream, datatyped as the URLStream class.
03:21This class is able to download binary files from a website and then save them to local data.
03:26Instantiate this object using the URLStream class's no arguments constructor method.
03:33When the URLStream class downloads the binary file, it will be saved as a ByteArray.
03:38Declare a variable named fileData, datatyped as a ByteArray
03:42and then instantiate it using the ByteArray class's no arguments constructor method.
03:49So those were all the variables we need.
03:52The urlString described in the location as a String, the URLRequest wrapped around the urlString.
03:57The URLStream which is going to do the downloading and the ByteArray
04:01which will receive the binary file and store it in memory.
04:04Now go to the downloadUpdater function.
04:07Add the following code, that first set up an event listener for a complete effect.
04:12When the download is complete you will get this event and be able to react.
04:17Call this code, urlStream.addEventListener, listen for the Event.COMPLETE event,
04:26and then call the completeHandler method when the event occurs.
04:29Now you are ready to download the file using this code, urlStream.load, and pass in the URLRequest object urlReq.
04:41This download will happen asynchronously and when the download is complete, the complete event will be dispatched
04:47and you will be ready handle and save the file to disk.
04:51Place the cursor inside the completeHandler function.
04:56The first task is to take the results of the URLStream class's load method
05:00and save the results to the predeclared ByteArray.
05:03I will use this code, urlStream.readBytes and then I will pass in the following values.
05:12First the ByteArray that I want to write to, fileData, then at beginning position, zero, and then the number of bytes
05:20that I want to download, urlStream.bytesAvailable.
05:31Now I will take the ByteArray and write its contents to a file.
05:36First I will create a file variable named f, datatyped as a File, and I will indicate where I want to write the file to.
05:43I'm going to put it on my desktop directory, so I can see it easily.
05:47I will call the desktopDirectory file's resolvePath property and pass in the name
05:52of the file I want to create, MyAIRApplicationV2.air.
06:00Now I will create a FileStream.
06:02I will name it, fs, datatyped as a FileStream object
06:06and I will instantiate it using the class's no arguments constructor method.
06:13Next I will add an event listener.
06:15I'm going to be opening this file asynchronously,
06:17so I want to be able to react whenever the file is being downloaded to the desktop.
06:21So I will call it fs.addEventListener and I will listen for a CLOSE event
06:26and whenever the FileStream has been closed, I will call a method named closeHandler.
06:32Now I will open the file that I want to write to, using this code, fs.openAsync, I will pass in the file object,
06:41simply named f here, and then use the constant FileMode.WRITE,
06:47to indicate that I want to write to this new file.
06:50Now I'll call the FileStream's writeBytes method.
06:54I will pass in the source ByteArray named fileData, a beginning offset of zero, and then the number of bytes
07:02that are in the ByteArray using the syntax, fileData.length.
07:10When the write operation is done, I will close the FileStream like this, fs.close().
07:17So that's the code you need for taking the binary content that's been downloaded using the URLStream,
07:23first reading it into a ByteArray and then from there, writing it to disk.
07:28Finally, go to the closeHandler method and add a bit of code to let the user know that the file has been written to disk.
07:36I will call this method Alert.show, and I will pass in two literal strings,
07:41"The AIR file has been saved locally", and then a title of "Download complete".
07:49I will save the changes and run the application, and make sure that you are running WAMP or MAMP.
07:56In this case, I'm looking at my system tray in the lower right hand corner
08:00and seeing that the WAMP server is ready to use.
08:03I will make sure that it's online and ready and you can tell from the system tray indicator
08:08by the little needle that's all the way over to the right.
08:10Then I will go back to the application and click the Download Updater button,
08:15and after a moment I get the message that the AIR file has been saved locally.
08:19I will close the application and take a look at the desktop and you will see that the application installer,
08:26MyAIRApplicationV2, has been saved successfully to the desktop.
08:30Now in the next video, I will show you how to compare the version number in this installer
08:34to the version that's already installed and then decide intelligently whether you want
08:39to follow through and do an update.
Collapse this transcript
Comparing application version numbers
00:00In this video, I'm going to describe how to detect the current version number
00:04of the application that's already installed on your system.
00:07Before you execute an automatic update you always want to compare the currentVersion number of the application
00:12to the version number you are expecting to install.
00:15It's important to note that the application must already know the version number of the target application installer
00:21and then it can detect its own version number that is the currentVersion number dynamically.
00:25For this demonstration I will use the application CompareVersions.mxml that you will find
00:30in the Chapter12BeginFolder if you are following along with the Exercises.
00:36This is the same application that I created in the previous video, but it now has a new function named compareVersions
00:42and a button with a label of compareVersions that calls that function.
00:45Here are the steps for comparing the version of the currently running application.
00:49Click into the CompareVersions function and then put in this code
00:53to clear a variable named descriptor, datatyped as an XML object.
00:59Remember that the application descriptor is an XML file and you can read this into memory using the following syntax;
01:06NativeApplication.nativeApplication.applicationDescriptor.
01:14This expression returns the actual XML object that is the application descriptor file.
01:20Now in order to read the application descriptor you need a namespace,
01:24you get this namespace using the syntax var ns:Namespace=Descriptor.namespce.
01:34The namespace function can handle a namespace prefix, but if you look back at an application descriptor file,
01:44what you see is that it does include a namespace in the application tag, but it doesn't use a namespace prefix,
01:50so this is what's called in XML the default namespace and this is what we are referring to,
01:56when we declare the namespace object using this code.
01:59Now to clear a variable named current version datatyped as a number and you will extract the version
02:07from the XML file and then cast it as a number.
02:10I can do it in this case because the version numbering that I'm using are purely numeric values 1.0, 2.0 and so on.
02:18So extract the value like this, start off with a casting expression of number parenthesis,
02:26then an E4X expression of descriptor.ns::version.
02:30The colon, colon is namespace syntax in E4X, we are saying start with the default namespace
02:40and then get the version element and its text note, return that value and cast it as a numeric value.
02:47Finally set a variable named newVersion, once again type as a number and set it to a literal value of two.
02:55Now in this case I'm setting the application version number right here in the code,
02:59but you could just as easily download an XML file for instance from the website
03:03to determine what version number you are looking for.
03:07Now you can compare the two versions, first of all put in a trace command and output this value currentVersion
03:15and then the currentVersion variable, then put in a conditional clause.
03:24If currentVersion is less than newVersion then I will put a trace statement like this trace eligible for upgrade.
03:34In the else clause add another trace statement not eligible for upgrade.
03:47Save your changes and run the application in debug mode, click the compareVersion button and watch the console
03:57in Flex Builder and you should see that the currentVersion is reported as version 1 and the message is eligible
04:02for upgrade because the currentVersion version 1 is less than the newVersion version 2.
04:08In the next video I will show you how to complete this process and execute the automatic upgrade.
Collapse this transcript
Performing an application update
00:00In this video, I'm going to describe how automatically Update the application
00:04after you have already downloaded the application installer to your local disc.
00:08You can only perform an automatic update using an installer that's stored on the local file system,
00:13that's why we had to download it first and it's strongly recommended that you only do this automatic update
00:18after you have checked your version numbers and I showed you how to do that in the previous video.
00:22For this demonstration I will use an application named ExecuteUpdate.mxml,
00:27this is very similar to the application that I used earlier.
00:30It has all the code to download the application from the website and then the code to compare the version
00:35of the currently running application against the version that we want to install.
00:39If we go back to the application descriptor for this application you will see that this version
00:45of the application is still on Version 1.0.
00:48So here are the steps, I'm going add code to do the update that I'm going to install this version of the application,
00:55you can only execute an automatic update using an application that's already installed
00:59in the local operating system.
01:00Then at runtime I will execute the update first checking the version number.
01:06Let's go back to the code.
01:08Codes of the compareVersion's method that currently is returning void, change its return data type from Void
01:14to Boolean, then go to the, if then clause, that's comparing the currentVersion to the desired newVersion.
01:20If the currentVersion is less than the newVersion return true, and otherwise return false.
01:30Now we have a function that we can use to determine dynamically whether we are eligible
01:35for an update, go to the do upgrade method.
01:38This method was added to this version of the application already
01:41and is being called upon a click event of the button labeled doUpgrade.
01:45Here are the steps, create a variable named updater datatyped as updater class
01:51and instantiate the object using the updater class' no arguments constructor.
01:56The next step is to create a file object, declare a new variable named installer file datatyped as a file object
02:05and get its location using the same syntax as we used before when we set the location of the file that was downloaded
02:11to the disc File.desktopDirectory.resolvePath then pass in the name of the installer file MyAIRApplicationV2.air.
02:25Finally do the upgrade.
02:28Call the updater object update method, you will pass in two arguments, the first is the file object that point
02:36to the AIR file that you have saved locally, I named it installer file.
02:39The second is the literal value of the new version 2.0.
02:44Now this value must match exactly, the version number as described in the application installer's descriptor file
02:51and you may remember back in the earlier video when we created the version 2 installer,
02:56that this is the version number that we put in 2.0.
02:59Now wrap all these code in an if clause, you only want to call this code if in fact you are eligible for the upgrade.
03:07See you will call the compareVersion function and wrap all of this code into the if clause,
03:15so that you will only be doing the update, if in fact you are eligible for it.
03:20Then add an else clause and use the alert class.
03:24Always selecting the Alert class from a list of classes to make sure that you put in the required import statement,
03:30then call the show method and pass in some error messages.
03:35Application can't be upgraded and error.
03:41Now you are ready to package and install the application.
03:44You can't run the updating functionality from an application that's running in debug mode,
03:49it has to already be installed on the operating system.
03:52So now use the Export feature to Export or Release Build.
03:57From the Menu select file, Export, Release Build, select ExecuteUpdate.mxml as the application
04:06and then change your export to file value to MyAIRApplicationV1.air, click through the screens to export
04:14to Release Build providing a digital certificate where necessary and then when you say that you want
04:20to finish the export, you will be prompted to overwrite the existing AIR file.
04:25Click yes, then go back to the Flex navigator view and double click to open MyAIRApplicationV1.air.
04:35Notice that it shows you that you haven an installed version of 1.0 and a version to be installed of 1.0.
04:42Click the replace button and this will ensure that the latest version of the application has been installed.
04:48You will know for sure that you have the right version because you will see the doUpgrade button
04:53and if you don't see the button then you will notice that you might have missed a step.
04:56Now we will execute the upgrade.
04:58Click the do upgrade button, you will see that the application closes and then reopens
05:04with its new look, showing that it's now in version 2.0.
05:07So those were all the steps for managing automatic updates to AIR applications.
05:12Once again the old version of the application must know the version number of the application it wants to update to.
05:18You can provide that information either hard coded in the application as I did in this demonstration
05:23or you could perhaps post an XML file that the application could download and inspect at runtime to find
05:30out what version is available then to actually execute the updating, you download the AIR application to the local disc
05:36and then use the updater class to perform the update.
Collapse this transcript
13. Advanced Techniques
Closing an application gracefully
00:01In this chapter of the video series I'm going to describe a couple of advanced techniques,
00:05that allow you to control how applications close and how they communicate with each other.
00:10For these demonstrations I'll use a Flex Project from the Exercises area.
00:13If you're following along with the Exercises, you can import this project.
00:18Select File, Import, Flex Project, click the Browse button next to Archive file, navigate to the Chapter13 folder
00:27under the Exercises area, and select Chapter13BeginProject.zip.
00:33Import the project, then go to the Flex Navigator view, go the source folder,
00:39and open the application, ClosingApplication.mxml.
00:43This application uses a Native Window as a pop-up window.
00:46It has a common issue.
00:48When you run the application and then click the Open Window button, that creates a Native Window component.
00:53If you then go back to the main application window and close that, then native window is left open on its own,
00:59and the application doesn't completely exit until the user closes down the native window pop-up.
01:05To handle this issue, I'll show you how to listen for an event named Closing.
01:09This event is dispatched as a native window is closing down.
01:12It's dispatched on the application window and also on any other pop-up windows.
01:16It's particularly used for an application window to detect when the application is shutting down,
01:22to allow you to handle synchronous operation, such as closing any other native windows.
01:27Let's take a look at the existing code.
01:29In the openWindow () method, there is a call to initialize the win variable and then open it on the screen.
01:35The closeWindow () function first calls the window's close () method and then sets the win object
01:40to null to release it for garbage collection.
01:42So, when the application is shutting down, if you would like to make sure that the native windows shut
01:47down at the same time, you'll handle two steps.
01:50Step number one will be to listen for the closing event, and when it happens, you'll then explicitly close
01:56that other native window, and then handle any other tasks that your application might need to do,
02:01before everything is completely shut down.
02:04Go to the windowed application tag, and add a closing event listener, then call a method called closingHandler ().
02:12We'll have to create that method, it doesn't already exist.
02:15So then go down to the Script section and add a new private function, named closingHandler ().
02:26Within the closingHandler () method, check first to see if the win variable is null.
02:32If (win != null), and then within the conditional block, call win.close ().
02:41This ensures that the native window pop-up is closed down, if in fact it's open,
02:46before you close down the rest of the application.
02:49I'll save the changes and run the application.
02:54I'll open the window and you'll see the My Native Window pop-up up here.
02:58Then I'll go back to the application window and close down the application by clicking the close icon,
03:04and you'll see that both the application and the pop-up window are closed simultaneously.
03:09You can also check to make sure you can still run the application,
03:12which would mean that the application is closed down completely.
03:15If in fact there were any invisible window still left in the environment,
03:19you wouldn't be able to restart the application from Flex Builder.
03:22Once again I'll open the pop-up window and then once again I'll close.
03:28It's also possible to explicitly close the application using a command called exit,
03:33that's a member of the Native Window class, here's how you do it.
03:36Create a new private function, named exitApp (), return void from the function.
03:46Within the function use this syntax, NativeApplication.NativeApplication.exit ().
03:54Call the exit method without any arguments.
03:58Then go down to the button that has a label of Exit Application,
04:01listen for a click event and call the exitApp () function.
04:04Save the changes and run the application.
04:08After the application opens up, you should now be able
04:12to click the Exit Application button and the application will close.
04:15This will also work if you open the pop-up window first and then go back
04:20to the application and close it programmatically.
04:23Notice that both the application window and the pop-up native window are closed at the same time.
04:28This is because the closing event is dispatched, no matter how the application starts to close,
04:33and it doesn't matter whether it happens as a result of a user gesture such as a mouse click or a keyboard shortcut
04:39or whether you're closing the application explicitly by calling the exit method.
Collapse this transcript
Communicating between AIR applications
00:01In this video I'm going to describe how to use a class name to the local connection that allows you to send messages
00:06between AIR applications running on the same local system.
00:10For this demonstration I'll use two AIR applications named CommunicationSource,
00:14and CommunicationTarget, both in the Chapter13BeginProject.
00:18If you're following along in the Exercises, you can open both of these applications now.
00:23I'll start off in the source application.
00:25The source application also sometimes known as the sending application, needs an instance of the LocalConnection class.
00:32You typically declare this class outside of any functions, so that you can address it from anywhere in the application.
00:38Place the cursor above the existing functions inside the Script section
00:43and declare private variable named sendingConn datatype as LocalConnection.
00:49At the same time, instantiate the variable using new and then call
00:56to the LocalConnection class's no arguments constructor method.
00:59Now, go down to the sendData () method.
01:01In this application, there are two text input controls, with IDs of fnameInput and lnameInput.
01:08When you call the sendData () method, there is already line of code there
01:11to concatenate these strings together into a single string.
01:15Now, in order to send the data from the sending application to the receiving application,
01:19call the Connection object's send method.
01:22Call sendingConn.send, and the first argument you go and pass in is a connection name.
01:29In order to communicate effectively between two AIR applications, the connection name should always start
01:34with an underscore character, and then can have descriptive name after that.
01:39I'll name it _myConnection.
01:42The second argument that you pass in is the name of a public method of the target application that you want to call.
01:48In the communication target application there is already a pubic method named displayData (),
01:53that's expecting a single argument, the name as a String.
01:56So that's the method that we'll call.
01:58You pass in the method name again as a String.
02:01Any other arguments that you pass in after that are considered to be arguments of the receiving method.
02:07So, for example, the third argument that you pass
02:09into the send method will be the first argument received in the remote method.
02:13I'm going to pass in the value of fullName, the variable that's already been created.
02:18So that's all you in the sending application.
02:21You instantiate the LocalConnection object, and then when you want to send the message you call the send method,
02:26you pass in a connection name, which is always prefixed with an underscore character,
02:30to indicate that you're communicating between applications with different identifiers or different domains.
02:36Then you pass in the name of the method you want to call, and any other arguments that you want to pass.
02:41Now, switch over to the target application.
02:44As with the sending application, declare a variable outside of any functions
02:48and datatype it as a LocalConnection object.
02:51I'll declare a variable named receivingConn, datatyped as LocalConnection, and as I did in the other application,
03:00I'll immediately initialize this object using the LocalConnection class as no arguments constructor method.
03:07Now in the init () method, which has already being called upon the applicationComplete event of the application,
03:13you're going to set up the connection to listen for messages.
03:16There are three properties to set.
03:18The first property is named client, and it's a reference
03:22to the Flash-based component that's going to receive the message.
03:25Set that value to, this, that is the application itself.
03:29The next item is a call to a method named allowDomain.
03:33For AIR application communication, you should always pass in a value of a single asterisk, this is because in order
03:39for AIR applications to communicate with each other over the LocalConnection class,
03:43you have to allow interdomain communications.
03:46If you're working with Flex applications downloaded as web applications, the rules are a little bit different.
03:51Now, call you Connection object's connect method, and pass in the name of the connection you're listening.
03:57Once again I'll use receivingConn and now I'll call the connect method and I'll pass in the name of the connection,
04:03which as before, starts with an underscore character, and then is any descriptive value.
04:09The important thing here is that connection name in the sending and receiving applications must match exactly.
04:14Now, the sending application is saying I want to call the displayData method
04:18and the receiving application's displayData method will receive the data.
04:22And as you can see in the code, it outputs that String to an object labeled, out, which is a text area control.
04:29I'll save the changes to both applications and then run both applications.
04:34So that's it.
04:35I've set the client property, I have called the allowDomain method and passed in a wild card asterisk,
04:40meaning anything to communicate with anything,
04:43and then I've connected using the same connection name as I said in the sending application.
04:47I'll save the changes and I'll check my problems area to make sure there are no programming errors.
04:53I'll go back to the source application and run it.
04:56Then I'll go to the target application and run it as well.
04:59Then I'll arrange the applications on the screen, so I can see both at the same time.
05:04I'll type values into first name and last name, and click the Send button, and in the target or receiving application,
05:13you should see that the data is correctly received.
05:16It's also possible to send more complex data, using the LocalConnection class.
05:21I'm going to make a couple of changes to the code in both applications.
05:25In the Source application I'm going to modify the behavior so that instead
05:29of sending the full name, I'll send a complex object.
05:32I'll put in braces to indicate that I'm creating a new ActionScript object on the fly,
05:38and then I'll pass the two values individually.
05:41The first item will be named firstname and will come from fnameInput.text
05:46and the second item will be called lastname and will come from lnameInput.text.
05:54I'll reformat the codes, we can see it all on the screen at the same time.
05:58So now instead of sending a simple String, I'm now actually sending a complex object.
06:03Now I'll go to the Target or receiving application and re-factor that as well.
06:08In the displayData function, I'll change the fullname's datatype from a String to an Object, and then,
06:15I'll set out.text to fullname.firstname, plus a space, plus fullname.lastname.
06:26I'll save the changes to both applications and run them once again.
06:30Once again I'll arrange the applications on the screen so I can see them both.
06:34I'll click into the Sending Data application and type in a name,
06:38click the Send Data button, and you'll see that it's received again.
06:43So you can send either simple values or complex values, using the LocalConnection class.
06:48There is one more subject to know about with the LocalConnection class that's important.
06:53Whenever you send information from the connection class, you'll get a StatusEvent
06:58and this event includes a level property that will tell you whether a thing succeeded or not.
07:03Go back to the sending application and place the cursor above the call to the send method and add an event listener
07:10to the sending connection object, and listen for the StatusEvent represented by the constant StatusEvent.STATUS.
07:18Then, call the existing statusHandler method that's already been created in this application.
07:24Now go down to the statusHandler method and put in the following conditional code, if (event.level == "status")
07:36and if that conditional evaluation is true, add in a trace method
07:40that outputs a message to the console that says, Success.
07:46Add in else clause and make a call to the trace method that outputs the string, Failure.
07:52Now go back to the Target application and run it in standard mode and then go back to the Source application
07:59and run that application in debug mode, so that we see the trace statements
08:03from the Source application but not from the Target.
08:06Now, click into the Source application and type in a name, and click the Send Data button,
08:14and you should see in addition to the data appearing in the Target application, the trace output, Success.
08:20Now, close the Target application, and try sending the data again,
08:25and this time you should see the trace message, Failure.
08:28So the StatusEvent will let you find out from within the sending application,
08:33whether the receiving application was there, ready, and whether it received the message successfully.
Collapse this transcript
Conclusion
Goodbye
00:00Hi! David Gassner here again. Thanks for sitting with me through this video series on building and deploying desktop applications
00:06with Flex 3.0 and AIR.
00:08In this series I showed how you can use your existing Flex application development skills
00:13to create native applications that run equally well on Windows and the Mac.
00:18I hope you found the answers to your questions about working with the local file system,
00:22creating and maintaining local databases, and other powerful features of the Adobe Integrated Runtime.
00:28lynda.com has other video series about using these advanced features of AIR,
00:32programming in Flash and Ajax. Whichever architecture and development tools you select, happy desktop application programming!
Collapse this transcript


Suggested courses to watch next:



Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,141 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,025 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked