navigate site menu

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

AIR for Flash Developers (2008)
Don Barnett

AIR for Flash Developers (2008)

with David Tucker

 


Rich internet applications become more popular and powerful every year, but they have been limited to what can be done from within a web browser. Adobe AIR allows web developers to leverage their Flash, Flex, HTML, and AJAX skills to create multi-platform desktop applications. In AIR for Flash Developers, David Tucker uses Flash CS3 Professional to create several AIR applications, exploring the workflow and features of the AIR extension and runtime along the way. He discusses how to integrate with an operating system; how to incorporate HTML and PDFs; how to use the local SQLite database for information; how to package, distribute, and update AIR applications; and much more. Example files accompany the course.

Note: This course will be most valuable to those who are familiar with ActionScript 3.0 and XML within Flash CS3 Professional.
Topics include:
  • Exchanging data with the Clipboard
  • Supporting drag-and-drop functionality
  • Performing file system actions
  • Managing multiple native windows
  • Using application, window, and context menus
  • Monitoring network connections
  • Synchronizing online and offline data

show more

author
David Tucker
subject
Developer, Desktop Apps
software
AIR 1, Flash Professional CS4
level
Advanced
duration
7h 2m
released
Jul 08, 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:00Welcome, I'm really glad you are here for this series and whether you're just curious about AIR or if you've already built an application,
00:07I really believe you can get a lot out of this series.
00:10AIR provides so much new functionality for Flash developers. And I am really excited to see the kind of applications that
00:16will be coming out over the next year.
00:18Now you maybe wondering, how am I connected with AIR? Well, I am an AIR, Flash and Flex developer from Savannah, Georgia
00:24and I have been working with AIR since its early days when it was still called the Apollo.
00:28I'm also a writer at insideria.com where I blog about AIR and its affect on rich internet application landscape. I'm also a
00:35contributor to the Adobe AIR Developer Center as well as maintaining my own blog at davidtucker.net, where I focus on AIR
00:41related projects. Now I hope that you are as excited about the possibilities with AIR as I am.
Collapse this transcript
Using the example files
00:01Just a quick word about the exercise files that we'll be using.
00:04If you're a premium member of the lynda.com Online Training Library
00:08or if you're watching this tutorial on a disc, you have access to the exercise files used throughout the title.
00:13In the Exercise Files folder, I have collected some assets for you as well as some graphics and some pre-compiled applications
00:20that you can use that actually go along with what we will be learning.
00:23Now I have copied this folder onto the desktop, but you can put yours wherever you would like.
00:27Now if you're a monthly or annual subscriber to lynda.com, you don't have access to the exercise files, but you can
00:33easily follow along and use your own assets inside of the applications that you will create.
00:37Let's get started.
Collapse this transcript
1. Getting Started with AIR
Introduction to AIR
00:00As we begin this series, I wanted to give you a little bit of information about some things that you can expect. We're going to be
00:05developing several applications throughout this series including a web browser built entirely in Flash CS3, an image viewer
00:12that allows you to pull images off of your local hard drive to view them,
00:15an online-offline contact manager application and even an application that analyzes the current monitor setup that you have.
00:22Now all of this is great and I really hope that you are excited about it, but also there are a few things that you'll need
00:27to know as we get into this. First, we're already making some assumptions.
00:32We assume that you're a little bit competent with ActionScript 3.0 as well as have a good understanding of how to work
00:37with the Flash IDE.
00:38If you don't, no worries.
00:40There are some other great series here at lynda.com that you can view to actually get up to speed on some of these issues.
00:49Just as an example, here in the Image Loader, we are actually dynamically grabbing some XML and then we are actually parsing
00:55through that to create some objects. If that seems kind of strange to you, again no worries, but I probably would take a
01:01chance to go look at some of the other tutorials on Flash CS3 and ActionScript 3.0 before you decide to jump into this course,
01:08but if you're ready for it, we're going to create some really great applications using Adobe AIR powered by Flash CS3 Professional.
Collapse this transcript
Getting started with AIR
00:01The AIR Essential Training series here at lynda.com covered many of the details on how to get Flash CS3 ready for
00:06creating AIR applications.
00:08Let's review those steps. First, you'll need to be sure that you have the latest version of Flash CS3 Professional installed.
00:15Now this can be accomplished by going under Help,
00:18and then Updates under the File menu. If you do need to update your installation, just complete the on-screen prompts before
00:24moving onto the next step.
00:26Next you'll need to download the Adobe AIR update for Flash CS3 Professional.
00:30This update can be found at the URL
00:33adobe.com/support/flash/downloads.html.
00:40When you scroll down the page you should see the option for the Adobe AIR Update for Flash CS3 Professional.
00:46Download the version that is correct for your system
00:48and save it on your hard drive. You will need to close Flash and any open browsers before continuing.
00:53Then install the update for Flash CS3.
00:56You'll know that the update installed correctly when you see the Create New Flash File Adobe AIR option on the welcome screen.
01:04Once you have installed this update, you'll be ready to create all of the applications that we will be working with in this series.
Collapse this transcript
2. Using the AIR Extension for Flash CS3
Understanding the AIR application workflow
00:00So you want to develop full desktop applications.
00:04Well the AIR update for Flash CS3 gives Flash developers the ability to create,
00:09test and package AIR applications using tools that they are already familiar with.
00:14While the tools are similar, the process for working
00:17with AIR applications inside of Flash is a bit different from the normal Flash development.
00:22You will need to review a few old items and learn a few new ones.
00:25In addition, I will walk you through the entire workflow for a Flash CS3 AIR application.
00:30Now there are a few helpful terms that you are going to need to know as you work with AIR.
00:35First, of course you will need to know AIR, and AIR is short for the Adobe Integrated Runtime
00:40and it is the base on which each AIR application runs.
00:44Now what this means for you is that you can't run your AIR application on any computer
00:48that does not have the Adobe Integrated Runtime installed.
00:52ADL is the short for the AIR Debug Launcher. It allows for an application to be previewed without installing it
00:58onto the computer and this is very important for you the developer, because you don't want to have to package
01:03and install an application every time you want to test one small change.
01:08When an AIR application is distributed, it is distributed as an .air file.
01:13Now this file allows an application to be installed on a computer.
01:16Now of course as we said it earlier, this computer has to have AIR installed
01:20for the .air file to be recognized as an actual AIR file.
01:24And finally a secure certificate is required to create an .air file
01:30and it verifies the publisher and application integrity.
01:33Now because AIR applications are so much more powerful than traditional Flash movies,
01:38AIR applications can work with the local file system.
01:40AIR applications have an embedded database and so these additional pieces
01:44of functionality require that an extra security measure be taken.
01:49So let's look at the workflow inside of Flash CS3 for AIR applications.
01:53First, you are going to need to create. Application are built with the same graphical tools
01:58as with a standard Flash movie, so you can use those same tools from the palette just as you did
02:04within Flash CS3 for traditional Flash movies.
02:07However, applications can choose to take advantage of the new classes and service monitoring components within AIR,
02:13so there is additional functionality. So not only can you use the same tools
02:16but you can expand on that and offer even more.
02:19Now debugging an AIR application is very much like debugging a traditional Flash movie.
02:24Applications can utilize the ActionScript 3 Debugger that's in Flash CS3.
02:28So all the power of that debugger isn't lost in AIR; rather you can use it to its full functionality inside of AIR.
02:35Second, applications are still run with the Test Movie and Debug Movie commands,
02:40and for those of you that use keyboard shortcuts,
02:43the keyboard shortcuts for those commands still work within AIR as well.
02:47The difference however, is that applications are handled by ADL, the AIR Debug Launcher instead of the Flash player.
02:54Finally, packaging and sending out your application.
02:57Applications are not published with the traditional Publish command,
03:01so the way the Flash CS3 movies were published is not the same.
03:06In Flash CS3, a movie was generated with an HTML file and other things that could easily be embedded on a web page,
03:12but rather with AIR, you create a .air file.
03:15The applications with AIR must be packaged using the Create AIR File command.
03:20This is found under the Command menu and it was one of the options added by the AIR update for Flash CS3 Professional.
03:26And finally as we stated earlier, applications must be signed with a secure certificate.
03:32This is important because it adds another security measure so that people can know who the application is coming from.
03:38Now while there are many techniques used in crafting AIR applications that I will cover in this series,
03:42the core workflow of creating, debugging and packaging an application will mostly remain the same.
03:48Once you understand how this process works in Flash with a simple AIR application, you can apply this to any
03:54of the complex applications that you will be creating in the future.
Collapse this transcript
Modifying the Application and Installer settings
00:00At this point you are probably ready to create your first AIR application,
00:03but you might be wondering, how do I make my application behave like other desktop applications I have seen?
00:08What's important to know that the desktop opens up many new possibilities for the developer
00:13for how the application will both look and function.
00:16Now to learn how these settings can affect an application, let's just go ahead and create one.
00:20So anytime you want to create a new AIR application inside of Flash CS3 you are going to want to go
00:25under the Create New Flash File Adobe AIR option.
00:28And when we create the new application it's going to look a lot like a normal Flash movie.
00:33There are a few things we are going to need to do first.
00:36First if we go under File and then Publish Settings, we are going to need to uncheck the HTML option.
00:42We don't need the generic HTML that's generated for a Flash movie because again this isn't going to be running
00:47in the browser, this is going to be a desktop application. Then we can click OK.
00:52Next we are going to want to go ahead and save our movie.
00:55Flash is going to require that you actually save a movie before you can edit the Application Settings.
01:00So let's go to File, Save and I am going to call this one Sample Application.
01:06And I am going to save it under the Chapter 2 folder of the exercise files
01:11but you can save it wherever you would like on your hard drive.
01:14After our application has been saved we can go ahead and start adding things to the Stage.
01:19First I am just going to go ahead and add some text to the Stage, to show that again just by using the normal tools
01:24that you are used to working with inside of Flash you can add items to a desktop application.
01:28Next I want to bring an image in that's going to serve as the footer for our application.
01:36So I am going to go to File and then Import and then Import to Stage.
01:42Now if you look under the exercise files folder in the Chapter 2 folder inside
01:47of the Images folder you will see an image called Footer.
01:50Let's open that image.
01:52Now that's brought it into the Stage but I want this to be positioned at the bottom.
01:56And again just as in Flash I can go to the Align panel.
01:59If you don't see the Align panel you can get there by going under Window and then Align.
02:04Now if we select the image and we go over here To Align and be sure that the
02:08To Stage option is checked we can then just hit the Align to Bottom button.
02:13That will align our footer to the bottom of the application.
02:18Now we have added some basic items to the Stage, we can now test our application.
02:22Now to test your application you simply need to go to Control, Test Movie.
02:26Now this is going to look like a lot of the very basic desktop applications that you have seen.
02:33It's got the normal what we call chrome around it like most other desktop applications.
02:38And it also can be moved around and has options for closing, for maximizing and for minimizing the application.
02:44But there are a few things on this application that aren't ideal.
02:47First, if we move to the bottom right corner of the application we can see
02:51that we are given the option to resize the window.
02:53And if we start resizing our application we notice that our application really wasn't made to be resized.
02:59The image at the bottom of the application is becoming very pixelated.
03:02It doesn't look very good.
03:04In addition if we go to the Maximize option and click it, our application takes up the whole screen but
03:10yet again the image at the bottom is pixelated because our application really wasn't made to be maximized.
03:15So wouldn't it would be great if there was a way to turn some of these items off so that users
03:19of your application could only do what you wanted them to do?
03:22Well these are just a few other things that you can change by changing the settings
03:26in the application descriptor file for an AIR application.
03:29Now the great thing is inside of Flash there is an easy way to edit the application descriptor file by going
03:35under Commands and then AIR Application and Installer Settings.
03:39If we click on that it brings up a dialog box with the lot of different form fields.
03:44Now a few of these are very important and are going to be need to be changed for each
03:48and every AIR application that you create.
03:51First I want to go ahead and give it a name. You can see that's already been given a name, Sample Application.
03:56And I am going to put a space in between that should call it Sample Application.
04:00Same thing for name we will give it the name, Sample Application.
04:03Now these items can't be left at their default values and it would be okay.
04:08But an item that needs to be changed for each and every AIR application that you create is the Application ID.
04:14This is how AIR distinguishes one AIR application from another.
04:17And when many people create an ID for their application they use something called Reverse DNS Format.
04:23And basically what this means is you take a domain that you own or associate it with and you flip it around backwards
04:30and then add the name of your application.
04:31For example, if I wanted to use the domain lynda.com, I could type in com.lynda and then add
04:41in the name of my application, Sample Application.
04:46You need to be sure that you go in and edit the application ID for every AIR application that you create.
04:51Now we are not going to worry about these other settings at the moment but we did want to stop people
04:55from resizing and maximizing our application.
04:58To accomplish this we are going to need to go to the advanced settings.
05:02If we click on the Settings button another dialog box will open and you will see that there are options
05:07and checkboxes next to Maximizable, Minimizable, Resizable and Visible.
05:12We are going to uncheck the Resizable and Maximizable options and then click OK.
05:17And if we click OK one more time these settings are going to be applied to our application.
05:22And now if we go to Control, Test Movie, our application will launch but now someone goes to the corner of our application
05:29they're not going to be given the option to resize the window.
05:32In addition if they go to the Maximize button, it's been disabled
05:36and even if they click it it's not going to maximize the application.
05:40Now these are just a few of the settings that you can change inside of the application descriptor file.
05:44Now to review, anytime you want to edit any of the application settings that are
05:48in the application descriptor file you will need to use the Application and Installer Settings dialog box.
05:54Every time you create an AIR application you will need to at least edit the application ID.
05:58Now this will be a core task that you will use for any AIR application that you create and since you know how
06:04to create your application with custom settings and how to test it with the AIR Debug Launcher you are now ready
06:09to package you AIR application for installation.
Collapse this transcript
Signing your AIR application
00:01The application is complete and now you need to be able to distribute the application to anyone and everyone.
00:07Since AIR applications are true desktop applications,
00:11the way in which they are published is quite a bit different from a traditional Flash movie.
00:15When AIR applications are published, they are packaged into an .air file that then can be installed
00:21on any computer that has AIR already installed.
00:23Since AIR applications have access to the user's computer,
00:26security is even a greater concern than with the traditional Flash movie.
00:30Because of this, the packaging requires a few additional steps.
00:33The first step is to create a secure certificate to package your AIR application with.
00:39We will start by opening the sample application.
00:41Let me go under File and then Open and then select Sample Application,
00:46which can be found under the Exercise files in the Chapter 2 folder.
00:50Now when the application is launched, we are going to need to go to the Application and Installer Settings dialog box,
00:56which can be found under Commands, Application and Installer Settings.
01:00Now to create a certificate, we are going to go down to the installer settings.
01:04You will see that there is an option that says Digital Signature and next to it says,
01:08"Select a certificate to sign the AIR file."
01:10Well we don't have one yet, so we are going to need to create one.
01:13So we need to click the Set button, which will allow us to then create a new certificate.
01:18And to create one, we can click the Create button and it will bring up another dialog box.
01:22Now you are going to have to fill in each of the items here, so for Publisher Name, I am just going to say,
01:28David Tucker and for the Organizational Unit, part of the organization that develops AIR applications
01:35and then for the Organization Name, we will say lynda.com.
01:39So we have created these basic items for our certificate, now the publisher name will actually appear
01:44in the installer, if you use a commercially signed certificate, not if you use a self-signed certificate.
01:49So now we are going to go and enter a password for our secure certificate.
01:53We are going to enter just 12345 for my certificate, hopefully,
01:58you will pick a much better password for your certificate.
02:01Then we need to select where we will save our certificate.
02:05So if you click the Browse button, it allows you to select a directory to save the certificate in.
02:09For this example, I am going to save the certificate on the desktop.
02:13So if we select desktop and then hit OK, we can see that it is going
02:16to name the certificate, mycert.p12, and that's what we want.
02:19We will just click OK and it will take the application in a second as it creates the file.
02:24Then it will inform us that the self-signed certificate has been created.
02:27We will click OK.
02:29Now we have created our certificate and it will automatically populate that into the certificate field.
02:34Now we need to enter in our password.
02:36I am going to enter in the extremely difficult password of 12345 and I am also going to select for it
02:43to remember the password for this session.
02:45This way each time we package the AIR application as long as we keep Flash open,
02:49we won't have to enter this password again, then we click OK.
02:53Now we have actually gone through the first step of packaging our application.
02:57Next, we will actually have to go through the process of creating an .air file as well
03:02as adding a custom icon to our application.
Collapse this transcript
Packaging your AIR application
00:00Now that you have signed your AIR application, you now can create an .air file that then can be distributed
00:06to anyone who is running AIR on their computer.
00:09In addition to doing that, we are also going to customize the Application icon
00:13to give your application a customized look and feel that people can then recognize.
00:18So the first thing we are going to do is open up our sample application, so I am going to go to File and then Open
00:23and then I am going to select sampleApplication02 which is in the Chapter 02 folder of the exercise files.
00:30Now that I have loaded up my application, I am going to go under Commands and then AIR application
00:36and installer settings, and that's going to bring up the application and installer settings dialog box.
00:40Now we have worked with many of the items in here, but we have not yet worked with configuring the Application icon
00:46and the reason is that this value cannot actually be previewed
00:49until you actually package and then install your application.
00:52So I am going to hit the Select icon images button and it's going to open up
00:55and it's going to show us 4 different sizes of icons.
00:58Now the reason that these icons are of different sizes is that different operating systems use them
01:03at different places at different sizes, so this way we can be sure
01:07that our application icon will appear properly for each of these sizes.
01:10So I have created some icons and placed them in the Icons folder inside of the Chapter 2 folder in the exercise files
01:16and we are going to replace these values with those.
01:19We are going start off here with the one that's 128 x 128.
01:23I am going to hit the Folder icon.
01:24I am going to go into the Icons folder and select Icon-128, and then I will do the same for 48,
01:32and then I will do the same for 32 and finally, 16.
01:38Now I have added all of my custom icons, and I can hit OK.
01:42Now I am just going to check and be sure that our signature has been signed correctly,
01:47and yes we can see that it has the correct certificate and we can hit OK.
01:53Now we are ready to actually package the application.
01:56So now I am going to save the file and then I am going to go to Commands and then Create AIR File.
02:01And then it will tell us the AIR file has been created.
02:05So I will click OK and I am going to open up the Chapter 2 folder and we will now see inside of there,
02:10a sampleApplication_02 that's an .air file, it's in installer package.
02:17So now we actually can double click on this and install our application.
02:20It will walk us through the process, again because we have used a self-signed certificate,
02:26it will tell us that the publisher is unknown, but then we can hit Install, we can leave the default settings here
02:32and just hit Continue, and it will actually install our application and there we go.
02:37We have actually installed and run our application.
02:40If we go to the desktop, we can see now that our Sample Application icon has been populated there as well
02:47as when we run the application, we can see that our icon has been populated at the top
02:52of the application as well in the native window.
02:55So now that you have learnt how to use the workflow to not only create, test and now package in your application,
03:01you now can move on to actually creating AIR applications that utilize some
03:04of the AIR specific classes that are available within Flash CS3.
Collapse this transcript
3. Using the Clipboard
Introducing the Clipboard
00:01As we begin to look at the clipboard support inside of AIR, we are going to be using a sample application
00:06that I have already created. So to see how this works just go ahead and look at the sample application
00:11without any of the AIR functionality in it.
00:15So we go to File and then Open.
00:17Then I am going to open ImageViewer01, which is in the Chapter 3 folder of the exercise files.
00:23Once the application is loaded, I am just going to go to Control and then Test Movie to see the functionality.
00:32Now what's happening is the application is loading an XML file that contains a listing of images
00:37with their thumbnails and if you click on any of these smaller items in the list below,
00:42it will bring the larger image to display above it.
00:46Now this is using 2 components, this is using a UI Loader for the top area
00:51and it is using a Tile List for the bottom list area.
00:54Let's look and see how we implemented that inside of ActionScript.
00:57So I am going to select my Actions layer, and then I am going to go to Windows
01:03and then Actions or again we can press the F9 key.
01:07Now immediately, you will notice that we have brought in some classes that we are going to be using,
01:12URLLoader, URLRequest and then the UILoader class.
01:15And if you look down, you will see why we used the first two.
01:18We are going to load in the XML using an URLLoader and it's just going to load in slides.xml.
01:23Now this is going to work the same way in an AIR application as it did in the browser,
01:28it's going to look in the exact same directory, it's going to find slides.xml and load it in.
01:33When that's complete, it's going to call the onXMLLoad method.
01:37And if we go and look at that method, it actually takes the loader, the data that's returned by the loader
01:43and then creates a new XML object and then here it uses that data to create an object for each of the different items
01:52that are found in the list: one for the thumb, one for the full size image, one for the caption.
01:57And then when it's done, it actually takes and adds it to the TileList component.
02:02Now some of this XML work might look a little bit confusing. If you haven't seen this before you might want to look
02:07at Todd Perkins' series ActionScript 3, Working with XML here on lynda.com.
02:14Now after we have added that, we are going to actually configure our TileList.
02:17So we have actually set a TileList on the Stage, we have set its size, its column width, its row height, its label field
02:24and then we also have added an event listener to it that is called onImageSelect,
02:28that gets called every time the item is changed within the TileList.
02:31So if we go and look at onImageSelect, it's going to set the imageLoader.Source equal to the data of the object
02:40that we set up here, which is the full size image.
02:43So it uses the data property to then set the image that will be displayed full size.
02:49So this simple application just uses roughly 39 lines of ActionScript code to create an application that loads
02:56in data from an XML file and then displays a list of images and then allows you to click
03:01on those images and view the images full screen.
03:03But there will be a lot of things that we would like to do with this application with some
03:06of the AIR specific functionality, so over the course of the next few sessions, we are going to be adding different items
03:11to this application to give it increased functionality.
Collapse this transcript
Understanding the Clipboard
00:00Most modern operating systems use a clipboard to share data between different applications.
00:06This can be simple data such as copied text, bitmap data from an image or a list of files from the desktop.
00:12Every time you copy and paste between applications, you are using the clipboard.
00:17Now before you begin working with the operating system clipboard inside of AIR,
00:21I wanted to demonstrate some key characteristics of the clipboard.
00:25So to do that, the first thing I am going to do is open up Internet Explorer.
00:28Now I have loaded up the lynda.com homepage, and I will go scroll down
00:33and I am going to find this one paragraph of text.
00:35I am going to highlight the paragraph and I am going to right-click or Control-click on Mac and select Copy.
00:41At this point, you will probably assume that this has just copied just the text,
00:46but as we will learn there are many different kinds of text within the clipboard.
00:50To illustrate this, I have loaded up Microsoft Word 2007.
00:54Let me go to the Paste option and I am going to go down to the Paste Special and it's going to show us a list
01:01of every type of data that's currently on the clipboard.
01:04We can see right here from this one item that we have highlighted and copied that there is unformatted text
01:10as we might expect, there is also HTML Formatted Text, there is Unformatted Unicode Text and there is Formatted Text RTF.
01:18So simply by highlighting one paragraph and copying it, we get 4 different data types added to the clipboard.
01:24But it's not just with text.
01:26If I clear all the items off the clipboard and I go back to the web page, I can unselect this text and move to the top
01:34of the page and right-click on the logo and select Copy.
01:38If I go back to Microsoft Word and go to Paste and Paste Special,
01:42you are going to see that there are also different types of data on the clipboard with an image.
01:46There is device-independent bitmap data, which is the actual bitmap data inside of the image.
01:51There is HTML Format Data, which includes the image tag and the reference to the actual image file itself
01:56and then an actual file's object that actually contains a reference to this specific file.
02:02So just again with copying one image, we get 3 different data formats.
02:06So there are several things that we need to learn about the clipboard, but one of the main items to understand
02:10as we move forward and look at AIR support for the clipboard is that clipboard can contain many different types
02:16of data even at the same time, even from a single originating piece of data.
02:22So we are going to move on and look at how AIR supports the clipboard and we will be working
02:26with the Image Loader application that we viewed earlier.
02:29AIR supports almost every function of the clipboard and it allows
02:32to greatly enhance the functionality of this application.
Collapse this transcript
Adding data to the Clipboard
00:00One of the main goals of clipboard support is to make your data available and accessible to other applications,
00:07to do that you place the data on the clipboard.
00:10In the beginning of this chapter we looked at an Image Viewer application.
00:14Now this application is what we are going to use to add this functionality.
00:18So I am going to go ahead and open up the Image Viewer application.
00:22So I want to go to File and then open and then in the Chapter 3 folder of the exercise files I am going
00:29to go ImageViewer01 and then I am going to run the application by going to Control, Test Movie.
00:39If you remember when we click on an image you will see the larger image displayed above.
00:44To go for this video will be to take the larger image displayed above and add it to the clipboard
00:50so that other applications can access it.
00:53To do that we are first going to need to add a button to the Stage that will trigger our copy functionality.
01:00So the first thing we need to do is create a new layer.
01:02I am just going to call it Button because that's where we place our button.
01:07Then I am going to open the Components window, this can be done by going under Window and then Components
01:14and then I am going to drag out an instance of the button to the bottom right of the Stage.
01:19I can then go under the Parameters tab and change the label on this button to be copied.
01:27And we are going to give this one an instance name of copyButton.
01:32Now that we have set up our Stage we can now begin working with the ActionScript.
01:39I am going to highlight the Actions layer and I am going to go to Window and then Actions.
01:44Now the first thing we are going to need to do is we are going to need to import two specific classes.
01:51The first class that we are going to need to import is the Clipboard class.
01:54If we don't import this class we are not going to have the ability to add data to the Clipboard.
01:59To import that we simply need to say import flash.desktop.Clipboard.
02:09In addition there is also a class inside of AIR that defines what type
02:15of clipboard data formats AIR supports, that class is called ClipboardFormats.
02:22The clipboard formats that are supported by AIR are Text_Format, which holds raw text data,
02:29URL_Format that holds URL, formatted items, HTML_ Format which has html tags and text, Bitmap_Format,
02:37which contains image data, and File_List_Format, which contains data from a group of files.
02:44Now to use this inside of AIR you have to first import the ClipboardFormats class.
02:49And there are many instances where you have to tell the Clipboard either what type of data you want to set
02:55or what type of data you want to retrieve.
02:57So to import the Clipboard Formats class we need to say import flash.desktop.ClipboardFormats.
03:07Now that we have imported those we can begin to wire the Clipboard functionality into our Copy button.
03:16So I am going to go under where I can figure the TileList, I am going to create a new small little subsection.
03:23We will call it Add Event Listeners.
03:25And this is just a comment that helps keep our code organized.
03:30Now I want to say copyButton.addEventListener and then we are going to need
03:37to tell it what event we are listening for.
03:39In this case we are going to listen for MouseEvent.CLICK.
03:43And what we are going to want to do is we are going to want to call a method called onCopyClick.
03:56So now we can head down to the event handler section of our code.
04:00And we can create a function called onCopyClick; it will receive an event that will be a Mouse Event.
04:10And it is not going to return anything.
04:13Now what we are going to want to do in this method is actually add the data
04:18to the Clipboard inside of this method.
04:21But what we want to do is we also want to add a very specific kind of data, we want to add the image data.
04:27Now to add image data we are going to be using the ClipboardFormats.Bitmap_Format
04:32of the formats for the clipboard.
04:35So to do this we are going to want to have a function that basically takes the current image that's
04:40in the UIloader and returns all the bitmap data for it.
04:45So we are going to add a new subsection.
04:48And this section is just going to be called Methods because these are the methods
04:53that are going to respond to any specific event.
05:00And then we are going to want to create a method called renderBitmapData and it's not going
05:10to take any arguments but it's going to return bitmap data.
05:14The first thing we are going to need to do inside of our renderBitmapData function is we are going
05:21to create a new instance of the BitmapData class, but to do that, we are actually going to have to go back
05:26and also import the BitmapData class so let's go back up to the top of our ActionScript and directly
05:32under where we imported the ClipboardFormats we are going to import flash.display.bitmapdata.
05:44If we scroll down to where we have our renderBitmapData function the first thing we are going to do is we are going
05:49to create a variable BD which will be BitmapData and we are going to set that equal to new BitmapData.
06:00Now when you create a new BitmapData you are going to need to tell the width and the height that you want it to be.
06:05Now the great thing is our UI loader actually tells us what it's currently displaying and its width and height
06:12so we can use that as the basis for this BitmapData.
06:16So we can say imgLoader, which is our UI loader, .content.
06:22Now this is the reference to the actual image that is being displayed and we will say width
06:27and then we will say imgLoader.content.height.
06:33So now we have created our BitmapData object.
06:40And now what we are going to want to do is we are going to want to fill it with all of the data from the image
06:44that is not currently being displayed in the UI loader.
06:47Now the BitmapData class has a method called Draw that will take an object on the Stage
06:53and then draw its data out in BitmapData.
06:55So we can say bd.draw and then pass in a reference to the imgLoader.content.
07:09By doing this we now have created a new instance of the BitmapData class, we have set its specific width and height
07:17and now we have actually added the bitmap data from the current image in the UI loader into the BitmapData object.
07:24The last thing we need to do is actually return our bitmap data.
07:29Now that we have rendered our bitmap data we can go back up to where onCopyClick method
07:34and we can actually add this data to the Clipboard.
07:38So to get to the operating system Clipboard we say Clipboard.generalClipboard and this is a reference
07:47to the normal operating system Clipboard and then to actually add data
07:51to the Clipboard we are going to call the setData method.
07:56Then within this method the first thing we are going to want to tell is what type of data we are passing in.
08:01And this is where we use the ClipboardFormats class.
08:03We will say ClipboardFormats.
08:07And then we will say Bitmap_Format and this will be the image data.
08:12And then we will need to tell it what data that we wanted to pass in.
08:15So what we want to do first is we want to go back and create another instance of the BitmapData class and set it equal
08:24to renderBitmapData, the method that we just created.
08:29Then we can go to our setData call and we can pass in BD for the bitmap data.
08:37Now we can save our application and we can test it.
08:41So to test it we are going to go to Control, Test Movie and we are going to select an image.
08:50Let us select this image of Bourbon Street.
08:52Now we should be able to go and hit our Copy button and then I am going to bring up Microsoft Paint.
08:59And I should be able inside of Microsoft Paint to go Edit and then Paste and there is our image it's been brought
09:05in from our AIR application through the clipboard.
09:08By being able to add data to the clipboard you can create applications that have two way communications
09:15with other applications on the user's operating system. But AIR clipboard support does not end there.
09:21AIR also gives you access to retrieve data from the clipboard as well as using some advanced functions
09:27to control when an item is actually pasted onto the clipboard.
09:31Now that you have learned how to add data to the clipboard you can began
09:34to explore these other options that are available to you within AIR.
Collapse this transcript
Getting data from the Clipboard
00:01Another vital area of clipboard support is being able to get data
00:05from the operating system clipboard into your application.
00:08A lot of times this is just summed up by saying paste so we want to paste data that somebody else has copied
00:14in from a different application into our application so that we can use it and manipulate it however we would like.
00:20We are going to add this functionality to the Image Viewer application.
00:24This application can be found if we go to File and Open and look under the Chapter 3 folder
00:30of the exercise files and go to ImageViewer02.
00:36The first thing we are going to need to do is add another button to our Stage.
00:40We have a Copy button but we are going to need a Paste button.
00:42I am going to go ahead and lock all the layers except the top one.
00:45I am going to change it from button to buttons you don't have to but if you are going to put two buttons
00:50on a layer it probably needs to be plural.
00:52The next thing you want to do is going to window and then components then we are going
00:57to drag another instance of the button onto the Stage.
01:00We are going to change its label by going to parameters and changing the label to Paste.
01:06We are also going to give it an instance name of pasteButton.
01:13Now we can close the Components window we can kind of position our Paste button where we would like it
01:18and then we can highlight both of it and our Copy button and be sure they are lined to center.
01:23Now we can go into the ActionScript and actually add the Paste functionality.
01:28So I am going to highlight the Actions layer then I am going to go under Window and then Actions.
01:33Now we have already imported the ClipboardFormats and BitmapData classes
01:38so adding this will only require two steps.
01:41First we need to create an event listener for a Paste button.
01:46We will say pasteButton.addEventListener and we are going to listen
01:54for the MouseEvent.Click and we are going to say onPasteClick.
02:02Now we are going to need to go and create the onPasteClick method in the event handler section of our code.
02:12So we are going to create a function onPasteClick.
02:19It is going to receive an event, which will be a mouse event, and it's not going to return anything.
02:31Now what we are going to want to do inside of this method is we are going to want
02:36to take any bitmap data that's currently on the clipboard and we are going to want to display it in our UI loader.
02:42So we are going to be using a method of the Clipboard class called getData.
02:47But the first thing we are going to is we are going to create a new instance of the Bitmap class.
02:52So we are going to say var bm and this will be just of type Bitmap and a Bitmap is related to BitmapData.
03:04But BitmapData is actually contained within a Bitmap so the UI loader is going
03:09to accept a Bitmap as the actual image that's on the Stage.
03:13So when we want to actually replace that image within image
03:15from the clipboard we are going to need to use the Bitmap class.
03:18We are going to say Bitmap=new Bitmap and now we are going to actually want to get the bitmap data off of the clipboard
03:29so we can say Clipboard.generalClipboard, which again is the reference to the operating system clipboard, .getData
03:38and then we are going to need to tell up what kind of data we wanted to get.
03:43So we are going to use the ClipboardFormats class and we are going to use Bitmap_Format.
03:54Then we can close this call.
03:56Now what we are going to want to do is we are actually going to want
03:59to set the image loader's source property to that bitmap.
04:06Now when we write everything we are going to receive an error.
04:09I will show you. It's going to saying here that we have an implicit coercion of a value
04:18and basically what it's saying is, is you are passing us a value
04:22and we don't know what it is. You are assuming it's bitmap data but there is no way to know. So what we are going
04:26to do is we are going to tell it that the value that's going to be returned
04:29by the getData call is going to be bitmap data.
04:33And that's something called Casting, so we can say we want this to be returned as bitmap data.
04:40Now this won't convert any data into a different format
04:44but rather it will just tell the Flash player expect bitmap data coming back from this function.
04:49If it doesn't end up returning a different type of data then it will throw an error.
04:53We can now test our application and see indeed that the error has gone away.
05:02We now if we wanted to can go back to Microsoft Paint and load it up, we can now take an image,
05:12for instance this image of Alcatraz Island we can add it to the clipboard.
05:17We can now drop it into Microsoft Paint by pasting.
05:21If we wanted to we could grab the Airbrush tool and this will go all over Alcatraz Island and then just say
05:29that we want to copy our image and then if we go back over to our Image Viewer and say paste there is our version
05:37that we have edited with our own artistic flair.
05:41So by not only being able to add data to a clipboard but also receiving data
05:46from the clipboard we have truly implemented two-way communication between our application and other applications
05:52that are running on the operating system.
Collapse this transcript
Using deferred rendering
00:00What if you created an application that gave up to the second stock values for the New York Stock Exchange and you wanted
00:07users to be able to copy stock values from your application into a spreadsheet application. Chances are that between
00:13the time they copied the information and then pasted it in their spreadsheet, the data would have changed.
00:18Deferred rendering inside of AIR allows you to define the data for the clipboard, not when it was copied, but rather when
00:25it was pasted. In this way the user of the stock prices application could ensure that the data that is passed would at least
00:32be to the second accurate. Deferred rendering inside of AIR is accomplished by using the setDataHandler method of the
00:39Clipboard class.
00:40Now we can also apply this to our Image Viewer application.
00:44If we go to File
00:45and then Open,
00:47we're going to open the ImageViewer03 application that's found in the Chapter 3 folder in the exercise files.
00:54To illustrate this functionality I am going to test the application.
00:57If we go to Control and then Test Movie,
01:03and we select Alcatraz Island
01:05and we hit Copy,
01:06and we then select Big Ben
01:09and we bring out Microsoft Paint,
01:11and we paste
01:12you'll notice that Alcatraz Island is the one that was added to the clipboard. And even though it's not the one currently
01:18selected, it's the one that was added when the setData method of the clipboard was called.
01:24So I'm going to go ahead and delete this from Microsoft Paint.
01:28Then I am going to minimize that for the moment. We are going to go in now
01:32and we are going to add one more button to our Stage. So we can go to the Window
01:36and then go to Components
01:38and then we are going to add one more button.
01:41And we are going to give this one
01:42a label
01:43of Copy Later.
01:47And again,
01:48labels can be accessed under the Parameters tab,
01:52and we are going to give this one an instance of copyLaterButton.
01:58We now can bring it a little closer
02:00to our other buttons we're going to select all three buttons. We're going to align them in the center and then we're going to space them evenly.
02:07You can now close the Components window.
02:09Now that we have created our Copy Later button and have given it an instance name we can now move to our ActionScript.
02:16So I am going to select the Actions layer
02:18and then go to Window
02:20and then Actions.
02:22Now the first thing we're going to need to do is we're going to need to add an Event Listener for the Copy Later button.
02:27So under our other addEventListeners we are going to say copyLaterButton.addEventListener
02:36and we are going to listen for a MouseEvent.Click
02:39and we are going to create a method called OnCopy
02:44LaterClick.
02:47Now we are going to go below all our other event handlers and we are going to create this method.
02:55onCopyLaterClick and it's going to receive an event that will be a mouse event but it's not going to return anything.
03:08So we can set the return type equal to void. Now as I stated at the beginning of this video the setDataHandler
03:14method of the Clipboard class allows us to do deferred rendering. So we are going to say Clipboard
03:20.generalClipboard, which returns a reference to the operating system clipboard,
03:25and then we are going to call the setDataHander method.
03:30And the first parameter that it's going to want is it's going to want to know what format this data is going to be in.
03:36And we are going to use ClipboardFormats
03:39.Bitmap_Format
03:43and notice it's going to want a function that's going to actually return the bitmap data of the currently selected item in the tile list.
03:51Well the convenient thing for us is we actually have already created that method. The method that we created in a
03:57previous video was renderBitmapData. It took the currently selected item from the UILoader and returned
04:04the bitmap data.
04:06So we actually can pass that in as the second parameter, renderBitmapData,
04:14and that we can close that call, we can save our application
04:18and now we can test it.
04:19If we close our Actions window and we go to Control and then Test Movie
04:27and we select Alcatraz Island
04:29and we hit Copy Later. And then we open up Microsoft Paint.
04:34We select Big Ben and then we paste.
04:37We'll notice that now Big Ben has been copied as opposed to Alcatraz Island. Even though Alcatraz Island was selected
04:44when the Copy Later button was clicked,
04:46the renderBitmapData method is not called until the data is actually pasted. And this is what enables us to give
04:53accurate bitmap data of the item that's currently selected.
04:58Now there are many different uses of deferred rendering but it can be especially useful when the data that you are placing on
05:03the clipboard needs to be calculated and could utilize a lot of system resources. In this way your application wouldn't need to do
05:10the difficult work until the data is needed.
05:13So just to review, we have been able to not only set data on the clipboard, get data from the clipboard, but also use deferred
05:21rendering to work with clipboard data inside of AIR.
Collapse this transcript
4. Supporting Drag-and-Drop Functionality
Understanding drag-and-drop operations
00:00Another level of operating system integration provided by Adobe AIR is the ability to support drag-and-drop gestures
00:06into and out of your application.
00:08Just as with the clipboard, data that is dragged out of an application exists in different formats.
00:13Applications can be configured to accept
00:15or reject a drag-in gesture based on the data format.
00:18To illustrate this, I have a folder.
00:20Inside of it are different images.
00:22I'm going to also open up a copy of Microsoft Word.
00:26Now, from my folder of the images, I can take one of my images and actually drag it onto Microsoft Word.
00:32You can see if the cursor changes and this change indicates that it will accept this drag-in data.
00:37I can then let go the mouse.
00:39You can see that the image has been added to the document in Microsoft Word.
00:43Now, from here, I can also drag this data out to another application.
00:47I've opened up Internet Explorer,
00:49and we can see that if I try to drag this,
00:52it says it will not let us drag this data in.
00:55So, an application can also be configured to not accept certain kinds of data.
00:59But I also have WordPad open and I can choose now if I wanted to drag and you can see that the cursor will change indicating
01:05that yes, this application will accept this drag-in data.
01:09Now, you can see that there are many similarities between clipboard support and drag-and-drop support inside of AIR.
01:13Actually, they both use the Clipboard class to accomplish this.
01:17Now, if you can leverage drag-and-drop, you can create a user experience that is very similar to a traditional desktop application.
Collapse this transcript
Supporting a drag operation
00:00Now, what we are going to want to do is we are going to want to take an existing application and actually let it share its data with other
00:05applications by using a drag-out gesture.
00:08Anytime you want to do a drag-in or drag-out gesture, you're going to be working with one class within AIR, the NativeDragManager,
00:15and specifically to begin a drag operation, you are going to use the doDrag method of this class and any interactive
00:21object on this Stage can be used as a drag object.
00:24We are going to go ahead and add this to an existing application.
00:27So, if we go under File and then Open,
00:29I'm going to open the Image Viewer 01 file which is in the Chapter 4 folder of the exercise files.
00:35Now, I am going to go ahead and test this movie.
00:37If we go to Control and Test Movie,
00:40we'll then see that our application has been loaded
00:42and we can see that if we click on any of these smaller items, it brings up the full size image above.
00:47Now, what we want to be able to do is actually grab this image and be able to drag it into other applications.
00:53So to accomplish that, we are going to be using the NativeDragManager.dodrag method.
00:58So, let's open the Actions panel.
01:00I'm going to highlight the Actions layer
01:01and then go to Window
01:03and then Actions.
01:04Now, the first thing we'll need to do is actually import the NativeDragManager class.
01:08This can be accomplished by going import flash.,
01:12and then we are going to go to desktop.NativeDragManager.
01:17Now that we have imported that class,
01:19we need to add an event listener to our UI Loader that loads the full size image.
01:23So, go down to where we have the event listeners and we are just going to add a new one.
01:27Now, the instance name of the UI Loader is image loader,
01:30IMG Loader.
01:31So we will say imgLoader.addEventListener
01:35and it's going to listen for the MouseEvent.mouseDown
01:40because we wanted to actually register when a user pushes the mouse down on the item so that we can actually drag it from
01:46that point on. And we will call the response method onLoaderMouseDown.
01:52Now, we are going to go ahead and add that method. So we scroll down to our EventHandler section and just add in one more method.
01:58function onLoader mouseDown.
02:03and it's going to receive an event which will be of type Mouse Event,
02:07return type on this is going to be void,
02:09because the method's not going to return anything.
02:12Now, the first item that we are going to want to accomplish within this method
02:15is we are actually going to create a new instance of the Clipboard class.
02:18No, we haven't done this previously because we've been working with the operating system clipboard which can be found in
02:23Clipboard.generalClipboard.
02:25In this case, we are actually going to pass an instance of the Clipboard class to the doDrag method.
02:30So we will say var clipboard
02:32will be of type Clipboard
02:35is equal to a new Clipboard.
02:38Now, we're also going to want to get the bitmap data of the current image that's actually inside of the image loader.
02:44Now, we have already created a method to do this. This is actually created in a previous video,
02:48and you can see the function renderBitmapData
02:51and this is just going to return the bitmap data of the currently selected image in the UI Loader.
02:55So we are going to say var
02:57BitmapData
03:00and that's going to be equal to the function
03:02renderBitmapData.
03:06So now we've retrieved the bitmap data as well.
03:08We're actually going to add that bitmap data to the clipboard. So we'll say clipboard.
03:12Notice in this instance, I am using a lower case 'c' for clipboard because I am referring here to a clipboard variable that we
03:17created at the beginning of this function.
03:19And we will say clipboard.setData
03:23and then we will use the ClipboardFormats
03:26and we'll useBitmap_Format
03:29and then we will actually pass in the bitmap data.
03:32Now that we've added to this instance of the Clipboard class that we have created,
03:36we now can pass it into the NativeDragManager.doDrag method.
03:42Now, notice here that we didn't have to create an instance of the NativeDragManager class.
03:45The NativeManager.doDrag method is a static method which means it can be called without instantiating the class.
03:52The first thing we are going to need to pass in is the Drag Initiator. In this case, that's going to be our image loader.
03:58Then, we'll need to actually pass in the clipboard that was created. Ours is just named clipboard.
04:03And finally, for us, we are going to need to pass the bitmap data that we wanted to render when the user begins the drag method and we
04:09have already created that with the BitmapData.
04:12Now, we have finished our method and we can actually go and test our application to see if it functions the way that we'd like.
04:17I'm going to close the Actions panel
04:18and I am going to go under Control and then Test Movie.
04:22Now, to test this, I am also going to open up a copy of Microsoft Word to run in the background.
04:28I am going to load up an image,
04:30such as Alcatraz Island,
04:31and then I am going to grab our image and actually drag and you can see the bitmap data that it's using as we drag.
04:37We can see here also that the cursor has changed saying that we can't drop this data here because we have not actually
04:43configured our application to receive dropped data,
04:46but if we drag it over to Word, you can see that the icon changes on the cursor and we can now drop the image in, and we've
04:52actually dragged the data out of our application.
04:54The NativeDragManager gives you quite a bit of power within your application.
04:58By using the doDrag method, you can now take data that's in your application and make it easily accessible to other
05:04applications simply by dragging the data from one application to another.
Collapse this transcript
Accepting dropped data
00:00Now, that you have created an application that can actually drag out data to be used in other application,
00:05you are probably going to want to create an application that allows you to drag data into it,
00:09but there is one thing to understand first: most applications deal with specific types of data.
00:14For example, in the Image Viewer, the application deals with bitmap and file data. It doesn't deal with text or URL data.
00:21Because of this you will want to limit what data can be dragged into the application.
00:26This can be accomplished by responding to the NativedragEnter and NativedragOver events.
00:31Once the application decides that a piece of data is appropriate,
00:34you can call the NativeDragManager.acceptDragDrop method.
00:38So, let's actually implement this.
00:40I am going to go to File and then Open and I am going to open the ImageViewerO2 file inside
00:45of the Chapter 4 folder for the exercise files.
00:49Now to implement this, we are going to go to the Actions layer, so click on the Actions layer and then I am going
00:53to go to Window and then Actions and the first thing we are going to need to do is we are going to actually need
00:58to import two new classes that we haven't used before.
01:01The first of these is going to be flash.desktop.ClipboardTransferMode
01:09and we will discuss what this particular class is and how it's used in a moment.
01:13We are also going to need to import the flash.filesystem.File class.
01:18So, now that we have imported our classes, we actually can add our event listeners to your UILoader.
01:24So if we scroll down to where the event listeners are, we are going to actually add two new ones.
01:29First we are going to want to response to the NativeDragEvent.
01:36and we are going to look for NativeDragEnter.
01:40Now, this is the event that's going to be dispatched whenever someone drags data over the application
01:45and the method that we are going to use to respond to that is going to be onDragEnter.
01:50Now, we are going to add one more. This one is going to be for NativeDragEvent.NativeDragDrop
02:05and then we are going to respond to that with the method onDragDrop.
02:08So, now that we have added these two event listeners, we actually can implement these methods.
02:13So, if we go to the Event Handler section of the code and scroll down below the others,
02:18we are going to create our two new methods.
02:19First, we are going to create the first method, onDragEnter, and that's going to receive an event,
02:27which will be a NativeDragEvent and it's not going to return anything,
02:32so we can set the return type equal to v oid.
02:35And inside of here, we are actually going to want to detect if this is the kind of data
02:39that we want our application to deal with.
02:41So we are going to want to use a method called hasFormat of the Clipboard class and the great thing
02:45about the NativeDragEvent is that it actually contains a reference to the current clipboard
02:49of the data that's being dragged over our application.
02:52So, we can say if event.clipboard.hasFormat and then we can pass in the format that we want.
03:00In this case, we are going want a new format that we haven't dealt with before, ClipboardFormats.File_List_Format
03:07and then say okay, if it has the data that we want, we will actually accept this drag operation and the way that we do
03:12that is to say NativeDragManager.acceptDragDrop.
03:17Now, we are going to need to pass in one parameter to this method and that's going
03:21to be the object that's actually allowed to accept the DragDrop.
03:24In this case, that's going to be Image Loader.
03:28Now, we have created this one method that actually looks at the data and accepts only the kind of data that we want.
03:33If any other type of data is passed over, the application will not allow it to be dropped.
03:37Now, we are going to create our onDragDrop event and it's also going to receive a NativeDragEvent.
03:48Now, what we are going to want to do inside of this method is we are actually going to want to extract the data
03:53from the clipboard and the file list format is going to return an array of files.
03:58So, we are going to create an array, we will just call it A and we are going to set that equal to event.clipboard
04:05because again this is a reference to the current clipboard of what's being dragged.
04:08And then we are going to want to get data.
04:11Now, we are going to want to tell it what format.
04:13In this case, we are going to use ClipboardsFormats. file_list_format and then we are going to need
04:19to pass one more item and this item tells the application that's sending us the data if we want a copy
04:24of the data or if we want the original thing.
04:27In this case, we are just going to want a copy, so we are going to use the class ClipboardTransferMode
04:32and we are going to want to use a clone only.
04:36So, now that we have actually grabbed the data, we actually can now make it into the type that it needs to be.
04:42If we would have run this code right now, it would throw an error saying, "You are trying to make this clipboard data
04:47into an array, but we don't know that that's an array."
04:49So, we actually can cast this data and say it's going to return an array, so that the compiler knows.
04:55Now, the next thing that we are going to need to do is we are going to want to create a new file.
04:59Now, we haven't yet dealt with the File class inside of AIR.
05:02The important thing to know is that an instance of the File class can represent either a file or a directory.
05:07In this case, it's going to reference a file.
05:09Since the file list returns an array of files, we are just going to take the first item off the list and we are going
05:14to tell the compiler that it's going to return a file, because arrays can contain many different types of data.
05:19This way our application knows exactly what type of data is in the array.
05:22Now, the last item that we will need to implement this is we want
05:26to set the Image Loader Source property equal to a property of our file object.
05:30Now, each file object contains a property called URL, which is a URL formatted reference to its path on the hard drive.
05:37This way the Image Loader can know where to go find the picture.
05:40So, if we save our application, close the Action panel, we can now test our movie.
05:44So, if we go to Control and then Test Movie, you can actually see that everything works as it did previously.
05:50We also have the capability to drag data out, but in addition I am going to open up a folder of some pictures.
05:56And just the sample pictures that come with Microsoft Vista, we now can go and drag any of these images
06:03into our application and we now can see it properly displayed on the screen.
06:09So our application now has the ability, not only to drag data out but also to drag specific files
06:14into the application and have them previewed in real time, truly creating two-way communication
06:19between the operating system, other applications and our application.
Collapse this transcript
5. Using the File System
Introducing file system support
00:00One of the main differences between AIR and a traditional web-based Flash movie is the File System Support.
00:05In a Flash movie, you can select a file from the user's hard drive and upload it through the FileReference class.
00:10In AIR, you have the capability to create, edit, move, and copy files in directories on the user's hard drive.
00:17There are three main classes that you will use on a regular basis in AIR,
00:20when you are working with the File System Support.
00:23These classes are first, the File class.
00:25Now, this contains a reference to an object in the file system, so it can be either a file or directory.
00:30It also contains static properties to give information about the file system.
00:34Now, this class will be used quite often whenever you are working with the actual file system and again,
00:39you will have an instance of this class for each and every file reference that you are working with.
00:43The next class is a FileMode class.
00:44Now, it's going to define the different modes that can be used for opening a file read, write, append, and update.
00:50So, every time you open a file, you are going to be opening it in one of these four modes.
00:55The last class that you are going to be using on a regular basis is the FileStream class.
00:59Now, this class is able to open files, read data from them and write data to them.
01:03Now, within AIR, the File System Support enables you to do a lot of these actions such as copy a file or directory,
01:09delete a file or directory, send a file or directory to the trash, move a file or directory,
01:15as well as getting a list of files, within a directory.
01:17So, you can see that any basic file action that can be performed
01:20within the operating system can be done within AIR as well.
01:23The File class contains static references to specific directories that work across different operating systems.
01:29This is extremely important because one of the great things about AIR is that it can work on multiple platforms,
01:35it can work on Windows, it can work on Mac.
01:37Now, if you hard code a directory such as c:documentsandsettingdavidtucker that's not going to work
01:44on a Mac, where it might work on Windows machine.
01:47So the File class gives you the static references, so that you can reference a directory by these names instead
01:53of actually by their actual hard coded name.
01:55First File.applicationDirectory, now this directory is a directory
02:00that actually houses the core bits of your application.
02:02For example, the compiled SWF file for your AIR application will actually reside in this directory.
02:08The applicationStorageDirectory is a directory that actually contains any extra assets
02:12that you might have for your application.
02:14Both of these contain shortcuts that enable you when you are typing out the path
02:18to actually get to the directory using less text.
02:21The first uses app:/, the second one uses appstorage:/.
02:27These options just give you a quicker and more concise way to get to the specific directories,
02:31wherever the user happens to install your application.
02:34The next one is File.desktopDirectory, as well as File.documentsDirectory and file.userDirectory.
02:41These are operating system specific directories that the user can use to store specific pieces of information
02:46and now you can reference these painlessly and have it work on every operating system that AIR can run on.
02:52Finally a warning, unlike with the Flash movie, you can perform real file system actions with AIR,
02:58so you need to be very cautious when working with the file system in AIR.
03:01If you choose to delete a file, it's really deleted, if you choose to move it
03:04to the trash, it's really moved to the trash.
03:06The same thing with moving files, so just be sure and be cautious with this new power that you have
03:11to develop powerful desktop applications.
Collapse this transcript
Working asynchronously vs. synchronously
00:00AIR provides two different methods for interacting with the file system, synchronous and asynchronous.
00:05Now, these are also the same two different methods that exist for working with the embedded SQL database
00:10that will be covered later in the series.
00:11Now, these two methods work very differently and each method has its own place.
00:15First, let's look at some examples to compare synchronous and asynchronous programming.
00:20In this first example, we are going to be using the FileStream class to open a file
00:24and while we haven't discussed this thoroughly, you can see that we've created instance of the FileStream, we open it,
00:29we extract data from it and then we close the FileStream.
00:33So, in reality, in those four lines of code, we have been able to accomplish all of that.
00:37Now, let's look at the asynchronous example.
00:40In the asynchronous, we created a new instance of the FileStream.
00:43We added an event listener for the Event.COMPLETE event.
00:46Then we open the FileStream.
00:48We actually respond to the Event.COMPLETE method and then inside of that method, we actually read the data
00:53out of the file and then close the FileStream.
00:56Each of these different methods has pros and cons.
00:59With synchronous, there is less code to accomplish file operation, so you don't have to actually respond to events
01:05so you will know that when you enter a command, it actually will be completed before moving to the next command.
01:09The problem is that it can negatively impact the user experience.
01:13For example, if you are loading in a really small text file, nothing is going to happen, it will be fine,
01:18it will load it in quick enough that the user won't notice any problems.
01:21However, if you are loading in a video file that's 2GB in size, the user is going to have to wait
01:26and your application will be basically frozen while this action is taken.
01:30They won't be able to interact with your application at all during this time.
01:33And finally, it should only be used for smaller files because as we stated, anytime you work with larger files,
01:38you can negatively impact the user experience.
01:40Asynchronous works different however.
01:42First, it takes more code for basic file operations.
01:45So now, instead of just opening a FileStream, you have to add an event listener,
01:49open the FileStream and then respond to that event.
01:51It does not affect the experience of the end-user.
01:55You open up the door for the user to still interact with your application even
01:58if a very intense file system action is taking place.
02:02Finally, it can be used with files of any size.
02:05Now, the truth is synchronous code is very easy to read and understand.
02:08And if you can learn to develop asynchronously, developing synchronously in situations
02:13where it can be useful will be very easy.
02:15So, all of the code samples that we will be doing for the series will be done in the asynchronous mode.
02:20This way, you can develop your applications that it won't negatively impact the user experience.
02:25Synchronous programming certainly has its place.
02:27If you need to develop an application quickly for prototyping purposes,
02:30synchronous programming can work very well.
02:33Or if you are in a situation where you know that you are only going to be dealing with very small files
02:36and there is not even a remote possibility you will be dealing with larger ones,
02:40you can look at synchronous programming to save time.
02:42However, in most situations, especially with applications where the user can control what type of data is loaded
02:47into the application, we'll probably want to use asynchronous programming so you don't run into some
02:52of the problems that I mentioned earlier.
Collapse this transcript
Browsing for files and directories
00:00So up to this point, we have developed an application that actually pulls in the names and locations of images
00:05through an XML file, but ideally we would like for the user to be able to select files
00:10and directories off of their own hard drive to view.
00:12Now the File class contains many methods that allow the application to prompt the end user
00:17to select a file or directory from their hard drive.
00:21This would be needed when the user needed to select the location to save a file,
00:24to select a directory of pictures to browse or to select files to open.
00:27So let's go ahead and implement that inside of our application.
00:30First, we are going to go to File and then Open and we are going to select the ImageViewer01 file
00:37in the Chapter 05 folder of the exercise files.
00:39Now that we have opened our application, let's look at this Stage.
00:42Since we are adding in a new piece of functionality, we are going to need to add in another button.
00:46In this case, we are going to want to create a button that has a label of Browse that then the user can click
00:51and that will be prompted for a directory of pictures.
00:54So the first thing, we will need to do is unlock the Buttons layer and then we are going to open the Components window.
00:59We now can drag a button from the Components window on to the Stage and we are going
01:03to give it a label by going under parameters of Browse.
01:06We are also going to give it an instance name of browseButton.
01:12Now we can select all of our buttons.
01:14We will align them to the center and we will be sure that they are evenly spaced.
01:19Now we can relock the Buttons layer and we can highlight our Actions layer and go under Window
01:23and then Actions to open the Actions panel.
01:26The first thing we are going to need to do is we are going to need to add an event listener for our Browse button,
01:30so we will say browseButton.addEventListener and we are going to want it to listen for the MouseEvent.CLICK event.
01:40And then we are going to have it respond with the method onBrowseClick.
01:47So now if we scroll down to our event handler section and go to the end of it,
01:51we are going to add one more event handler.
01:53So we will set a function onBrowseClick, we will receive an event of type MouseEvent and it's not going
02:02to return anything so we can leave the return type as void.
02:05Inside of this method, we are going to want to do a few things specifically.
02:08The first thing we are going to do is we are going to create an instance of the File class.
02:11So we will saay var file of type, File is going to be equal to a new File.
02:19The next thing we will need to do is we will need to add an event listener for this file
02:22because we are getting ready to ask the user to select a directory.
02:25When they do, it will actually dispatch a SELECT event and then this will fire another method.
02:30So in this case, we want to say file.addEventListener and we are going to listen for the Event.SELECT event.
02:37And then we will respond with the onDirectorySelect method that we will create shortly.
02:44Next we need to actually prompt the user, to accomplish this we simply need to say file.browseForDirectory
02:53and then we will tell the user we just want them to select pictures.
02:58Now if we save our application, if we attempted to run it at this point, it would through an error because we have not
03:03yet created our onDirectorySelect method.
03:05So I am going to go ahead and create a shell of this method that we actually will be implementing later.
03:10So we will say function onDirectorySelect and then we will say that it's going to receive an Event of type event.
03:20It's not going to return anything, so we can go ahead and leave the return type void.
03:23And since we are not yet implementing this functionality, I am going to leave myself a little to doonCopyClick note
03:27to remind myself to go back and add this functionality.
03:30So we will say ToDo Add Directory Listing.
03:35So now we can save our application and if we go under Control and then Test Movie,
03:42we can see here that our application works as it has before we can select a smaller image and see the larger image,
03:47but now we also have the Browse button. If we click the Browse button, it will prompt us for directory.
03:52We then can go and select a directory that we would like, but at this point when we click OK,
03:56nothing is going to happen because we haven't yet implemented this functionality.
03:59However in the course of this lesson, you have learned how to create an instance of the File class
04:04and use that to then prompt the user to select a directory.
04:07Now you are ready to actually respond to that event and display a listing of all the files within a given directory.
Collapse this transcript
Listing the contents of a directory
00:00Now that you have been able to prompt the user to select a directory on their hard drive,
00:04you are going to want to be able to respond to that by actually taking that directory and learning how
00:08to list all the files that are inside of it and also learning how to look at each of those and determining
00:13if it's a file, if it's a directory or even if it's a certain file type that you want to work with.
00:17So let's go ahead and implement that inside of an application.
00:20So I am going to go to File and then Open and then I am going to open the ImageViewer02 file inside
00:26of the Chapter 5 folder in the exercise files.
00:29So if I test the movie, I have got the ability here to select the Browse button, where we can select a directory
00:36from the hard drive, but if we click OK, nothing happens because we haven't yet implemented that method.
00:41So let's go ahead and close the application.
00:43Go to the Actions layer, go to Window and then go down to Actions.
00:47Now we are going to scroll down to the method that we didn't fully implement previously.
00:51Well now that we have gotten there, because I add it a ToDo tag that reminds us
00:54that we need to add the directory listing.
00:56So I will just highlight that comment and delete it.
00:58Now the first thing we are going to need to do is because we are going to want do display our images
01:03from this folder actually in the Tile List, we are going to want to remove the current items that are in the Tile List.
01:08So we will just say imgList.removeAll and that will remove all of the current items.
01:14Now we are going to want to get a reference to the directory that the user selected from the prompt.
01:19So we can say var and since this a file reference, we will just call it fileRef and it's actually of type File
01:26and we are going to actually set that equal to Event.TARGET.
01:30Now this is another situation where we are going to have to use casting.
01:33Event.TARGET can contain a lot of different types of data,
01:36we need to reassure the compiler that we are passing it a file.
01:39So we will say Event.TARGET as File.
01:43Next we are going to need to actually get a listing of all of the files within the directory.
01:47It's going to return an array.
01:48So let's go ahead and create an array to use.
01:50We will say var dirListing, which is a short for Directory Listing, of type Array. It's going to be equal to-
01:58and this is a new method that we are going to use.
01:59We are going to get the file reference and again this is a reference to that directory that the user selected
02:04and then we are going to use the method getDirectoryListing.
02:10Now we actually have an array of each of these items.
02:13Now we actually need to go in and create a listing for each of these arrays.
02:17So we also need to go in and take a peek at each of these and be sure
02:20that we are actually looking at an image, which we want to look at.
02:23So we are going to be using the for each statement.
02:25We will say for each, and then we need to say for each file, so we will say var file, in
02:31and then we need to pass in our array, DirListing.
02:36Now this way, this one statement, the for each statement will loop over each item in the directory listing.
02:41Inside of the for each statement, we can use the variable file to refer to the current item as it's looping through.
02:48Now if we want to add these to the Tile List, the first thing we are going to need
02:51to do is we are going to need to create a new object.
02:54But before we can actually create the object and give it the data,
02:56we want to be sure that we are working with a real file.
02:59So we need to actually examine it.
03:01So we are going to create an if statement.
03:02The first thing we are going to want to do is that we want to be sure
03:05that we are looking at a file and not a directory.
03:07Now the instance of the File class contains a property called isDirectory.
03:12If this is a directory it will return true.
03:14If it's not a directory, it will return false.
03:17In this instance, we only want it to return true if it's not a directory, so to do that we are just going
03:23to put an exclamation point in front of it and it will actually reverse whatever the result is.
03:28So in this case, if the file is a directory, it will return false, if it's not a directory, it will return true.
03:34We also want to check and be sure it's not symbolic link.
03:37Now some system support symbolic links and basically that's just where there is a file inside
03:42of the directory that's just a pointer to another file.
03:45We want to be sure we are not looking at any of those either.
03:47So there also is a property file.isSymbolicLink.
03:52Now we want to do the same thing here, we don't want it to be a symbolic link,
03:55so we want it to return true if it's not.
03:58To accomplish this, we are going to put another exclamation point in front of it.
04:01So now we have ensured that this is a kind of file that we want to be working with.
04:05So now we are going to create an object to actually insert into the Tile List.
04:09We will say var O is of type Object and that's equal to a new Object.
04:14Then we are going to want to actually fill in the data unlike with the XML where we had a separate image file
04:20for the thumbnail as well as for the larger version, in this case we are going to use the large image for both
04:25and actually just have it scale down the large image to fit into the thumbnail.
04:28So our data and source properties are both going to be the same.
04:31So we will say o.data is equal to file.nativePath.
04:36Now we haven't used this property before, but it actually returns the path of the file on the local hard drive.
04:42In the format, all files are expected to be for that operating system.
04:46We will actually look at this a little bit more in depth in the next video.
04:49But we are going to set o.data and o.source equal to file.nativePath.
04:55Now the last thing we are going to need to do is actually add this object to the Tile List.
05:01Since we have removed all the items that are in there before we can just call the addItem method
05:05and then we will add in our object.
05:09Now we can hit Save.
05:10So just to review, we have removed all the items from the Tile List, we have created a file reference that's
05:14of type file that points to the directory that the user selected.
05:17We have gotten all the files in the directory, in the directory listing then we have looped through each of them
05:22to ensure that they are not a directory or a symbolic link.
05:24Now we can actually test on moving.
05:26If we go to Control and then Test Movie, we now can select Browse and I happen to know
05:32that I have some pictures in my Pictures directory.
05:34I am going to go to the Edinburgh directory and then hit OK.
05:37Now it's going to throw an error, it's going to say loaded file is an unknown type.
05:42Now this actually is okay, because I also know that there are one or two files
05:45in this directory that aren't actually image files.
05:48We want to ensure that we are looking at the right kind of files, so let's go back to our application.
05:53If we look here, we have already checked to see if the file is a directory and a symbolic link, but now we want to check
05:59and be sure that we are looking at a file that has .jpg somewhere in the file name,
06:03that way we can sure that we are working with an actual JPEG file.
06:06So we will say and we also want to check file.nativePath because we said earlier it contains the native path
06:14for that specific file in the operating system and it's actually a string.
06:18Now one of the methods that you can use from the String class is Search.
06:22You can tell this to search for a string within the file name.
06:25So we will say we want to search for .jpg.
06:29Now if this actually finds .jpg in the file name, it's going to return a number
06:33that indicates where in the string this occurs.
06:35If it doesn't find .jpg then it's going to return negative one.
06:40So we just want to say, we want to be sure that this does not equal negative one.
06:44So now we can actually close that section, save it, now we can go back and launch our application again.
06:51We will say Control, Test Movie, now it brings back up our movie.
06:56We can now browse and go back down to my pictures directory and go to Edinburgh and click OK.
07:02And now no errors have been thrown and we can be sure
07:05that we are actually dealing with JPEG images, which we want to do.
07:08Now if you wanted to extend this application even further, you could actually have it check for other file name formats
07:13that you might want to support as well such as PNGs which the Flash player can load file.
07:17But in this case we have created an application that prompts the user to select a directory.
07:22We have then looped through all the files in that directory using the getDirectoryListing method then we have checked
07:27each of those files to be sure that it's not a directory, it's not a symbolic link
07:30and to be sure that it has .jpg in the file name.
07:33We will continue putting a lot of these other methods from the File class together to create an application
07:37that truly has great support for the file system.
Collapse this transcript
Using the File class properties
00:00Now that we are able to open a directory look at all of its contents and look at each of the files contained
00:05in that directory and determine some information about them such as
00:08if they are a directory or if they are a symbolic link.
00:10We are going to look at some other properties of the file class that will enable us to do some things more efficiently
00:15than we did in the previous movies as well as access some information
00:18about the file that we haven't actually accessed yet.
00:21So to accomplish this we are going to need to open the application.
00:24So if we go to File and we go to Open we are going to open ImageViewer03 in the Chapter 5 folder of the exercise files.
00:31Now we are going to go to the Actions panel so let's click on the Actions later and then go to Window and then Actions
00:37and we are going to place what's called a breakpoint in our application.
00:41This needs to be done at a very specific point for us to be able to view the data that we need to view so scroll
00:45down to the onDirectorySelect method and then we are going
00:49to place a breakpoint directly here to next to where it says var o Object.
00:54Now what this will do is when we launch our application in Debug mode
00:58when the application reaches this point it will stop
01:01and it will let us inspect the current properties within this method.
01:05We are going to take a closer look at the file class and its properties so let's go to Debug and then Debug Movie.
01:13It will take a second for our application to load but once it does it will look just like it did before.
01:17We are going to go to browse and then I am going to go under David Tucker and then Pictures.
01:22You can pick a directory that you have on your system if you would
01:24like to use another directory as long as it contains some JPEGs.
01:26Let's click on Edinburgh, click OK and you will notice in the background things have kind of changed.
01:32First the notification is telling us the Flash has something it wants us to see so if we click on the taskbar
01:37and go to Flash or if you are on Mac you can actually click on the dock.
01:41We are then going to move in and we are going to look at this instance of file.
01:44If we look at the code on the right this is were we actually looping through each of the files.
01:49And you can see for each file, so we are actually looking at the first instance of the file.
01:54So if we move this over and we go to the Variables window we can look at this instance of File and see its properties.
02:00If I press the plus sign next to it, it will expand and show me all the information that it has.
02:05There is a couple of things I want to note specifically,
02:07if you look at the field named nativePath you can see the native path of the application that begins with c:/users.
02:15This is going to be the native path for that specific operating system so sometimes when you are working
02:20with other applications you are going to need to be able to access this data.
02:23In addition we also have a URL property and if we look at that it starts
02:28with a file:/// before it moves on to the native path .
02:31But also in the place of a space between David and Tucker it's replaced it with percent 20.
02:36So this is basically a URL encoded version of a file name that can be used also in communicating
02:42with other applications or passing this information through a component within your own application.
02:46There are two other properties I want to note. First if you look at Type you can see
02:51that this is a JPEG file. It says .jpg. We can use this in our application
02:56so we don't have to use the Search method of the string.
02:58This will shorten the code that we have to write.
03:00In addition you can see that there is also a Name property, 1.jpeg.
03:04That we can then use for the captions within our application.
03:08By using these properties we can decrease some code in some areas
03:11and we also can gain some functionality in others, so let's exit Debug mode.
03:15To accomplish this we are going to click the Red X in the Debug console.
03:18Now that we are back to our application we are going to first go and we are going
03:23to add the name as the caption for each image.
03:26So we will say o.caption = file.name.
03:32In addition we are going to go to the section where we were searching for jpeg and we are going to add
03:37in an equality statement, we will say file.type = .Jpg this way we can check to see if it is indeed a jpeg file
03:48without having as much code as we had previously.
03:52Now we can save our application we can take our breakpoint off and we can go to Control and then Test Movie.
04:00Now if we browse and just go to a directory of pictures
04:03and then click OK we will notice a couple of things have changed.
04:07First of all it did indeed load only the jpegs.
04:10We don't have error saying that there is a file that isn't a jpeg within this directory.
04:14In addition we can see that the names of our images have been added as the captions below.
04:18So in a lot of ways this is functioning just like it did in the beginning
04:21when we were loading all the images in from XML.
04:24By using these file properties you can learn how to better access your files
04:27as well as how to obtain information about them.
04:29There are many other properties that we won't be using in this application and we can determine things such as
04:34when the file is last modified and when it was created and this information can prove very useful
04:38as you are creating full featured applications that utilize a file system support within AIR.
Collapse this transcript
Performing file system actions
00:00Now that we have created an application it allows us to look through a directory,
00:03see all the files and even find properties of those files.
00:07We now want to be able to perform basic file actions on these files.
00:10Now this can all be accomplished with the file class inside of AIR
00:13and gives you the developer the ability to create very powerful applications.
00:17So let's go ahead and add that to our Image Viewer application.
00:20First let's go under File and then Open and then select ImageViewer04
00:24in the Chapter 5 folder of the exercise files and then hit Open.
00:28We are going to stay on the Stage for a second and add one more item to the Stage.
00:32To do that we are also going to need to another layer and we are going to call this layer ComboBox.
00:38We are now going to go to the Components window under Window and then Components and then we are going to drag
00:43out an instance of, you guessed it the ComboBox.
00:46We now can close the Components window.
00:47I will move this around so it lands up on the Stage and we will give window an instance name of fileActionBox.
00:54Now we are also going to want to adjust some of its parameters.
00:57So if we hit the Parameters tab we are going to want to be sure that the Editable Property is set
01:02to False then we are going to select the dataProvider property and then we are going
01:05to hit the magnifying glass on the right.
01:07Now we can actually add values to this ComboBox.
01:10First we are going to give it a default label of File Actions.
01:15Then we are going to give the first label the value of Copy file,
01:20then we are going to add another one then we are going to give it a value of move to trash.
01:26Then we are going to add one more and give it the label of Delete File.
01:29Now we don't need to worry about the Data Properties for any of these items then we will click OK.
01:36Now we actually are ready to move in and begin working with ActionScript
01:39so let's lock our ComboBox layer then select the Actions layer and go to Window and then Actions.
01:45The first thing we are going to need to do is add an event listener for our fileActionBox so if we scroll
01:50down to our Event Listener section we can then move to the end and add a new one
01:54and it will be fileActionBox.addEventListener and then in here it every time the value
02:00of a ComboBox is changed it dispatches the changed event so we will be looking for Event.CHANGE and we will respond
02:06to that with the onFileActionBox method so let's go ahead and add that method.
02:13Let's scroll down to our Event Handler section and we are going
02:17to create a new function which will be onFileActionBox.
02:22Let's go into receive an event of type Event and it's not going to return anything
02:26so we can leave the return type equal to void.
02:29Now here inside of this method before we can perform any file actions we are going to be need to be sure
02:33that one thing is true if there is actually an item selected on the Tile List so to accomplish that we will say
02:40if imglist.selectedItem so if there is a value in that then we will proceed
02:47but if not we are just not going to do anything.
02:50So now all of the logic that will exist for us moving our file to the trash or deleting it or copying it is all going
02:55to be contained inside of this if statement.
02:57And we are going to determine which value is currently selected on the ComboBox by using a switch statement.
03:02So we will say switch and we will switch actually on the statement fileActionBox.selectedItem.label so depending
03:13on what this value is we actually do different things.
03:16We can now setup our cases for each of the actions.
03:19First we have Copy File and then we can go in and just add a comment reminding us to come back
03:26and implement the copy file functionality then we can add a Break statement.
03:30Now each of these will need to have a break statement.
03:33If they don't you are on the possibility of trying to commit multiple actions on a single file.
03:38The next one will be case. Say Delete File, add the break statement and then finally we will say Move to Trash.
03:56And then we will add our break statement.
03:59Now we are going to need one property to each of the items in the tile list to make this possible so we will scroll
04:05up to our onDirectorySelect method and we will add the property file to the object.
04:10Now we are just going to set this equal to the current file so this property will contain an instance of the file class
04:16for each of the images that's being displayed.
04:19Now we can scroll down and actual begin working with implementing these pieces of functionality.
04:24So first we will actually look at implementing the copy functionality so the first thing we are going to need to do
04:29to copy our file is we are going to need to create an instance of the File class and this is
04:33because we are actually going to prompt the user with where we want them to save this copied file.
04:38So we will first say var f of type File is equal to new File.
04:43Now since we are going to actually prompt the user we need to be sure that we add an event listener
04:48which will be f.add ventListener and when I select the location
04:52to save this copied file it will actually dispatch the select event so we want to listen
04:56for Event.SELECT then we will respond to it with the onCopySelect method.
05:02Finally to actually ask the user where they want to save the file we can call the f.browseForSave method then we need
05:11to give it a name and in this case we will say Copy File To
05:15that way the user will know why again they are having to enter the name of the file.
05:18Finally the last thing we are going to want to do is actually set the fileActionBox back to its default value
05:24so we will say fileActionBox.selectedIndex and we will just set that equal to 0 and that will set it back
05:33to the very first value in its data provider.
05:36Now we need to create our onCopySelect method now this method will receive an event
05:45of type Event and the return type will be void.
05:49Now inside of this method we are going to need to actually pull the file reference out of the event
05:54so we will say var file of type File will be equal to and we are going to set it equal to Event.TARGET
06:03and that will actually get the value of the file.
06:05But again because the Event.Target can contain a lot of different values we are going to want
06:10to specifically tell the application that it contains a file.
06:13This is called casting.
06:15Now the next thing we are going to need to do is actually perform the copy
06:18so in this case we will say imglist.selectedItem.file, and then we will say Copy to Async.
06:28Again we are going to be asynchronous methods.
06:30Now if we actually needed anything to happen when this file was done copying then we would need to add an event listener
06:36but in this case we can actually just tell it to copy and then the user can go back later if they want
06:40to actually see the location where that file has been saved.
06:43Then we also need to pass into this method where we wanted to copy the file to.
06:46We have already prompted the user for this so we can just pass in the file reference
06:50that was created when they actually selected the file.
06:53Now we need to actually implement the delete and move to trash options so let's move to the delete option.
06:58We can go and highlight the comment and then delete it.
07:01In this case we are going to need to respond to the complete event of the deleteFileAsync method.
07:07So we are going to first say imglist.selecteditem.file.addEventListener.
07:15This will actually let us listen for when the File Delete command is been completed so we wanted to listen
07:20for Event.COMPLETE and then we will respond with onFileActionComplete.
07:28Now we can actually delete our file imglist.selectedItem.file again this is a reference
07:36to the current file of the item that is selected and then we will say deleteFileAsync.
07:42We don't need to pass any parameters into it.
07:44It will just delete the file that have references.
07:46And the last thing that we need to do in this part of the method is actually to set the fileActionBox back
07:51to its default value that can be accomplished by just copying and pasting that in.
07:56Now we are going to need to actually write the onFileActionComplete method so we will scroll
08:01down below our onCopySelect method and create onFileActionComplete and it will receive an event
08:10of type Event that's not going to return anything so we can leave the return type as void.
08:14Now inside of here we are only going to need to do one thing since we are actually deleting an item that's
08:19in our tile list we are going to want to actually remove that item from the list so we can say imglist.removeItem
08:25and then from here we are going to remove imgList.selectedItem.
08:33Now we can scroll back up and implement our move to trash.
08:36We actually can copy most of the code from the delete file section and paste it in the move to trash section.
08:43The only thing that we have to be changed is instead of delete to file aysnc we are just going to say move
08:49to trash async and everything else can remain the same, even the same method can respond to the Event.COMPLETE event.
08:58Now we have implemented all of the functionality for our file action support
09:01so now we can test our application and see if it works.
09:04So I am going to close the Actions panel and we are going to go to Control and Test Movie.
09:08Now this isn't going to work with any of the items that are loaded in by default through the XML.
09:14We are actually going to have browse through a directory.
09:16So we will say Browse and go to David Tucker and then pictures
09:20and then we will actually click on this event of folder.
09:22You can choose any folder on your hard drive that contains images.
09:25Now here is a picture of a fountain in number 2 and let's just say for some reason I just don't like this picture.
09:30I actually can now go to File Actions and move this file to the trash.
09:34You can see that when that is completed it actually has been removed from the list.
09:37In the same way let's say I want to save a copy of this particular picture.
09:41Well I can easily go to File Actions and say Copy File.
09:45It will then prompt me for where I want to save it I will just call this one copy.jpg.
09:50Once I hit Save it will actually perform the copy.
09:53If I now go to the desktop I can see that indeed it has copied over my file and I have a copy
09:58of the original right here on my desktop so with this functionality you can easily include some
10:03of these core file actions within your application and now you are ready to move on to actually working with writing
10:08and receiving data from files on the local hard drive.
Collapse this transcript
Writing data to a file
00:00There will be many times when you want to actually store data on the user's local computer.
00:04As we discussed earlier, one of the ways that you can do that is
00:07to actually store data inside of a file on the user's computer.
00:10Obviously, the File System Support within there gives you this capability
00:13and we are going to actually use this in our application.
00:16We want to actually allow the user to set the default directory that will actually be displayed
00:21when they open up our Image Viewer application.
00:23This way we can get rid of the old XML file that we use to deal with, in this way it entirely is linked
00:28to the user's file system and because of that it can then be customized for each individual user's needs.
00:34So, now let's go to the File menu and open up our application.
00:37We will go to Open and we will open up ImageViewer06, in the Chapter 5 folder in the exercise files.
00:44Now, if we look at the Stage, we have 4 buttons at the bottom.
00:48In this case, I am going to choose to actually rename a Copy Layer button
00:52and make it our Set Default button, so let's unlock the Buttons layer.
00:56We now can just select the Copy Layer button, we are going to change the instance name to make it setDefaultButton,
01:02we are also going to change the label to Set Default.
01:07Now, because we changed the instance name, we are going need to be sure that we delete any old references
01:12to the Copy Layer button inside of our ActionScript, so let's go ahead and lock the Buttons layer,
01:16highlight the Actions layer and then go to Window and then Actions.
01:20Let's scroll down to the section, where we have our event listeners, and you can see there,
01:24there is one reference to our Copy Layer button, we can highlight that and then delete it.
01:28In addition, that means there is also a method we won't need anymore,
01:32the onCopyLayerClick method, we can go ahead and delete that.
01:36Now, we are ready to add the event listener for our Set Default button.
01:39So, we can say setDefaultButton.addEventListener and we are going to be listening for the MouseEvent.CLICK event
01:51and we are going to call the onSetDefault method.
01:55Before we add that, we are going to need to add a property that is accessible to the entire application
02:01and we are going to actually store the value of the current directory,
02:04when the user selects a new directory inside of that property.
02:07So let's go to the top directly under our Import Statements
02:11and we will just create a property var currentDirectory of type File.
02:18We will now need to update our onDirectorySelect method,
02:21so that every time the user selects a new directory it updates the currentDirectory property.
02:26So, we will scroll down to our onDirectorySelect method and inside of here, we can totally do away with the fileRef,
02:33the variable that we created to hold the instance of the file and instead assign currentDirectory.
02:39We also will have to do it on the next line,
02:41so instead of saying fileRef.getDirectoryListing we can say currentDirectory.getDirectoryListing.
02:48Now, we actually can begin updating our onSetDefault method.
02:51So we will add a new event listener, method onSetDefault, it will receive an event of type Mouse Event and it's not going
03:02to return anything so can need the return type void.
03:04The first thing we are going to need to do is to create an instance of a FileStream class.
03:09Now, the FileStream class is used anytime you need to stream data to or stream data from a file on the user's hard drive.
03:16So, in this case we will say var and we will just call it fs, of type FileStream, is equal to a new FileStream.
03:24Now, we have not yet imported the FileStream class, so we will need to do that.
03:28But in addition, we are also going to need the FileMode class, so instead of actually having align for each
03:33of those items, we can actually go back up to our imports and we are going
03:37to import everything in the flash.filesystem package.
03:41Now, we can scroll back down to our onSetDefault method.
03:44Now that we have created the instance of our FileStream, we can go ahead and add an event listener.
03:51Since, we will be working with the FileStream asynchronously,
03:54we want to listen for the Event.COMPLETE event, this will tell us when it is actually completed writing data
04:00to our file and we will respond to that with the onFileStreamComplete method.
04:05As I said, we are going to be opening an asynchronous connection, so we will say fs.openAsync
04:11and now we need to tell it what file we wanted to open.
04:14Now, we are going to create a new reference to a file, so we will say new File.
04:19If we pass in a path that already exists then we will use that file.
04:24However, if we pass in a new file name, that file name will be created.
04:27As I stated in the beginning of this chapter, we can use certain reference that will point
04:32to specific directories for our application.
04:34We are going to use one of these now.
04:35We are going to say AppStorage, which is the default storage directory for our application ":/"
04:41and now we actually can put in the name of our file.
04:45In our case, it will be prefs.xml and we will use this to store application preferences.
04:51Now, we can close that and we need to now tell the FileStream what mode we want to open our file in.
04:57In this case, we are going to open our file in file in FileMode.WRITE.
05:01Now, this will actually write data to the file, if the file already contains data, it will overwrite it.
05:07If we wanted to continue writing a file that already existed, we will use the FileMode.APPEND.
05:12If you are working with a file and you want to be able to not only append data, but also go back and write data then
05:18in those cases you are going to use the FileMode.UPDATE.
05:21Now, that we have opened an asynchronous connection to our file, we are going want to actually figure
05:25out what data we are going to want to store inside of our file.
05:27So, we are going to create a variable, fileData and that's going to be a string.
05:33And in this case, we are going to actually make the string contain some XML data, so we will actually want
05:38to go ahead and put it our XML header first.
05:40So, we will say XML version = 1.0, then we want to say encoding equals UTF-8.
05:50If you notice here, I used single quotes on the outside,
05:54because I had to use double quotes actually inside of the string.
05:57Next, we are going to want to actually store the information about our preferences, so we will say fileData +=,
06:03which will continue what we already put inside a fileData.
06:06We are going to want to now say prefs and that will be our outer tag and then we will have an inner tag
06:10that will be defaultDirectory and then we are going to want to actually put in the value of our currentDirectory.
06:18So, in this case we will say +currentDirectory and we will just pass in the native path .
06:25Now, we are going to want to add one more item, our closing tags, so we will say fileData +=
06:32and then we will close off our defaultDirectory and then we will close the prefs.
06:39Now, that we have actually added our file data that will be stored in our file, we actually can begin the process
06:45of writing it, so we will say fs.write and whenever you are writing a string into a file,
06:51you are going to use writeUTFBytes and then we will just say that we want to write the fileData.
06:57Now, since we opened it asynchronously, anytime we read or write data to a file,
07:02it will actually dispatch the Event.COMPLETE whenever it is done actually writing that data,
07:07so we actually need to create our one additional method the onFileStreamComplete method
07:16and that will receive an event of type Event.
07:19And since, we don't need to return anything; we can set the return type as void.
07:23Now, inside of this method, we really just need to close the FileStream,
07:26so we will say var fs of type FileStream is equal to Event.TARGET.
07:33And as we have stated before, since the target can contain many different types of data,
07:37we need to actually tell the application that it's going to be a FileStream, so we will say as FileStream.
07:43Next, we can just say fs.close and that will actually close the connection to our FileStream
07:49and we would have written our data to the file.
07:51So, let's go ahead and test our application.
07:56We are going to first browse for a directory, pick this event in directory and select Open,
08:01but you can select any directory on a computer's hard drive that has pictures.
08:04We then can say, Set Default.
08:06Now, we will notice here that nothing happens.
08:08We haven't set anything yet that will actually be displayed to the end user, however we are going to actually build
08:13on the skill and now that you are able to actually write data to a file on the hard drive,
08:17we are now going to actually have the application automatically read that data
08:21in from the hard drive and update View accordingly.
Collapse this transcript
Reading files
00:00Now that we've created an application that allows us to store information on the user's hard drive,
00:05we are now going to use that information to update the application.
00:07Originally, we loaded in an XML file that had references to many different files in it.
00:12Now, we are actually going to be able to do away with that portion of the application.
00:16Instead, we are going to actually use the data that was stored on the user's hard drive
00:19to have it automatically load data whenever the application launches.
00:23In this case, it will change to the default directory that they have set
00:26and then it will update the screen with the proper data.
00:29So let's go ahead and open up the application.
00:31We will go to File and then Open and then we are going to scroll down to Image Viewer 07
00:39in the Chapter 5 folder of the exercise files.
00:42We are going to go ahead and go to the Actions panel,
00:46so let's go to the Actions layer and then Window and then Actions.
00:49Now, the first thing we are going to do is we are going to remove any references to the XML data.
00:55So we will go ahead and highlight this section here and we can just delete it.
01:01We now can scroll down and also delete the onXMLLoad method.
01:09After that's deleted, we are now ready to begin the process
01:12of retrieving data that's stored on the user's local hard drive.
01:16Now, to do this, the first thing we are going to need to do is we are going to create a method called readPreferences.
01:20So let's go down to our method section because it's not responding to any events.
01:26We will say function readPreferences, and this isn't accepting any parameters
01:34and it's also not returning anything.
01:35Now, the first thing we are going to need to do is create an instance of the FileStream class,
01:41so we will say var fs of type FileStream is equal to a new FileStream.
01:49The next thing that we are going to need to do is add an event listener.
01:54Since we are going to be opening this action asynchronously, we are going to need to listen for the Event.COMPLETE event.
02:00So we'll say fs.addEventListener, Event.COMPLETE and then we will respond with the onOpenPreferences method.
02:10The next thing that we are going to need to do is actually open the file.
02:15So we will say fs.openAsync and then we are going to need to pass in the file reference.
02:20So we will create a new file reference and then we'll pass in the name of the file that we referenced
02:25when we actually wrote it to the hard drive.
02:27I will copy that and then paste it below.
02:31The next thing we are going to need to do is tell the FileStream what mode we are going to open the file in.
02:37In this case, we are going to open the file in FileMode.READ.
02:42Now, we can close our OpenAsync.
02:48Now, everything else that happens is actually going to be passed up to the onOpenPreferences method.
02:52So let's go ahead and create that method.
02:54We will go up to the end of our Event Handler section and create the new method onOpenPreferences.
03:04It's going to receive an event of type Event and it's not going
03:09to return anything so we can leave the return type void.
03:13Now, inside of this method, we are going to need to go ahead and grab the FileStream.
03:17So we will say var fs of type FileStream is going to be equal to event.target.
03:25As we stated earlier, event.target can contain many different types of data.
03:30So we want to be sure and let the application know that it's going to be a FileStream.
03:33So we will say as FileStream.
03:36That way, we have cast event.target as a FileStream.
03:39The next item is we are going to need to go ahead and extract the data out of the file.
03:43So we will say var preferences and that's actually going to be of type XML because we are actually going
03:50to parse XML data out of the file we saved on the user's hard drive, XML.
03:55And now, we are actually going to read from the file.
03:58So we will say fs.
04:00And just as we used writeUTFBytes to write the data,
04:03we are now going to use readUTFBytes to read the data from the file.
04:08It's going to ask us how many bytes we wanted to read and we wanted to read all of them.
04:14The good thing is our FileStream instance actually contains the number of bytes that are available.
04:18So we can say fs.bytesAvailable.
04:21Now, we can close that line.
04:24Now, the next thing we need to do is now that we actually have the preferences XML is we need
04:29to set the currentDirectory property to that actual value.
04:33So we will say currentDirectory is going to be equal to and then we are going to say new File reference,
04:42and then we are going to pass in the name of the directory that was saved on the user's hard drive.
04:47We can get to that by saying preferences. That will be the root tag and then we can say defaultDirectory.
04:56Now, because the application doesn't know, in this case, if there is more than one defaultDirectory tag
05:01because it's an XML list, we actually can just have it get the first one.
05:05Now, the last thing we are going to need to do, we are going to need to have a method that creates a list
05:11of all the files and then adds them to the tile list.
05:14Now, in this case, we have a method that does something similar.
05:16If we scroll up to our onDirectorySelect method, it does all of that but it's actually tied to the event.
05:23So it needs to be able to still get to the event.
05:25So we are actually going to extract part of this method and create a new method called listFiles.
05:31So we will highlight everything from var dirListing down, cut it and then we will move down to our method section
05:40and create a new method function listFiles.
05:44It's not going to return anything so we can say the return type is void.
05:50Now, we can just paste all of the data in.
05:52Now, we need to go back up to our onDirectorySelect method and put in a reference to the method listFiles.
06:01That way, every time the user selects a directory, it will still update all of the files within the application.
06:07Now, we need to scroll down and we also need to call this method inside of our
06:10onOpenPreferences, so we will say listFiles.
06:14Now, the last thing we need to do, we want to use this readPreferences method
06:19to actually load data once the application is launched.
06:22So we can highlight the name and we can go up to the top of the application where we used to load in the XML Data.
06:28And we now can load preferences.
06:32I will create a comment so I will know what I am doing.
06:36Then, we will add in the readPreferences call.
06:39Now, we should be able to save our application.
06:41Let's test our movie.
06:43Now, as you can see, we actually set a value and it actually went and detected
06:52that value when we launched the application.
06:54Let's go ahead and try this again.
06:55Let's go to Browse.
06:57We will go to David Tucker pictures.
06:59Again, you can pick any directory you want on your hard drive that contains images.
07:03I am going to go to the directory Savannah, we will click OK.
07:06Now, it will go through and load all of those values, but now we will click Set Default.
07:11Now, we will close the application and we will go to Control and then Test Movie again,
07:17and you will see that the application has been updated with the new directory and automatically loads the new images.
07:25Outside of that, it still functions with all the functionality that we put into it earlier.
07:29So now, you have been able to not only write data to the user's local hard drive but also to read data back.
07:35This can be a great way to store things such as application preferences as well as application data.
Collapse this transcript
Using temporary files and directories
00:00There might be some yimes while you are developing your applications in working with the file system that you just want to create a
00:05temporary file or directory to store data in for the length of the application and then just delete it once you are done.
00:10In those cases you can use two methods of the File class to help you.
00:14Let's open up,
00:15in the Chapter 5 folder of the exercise files, ImageViewer08.
00:20Let's go to the Actions layer,
00:21and then go under Window and then Actions.
00:24If we scroll down
00:27to the onSetDefault method,
00:29let's pretend for a moment that instead of actually storing this on the user's local hard drive,
00:33we just wanted to create a temporary file that would exist for as long as the application and then we could delete it.
00:38In those cases we can actually just delete the reference to the file and we could use a method that's included with the File class.
00:44In those cases, we can then just say File.
00:47createTempFile
00:51and what this will do, this will actually create a temporary file inside of the temporary file's folder for the application.
00:57Now this will automatically create a unique file. So you will have to check and see if the file exists. You can't even give it a name
01:04but you can create a file which you know is going to be unique for your application.
01:08However, in these instances because you don't know the name of the file, you can't really make this data accessible once
01:13you restart the application.
01:15So in these cases these files are made to be used for a single use of the application.
01:19You also can create a temporary directory.
01:22However,
01:23you still must be sure to go through and delete the file when you're done with it because these files will not be
01:27deleted automatically from the user's local hard drive.
01:30By using this you can create temporary preferences or you can dump temporary application data and this can be very
01:35useful when developing your applications and it is just another example of the file system support that AIR provides for you.
Collapse this transcript
6. Using HTML
Introducing HTML in AIR
00:01One of the benefits of AIR that opens up new possibilities to developers is the robust HTML support.
00:07AIR includes the entire WebKit, HTML rendering engine and JavaScript interpreter.
00:11This is the same engine that powers the Safari browser that comes with Mac
00:15and is also available for Windows XP and Vista.
00:18By leveraging this technology developers can create entirely new experiences within Flash for the desktop.
00:24However, Flash already supports some HTML, so what is gained by the new HTML support inside of AIR?
00:30In this session you will learn what the key differences are between the standard HTML support inside of Flash
00:35and the advanced HTML support inside of AIR.
00:37You will also see the sample application that will be created in this chapter.
00:41So let's look closely at the differences between the normal Flash support and AIR.
00:45In a Flash movie it renders only a small subset of HTML tags,
00:49so you can basically have some tags that modify the way the text looks.
00:53In a Flash movie it also supports a limited set of CSS properties, so you can set a few things
00:59but you can't do nearly as much as you can within CSS in a normal HTML page.
01:03You are also limited to loading external content on servers that allow it;
01:07they have to have a cross-domain policy file to allow you to work with their data.
01:11In addition there's no JavaScript support in HTML.
01:13Now you can talk to JavaScript functions through the external interface but there is no direct way
01:18to interpret JavaScript methods inside of Flash.
01:21However with AIR, you can fully support all standard HTML tags so anything that you can create with HTML
01:28and view in a browser you now can view inside of AIR.
01:30AIR fully supports standard CSS as well as the WebKit extensions.
01:34So not only can you do everything you normally will be able to do in a browser
01:37but with the WebKit extensions you can do even a few more things.
01:41AIR can load external content without a policy file.
01:44So in these cases you are not limited to just those servers that allow it.
01:48Also, AIR contains the full JavaScript Interpreter that comes with WebKit.
01:52So now you have the capability to connect ActionScript and JavaScript in a way never before thought possible.
01:59In this chapter we will be creating a browser just with AIR and Flash that uses the HTML support to load a URL,
02:05it is going to have history support with a forward and back control, you are going to be able
02:09to access the JavaScript Document Object Model, you are going to be able
02:12to manipulate CSS data and scroll HTML content, all within AIR.
02:18Now with this power inside of AIR you can now develop new and engaging experiences.
02:21So you are now ready to create a web browser with nothing but Flash CS3 and Adobe AIR.
Collapse this transcript
Using the HTMLLoader
00:01In this session, you will learn how to use the HTMLLoader class that comes with AIR.
00:04Anytime you want to view HTML content inside of an AIR application in Flash,
00:08you are going to be using the HTMLLoader class.
00:11By the end of this session, you will know how to create an instance of the class,
00:15place it on the Stage, position it and then load a URL into it.
00:18The first step in creating a browser application is to create a new AIR application inside a Flash CS3.
00:23Now we can do this by going under Create New and then going to Flash File, Adobe AIR.
00:29Now the first thing we are going to do is we are going to save our application.
00:33In this case, I am just going to save mine on the desktop and we are just going to call it Browser.
00:38You can choose to save yours wherever you would like on your hard drive.
00:42Now we need to adjust some of the settings.
00:43First we will change the size we will make this, 800 pixels x 600 pixels,
00:49since browsers generally have a lot to display.
00:52In addition, we will also go and adjust some of the AIR Application and Installer Settings.
00:56Now this can be accomplished by going under Commands and then AIR Application and Installer Settings.
01:01Note that you will actually have to save your application before you actually can edit the settings.
01:05Now we are going to give it a File Name, a Name and an ID as we need to do for every AIR application that we create.
01:12So we will call this Browser application for both the File Name and the Name
01:18and then we will need to actually give it an ID.
01:22In most cases, people use the Reverse DNS Format, so either a URL that you own or are associated with,
01:28you can just flip around backwards and use that here.
01:30In this case, I am going to use the lynda.com domain, so I will say com.lynda
01:34and then I will say it Browser Application, which is the name of our application.
01:39We are also going to need to adjust a couple of the advanced settings,
01:42so let's click on Settings next to the word Advanced.
01:45We will uncheck the Maximizable and Resizable options and then click OK.
01:49We will click OK one more time and now our settings have gone into effect.
01:53Now we actually can create an Actions layer and start working with it.
01:56But first we are going to need to lay out some of the UI Elements of our application.
02:01So we are actually going to rename this layer UI for the user interface.
02:05Now we are going to go to Window and then go to Components.
02:08Now we are going to actually need to drag two components onto the Stage, first we will drag the button
02:13and then we will drag one instance of the text input.
02:16We can now close the Components window.
02:18I am going to position the Text Input in top left of the screen.
02:21Then I am going to position the Label on the top right of the application.
02:26Now I am going to go ahead and select the Free Transform tool, and I am going to choose the Text Input and I am going
02:33to hold down the Alt key on PC or Option key on Mac and I am going to stretch this to the right.
02:38I want to stretch it, so that it is close to the button.
02:41Now I am going to select both items and I am going to go to the Align panel.
02:48If yours is not open, you can go under Window and then Align.
02:51And then inside of the Align panel, I am going to choose to align these up both in the center.
02:55Now I am going to give the text input an instance name of URLInput and I am going
03:04to give the button an instance name of goButton.
03:06And I am also going to change its label to be Go.
03:10Now we can lock our UI layer, create a new layer name it Actions.
03:17At Preference I would like to keep all of my Actions layers at the bottom and then I am going to lock that layer.
03:24We now can be sure that it's selected and we can go under Window and then Actions.
03:28I would like to keep my code organized by giving it sections.
03:33In this section, we are going to be importing classes so I will add an import comment so I know where I am at.
03:38Now the first thing we are going to need to do is we are going to need to import an entire package.
03:42We are going to be using several classes from the Flash.display package, so we will just import all those.
03:49In addition, we are also going to need to import the HTMLLoader.
03:52So we will say importFlash.html.htmlloader.
03:57We are also going to need the URLRequest class because when we use the Load method of the HTMLLoader,
04:04it's going to require that we pass in the URLRequest to that method.
04:07So we will say import flash.net.URLRequest.
04:12Now we can actually set up our Stage.
04:16In this case, we are going to need to actually set a few properties, by default the HTMLLoader tries
04:22to scale our content to the size of the actual HTMLLoader container.
04:26We don't want it to do that, so we are actually going to set the stage scaleMode and the stageAlign.
04:30So in these cases, we are going to say stage.scaleMode, it is going to be equal to StageScaleMode.No_Scale.
04:43We also need to set the Align property and that will be stage.align it's going to be equal to StageAlign.
04:53then we will say Top_Left.
04:56Now that we have set up our Stage, we can begin creating our properties and position them on the Stage.
05:02In this case, we are first going to create the HTMLLoader.
05:06So we will say var html Loader is of type HTMLLoader is equal to a new HTMLLoader.
05:16Now we are going to want to position our item on this Stage, so we will say htmlLoader.x and we are going to set
05:24that equal to 10 so that it doesn't go all the way to the edge of the application.
05:28Then we will the y property and we will set that equal to 45, so this is far enough down off the top
05:33that it won't run into our URL input and goButton.
05:35Next we are going to need to actually set the width and that is going to be equal to stage.stageWidth
05:43and then we are going to subtract 40, so it will reside in about the middle of the window.
05:51Then we are going to need to set the height and that's going to be equal to stage.stageHeight
05:57and then we are going to subtract a 100 from that.
06:03Now the next thing that we will need to do is actually add our HTMLLoader to the Display List, this can be accomplished
06:09by just saying addChild and then htmlLoader.
06:13Now we are going to want to go ahead and add an event listener for our goButton.
06:19So we will say goButton.addEventListener and then we are going to want to listen for the MouseEvent.CLICK event.
06:27And we are going to pass it into an onGoClick method.
06:36Now within this method, we are actually going to retrieve the data that's in the URL Input
06:40and then pass it at the HTMLLoader to load.
06:43So we will go ahead and create this function but first we will create our section for our event handlers.
06:53Then we will say function onGoClick and then we will want to pass in the event,
07:00in this case it will be an event of type MouseEvent.
07:03It's not going to return anything, so we can leave the return type as void.
07:07Now within here we are going to want to use the HTMLLoader.load method, so we will say htmlLLoader.load
07:15and here is where we actually need to create a URLRequest.
07:17So we will say new URLRequest and we will pass in the URL that we wanted to go to.
07:23In this case we are going to use the URL input so we will say urlInput.text and that will bring us back the text
07:30that is actually contained in the text input on the Stage.
07:33So that's all we need to do for our onGoClick method.
07:37In most cases when you go to a web browser it actually loads a page by default so when I go back
07:42up under the addChild method and I am going to say htmlLoader.load and then we are going to tell it
07:48to load a new URLRequest and we will just put lynda.com.
07:54In this way when the user opens the browser, it will automatically navigate to a page for them.
07:58So now let's save our application and then we can go to control and then Test Movie
08:03and now that we have tested our movie, you will see it comes up
08:06and it will take it a second but then it loads the lynda.com page.
08:10Now your application already has many of the trappings of a complete web browser.
08:14We can tell by even typing in a URL such as www.google.com then we can go
08:21to the goButton click and there we go, we have loaded a page.
08:25So you should now feel comfortable using the HTMLLoader placing it on the Stage and using it
08:30to load a URL all within Flash CS3 and AIR.
Collapse this transcript
Scrolling HTMLLoader content
00:00In this session you will learn how to scroll the content within the HTMLLoader container.
00:04The HTMLLoader does not contain any scroll bars by default so we will be using the ScrollBar control that's within Flash.
00:10To begin we will open the FileBrowserApplication01 which can be found in the Chapter 6 folder of the exercise files.
00:16So we will click the File and then click Open.
00:20The first thing we will need to do before we jump
00:22into the Actions panel is we are going to need to add an item to the library.
00:25So if we go to Window and then Components we are going to look for the UIScrollBar.
00:31And we are going to add this into our library.
00:33Now we are not actually going to be using the UIScrollBar however,
00:37the base class for the UIScrollBar is fl.controls.ScrollBar and this is the class that we will be using.
00:43So to ensure that it gets compiled into our application we are just going to add that component to the library.
00:48Now we will select our Actions layer and we will go under Window and then Actions.
00:52Now the first thing we will need to do is create two scroll bars. So directly under the area
00:57where we created our HTMLLoader and added it to the Stage we are going to create a scroll bar.
01:02We will start off with vScrollBar for Vertical.
01:04It's going to be of type ScrollBar and it's going to be equal to a new ScrollBar.
01:09Now to ensure that we are able to do this we are going to need
01:12to import two classes first we are going to need to import fl.controls.ScrollBar.
01:20In addition we are also going to need to import the fl.events.* package.
01:28Some of the events that are dispatched by the ScrollBar are in this package
01:31and this way we can react to those events.
01:34After we create the vScrollBar we are going to need to position it on the Stage.
01:38First we are going to need to set its direction.
01:41This is the property of the ScrollBar that tells it if it goes horizontal or if it goes vertical.
01:46So we will set vScrollBar.direction=vertical.
01:50Next we will need to set the x and y properties of the vScrollBar.
01:56In this case the x is going to be equal to htmlLoader.x and then we are going to want to add in the htmlLoader.width.
02:06This will position the vertical scroll bar directly on the right side of the HTMLLoader container.
02:12Next we will set the y property and that's going to be equal to htmlLoader.y. This will position it even with the top
02:22of the HTMLLoader container which is what we want.
02:25Then we will set the height which will be vScrollBar.height and that's going to be equal to htmlloader.height.
02:34This way the scroll bar will run directly down the right side
02:38of the HTMLLoader container for the full height of the container.
02:41Now the next thing we are going to need to do is we are going to need to set a few of the specific properties
02:45of the scroll bar. First we are going to need to set line scroll size.
02:49In this case we are going to tell it to scroll 15 lines every time they push scroll down or scroll up.
02:57In addition we are going to need to set the page size.
02:59Now we can set the page size just simply equal to the htmlLoader.height.
03:07This way when someone clicks the track of the actual scroll bar it will note to move
03:11down the full width of the HTMLLoader's content.
03:15Now at this point redone setting up our vScrollBar and we can add it to the Stage.
03:19So we will say addChild vScrollBar.
03:23Now we are ready to move on to creating a horizontal scroll bar so we will say var hScrollBar
03:29of type ScrollBar is going to be equal to a new ScrollBar.
03:36Now we are going to set its direction and that's going to be equal to horizontal.
03:45Next we are going to need to set the x and y values we are going to set the hScrollBar.x is going to be equal
03:53to htmlLoader.x. This will position the scroll bar to be even with the left side of the HTMLLoader container.
04:01Then we will set the hScrollBar.y=htmlLoader.y but then we are going to add in the htmlLoader.height.
04:13This will position the horizontal scroll bar directly below the HTML container and that's what we want.
04:19Next we are going to need to configure the width.
04:22So we will say hScrollBar.width is going to be equal to htmlLoader.width.
04:28This way it will reside directly below the HTMLLoader and also will be just as wide as the HTMLLoader container.
04:34Next we are going to need to also do the line scroll size for the hScrollBar and we can set that equal to 15,
04:42we also can set the pageSize=htmlLoader.width.
04:52Next we are going to add our hScrollBar to the display list.
05:01Now we are going to need to listen for two specific events so we actually can scroll down and we can see
05:08that we have a section here where we add event listeners.
05:10So we will go ahead and create little subsection that says Add Event Listeners.
05:15And I will create an addEventListener statement for each scroll bar.
05:19First with the vScrollBar we will add an Event Listener and we are going to want
05:24to listen specifically for the ScrollEvent.SCROLL.
05:30And for that we are going to create a method called onVScroll and it will do the same thing for the hScrollBar
05:41and we are also going to listen for the ScrollEvent.SCROLL and we will respond to that with the onHScroll method.
05:49Now that we have added our two event listeners we can actually begin the process of configuring those methods.
05:56So if we go down to the event handler section we are going to first create a method and this is going
06:02to be called onVScroll, it's going to receive an event it's going to be a ScrollEvent and it is not going
06:08to return anything so we can set that return type equal to void.
06:11Now we are going to use a property of the HTMLLoader that's called scrollV.
06:20Now basically what this does is this tells the HTMLLoader how far to scroll down the content.
06:26In this case we actually can take that value from the event.position property.
06:33Now position is a property that's actually passed in by the ScrollEvent and we can use
06:36that to tell the HTMLLoader where to scroll the content vertically.
06:40Now the same thing we can actually copy this entire method and we will paste it below.
06:44And we just need to update it with H instead of V.
06:48So in this case we have got onHScroll and scrollh is equal to event.position.
06:53Now that we have added that we are going to need to add one more method to our application.
06:57If we left it this way, well our scroll bars would work they would not be updated every time that we go to a new page.
07:04We obviously want our scroll bars to work with any page that we go to so because of
07:07that we will create a method called updateScrollBars.
07:11Since this is a method that won't be called by an event we are going
07:14to actually create a new section just for our methods.
07:21So we will create the method called function and then we will say updateScrollBars and it is not going
07:28to receive any events and it's not going to return anything.
07:31Now we are going to need to do some calculations inside of here, first we are going to need to determine
07:38if we need a horizontal or vertical scroll bar for a given page.
07:42So we are going to use two properties of the HTMLLoader, contentWidth and contentHeight.
07:47And that gives the actual width and height of the HTMLLoader container's content so first we will determine
07:53if we need the vScrollBar to be enabled, if htmlLoader.contentHeight,
08:00if that is actually greater then htmlLoader.Height then we know that we are actually going to need our scroll bar.
08:09That statement is basically saying if the stuff inside of the HTMLLoader is taller
08:13than the HTMLLoader itself then yes, we are going to need the scroll bars.
08:17We will go inside of the if statement here and we will say vScrollBar.enabled=true.
08:24On the other side we know that if it's the content height is not greater than the height then we are not going
08:30to need the scroll bars so we can say else and we can say vScrollBar.enabled=false.
08:39Now we also can put in the same logic for the hScrollBar but before we do we are going to need to do the min
08:45and max scroll positions for the vScrollBar so we will say vScrollBar.minScrollPosition is going to be equal to 0
08:56because we are always going to want the minimum to be 0 that way they could scroll all the way back to the top.
09:00Next we are going to set the maxScrollPosition.
09:06And here is where things are a little bit different.
09:09To create the maximum scroll position we want to take the content height but we also want
09:13to subtract the htmlLoader height from that value.
09:16We will say htmlLoader.contentHeight-htmlLoader.height.
09:25If you didn't subtract the htmlLoader height from the htmlLoader contentHeight then you would actually be able
09:31to scroll down further than the actual content goes.
09:35This way if you subtract the htmlLoader height you know that you can only scroll the length of the webpage and no more.
09:41Now we can go down and implement the same thing for the hScrollBar.
09:44We will say if htmlLoader.contentWidth is greater than htmlLoader.width then we know
09:54that we will need out hScrollBar enabled.
09:57So we will say hScrollBar.enabled=true but we also know that if it's not then we are not going
10:05to need enabled so we will say hScrollBar.enabled=false.
10:11Now we will also need to go in and set the max and min scroll position values
10:16so we will say hScrollBar.minScrollPosition it's going to be equal to 0.
10:22And then we will say hScrollBar.maxScrollPosition this going to be equal to htmlLoader.content and then we are going
10:33to subtract the htmlLoader.width from that value.
10:37Now the last thing we are going to need to do is to tell our HTMLLoader that every time we go to a new page we want
10:43to update the scroll bars so I am going to highlight the name of this method.
10:46And then we are going to go up an addEventListener to the HTMLLoader.
10:51We will say htmlLoader.addEventListener and then we are going to be listening for the Event.COMPLETE event.
11:00And we are going to respond to that by calling a method called onLoadComplete so we will go
11:08down to our event handler section, we will scroll down, we will create a new function called onLoadComplete
11:16and it will receive an event of type event and it's not going to return anything so we can leave the return type
11:22as void and then we are going to call this method updateScrollBars.
11:25Now if we test our application by going to Control and then Test Movie the first thing we should notice is
11:32that we see the actual scroll bars on the Stage.
11:35The next thing you will notice is that as the content was loading the scroll bars were both disabled.
11:40However now that the content has finished loading they have been enabled and we can now scroll our content.
11:46We can scroll vertically and we can scroll horizontally so we can see the entire page.
11:52In addition if we go to another page and we click the goButton you will notice
11:59that both of the scroll bars have been disabled.
12:01This is because this content does not require the scroll bars because it fits
12:04within the HTMLLoader container width and height values.
12:08Your browser application can now view HTML content of any size by the use of the scroll bars that you have added.
12:14You now should be able to create instances of the ScrollBar class and attach them to the HTMLLoader objects.
Collapse this transcript
Accessing HTML history
00:01No browser would be complete without Forward and Back buttons.
00:04So, in this lesson, you will learn how to access to browser history within an HTMLLoader object.
00:09This powerful feature of the HTMLLoader object allows you to move back and forth within the HTML history as well
00:15as track your current location in that history.
00:17So we will be using the Browser Application 02 file.
00:20So, if we go to File and then Open and then if we look in the Chapter 6 folder
00:25of the exercise files, we go to Browser Application 02.
00:29Now, the first thing we'll need to do is to actually add some buttons onto the Stage that will allow us
00:35to use the forward and back functionality.
00:37So the first thing I am going to do is unlock the UI Layer.
00:40Then I am going to select the layer and then we'll open the Components window.
00:43Now, we are going to be dragging two more buttons onto the Stage but first we are going to need
00:48to actually scale our URL input so that we have rooms.
00:51So I will select the Free Transform tool and then I will select the URL input but I will hold down Alt
00:57and drag from the left side and drag it in.
01:00Then, we can drag two instances of the button class onto the Stage.
01:06We will make each of these only be 30 in width.
01:09I am going to give the first one an instance name of backButton.
01:12And then we are going to go into parameters and instead of having a label be label, I am actually going to use a symbol
01:19that is going to just signify that it's a back motion.
01:23Next, we will select the Next button.
01:25We will do the same thing.
01:26We will give it a width of 30.
01:27We will give this one an instance name a forwardButton and give it a symbol for label that signifies moving forward.
01:34Now, we can line both of our items up.
01:37We can then highlight all of the UI items on this layer, we will align them to center.
01:43Now, we will move our items over to the edge of the Stage and then we are actually going
01:49to select the URL input one more time, select the Free Transform tool, hold down the Alt key and slide it
01:55so it's getting fairly close back to the Forward and Back buttons.
02:01You can position yours as you like.
02:04And now that we have given two new buttons instance names of backButton and forwardButton,
02:09we now can actually connect that with our ActionScript.
02:11So let's lock the UI Layer.
02:12Now, we will go to the Actions layer and now we will go to Window and then Actions.
02:17Also at this point, we are done with the Components window so you can close that.
02:21Now, the first thing we are going to need to do is add event listeners for our Forward and Back buttons.
02:26So let's scroll down to the section of code where we add event listeners
02:30and we are going to first add for the Back button.
02:32We will say backButton.addEventListener and then we will say MouseEvent.CLICK because we want
02:42to find out when they actually click the button.
02:43And then at this point, we will call onBackClick.
02:50Next, we work with the Forward button.
02:51We will say forwardButton.addEventListener and then at this point,
02:57we will also listen for the MouseEvent.CLICK and we will call the onForwardClick.
03:03Now, we are going to need to actually implement the onBackClick and onForwardClick methods.
03:09So, if we scroll down to the Event Handler section, we will add a new line
03:13and we will first create the onBackClick method.
03:15In this case, it's going to receive an event that will be of type MouseEvent.
03:23It's not going to return anything so we can leave the return type as void.
03:26And inside of here, we are actually going to use a method of the HTMLLoader class that allows us to go back
03:32and that's going to be htmlLoader.historyBack.
03:38That doesn't take any parameters.
03:40Now, we'll do the same thing for the onForwardClick and it will receive an event of type MouseEvent.
03:50It's not going to return anything so we can leave the return type void.
03:53And then we are going to call the htmlLoader.historyForward, again with no parameters.
04:01So now that we have added this to our movie, we actually can save and then we can go
04:06to Control, Test Movie to test our application.
04:09So, we are going to go ahead and go to another site.
04:15Let's just say we want to go to Google.com.
04:18We will hit the goButton and now, if we press the Back button, we will see that indeed we'll return to Lynda.com.
04:25However, there is a couple of problems with this.
04:27First, we know that we are at the beginning of our HTML history
04:31but we can still click the Back button but nothing happens.
04:33At this point, we can click the Forward button and it will take us back to Google, but then,
04:38we can hit the Forward button and it won't do anything because we are at the end of the HTML history.
04:42This can be a bit confusing for the end user.
04:45So in this case, we are going to actually enable or disable these buttons based on where we are in the HTML history.
04:51So now that we have seen that our buttons are perfect that even though they can go forward and back to keep it
04:56from being confusing to the end user, we are going to enable
05:00or disable the buttons based on where we are in the HTML history.
05:03So I am going to close the application and then I am going to go, I am going to create a new method just
05:08under the Method section and we are going to call this method updateHTM History.
05:12Now, this is not going to receive any events and it's also not going to return anything.
05:21Now, within this method, we are going to need to check and find out where we are in the HTML history.
05:26The great thing is that the HTMLLoader actually gives us a couple of values that will help.
05:31So the first thing we are going to want to do is determine if we need to enable the Back button.
05:35Now, we will know if we are at the very beginning of the HTML history, in other words, if there is no pages before,
05:42then we know that we need to disable the Back button because we can't go back any further, and that can be accomplished
05:47by saying if htmlLoader.historyPosition, if that is equal to 0, then we will know that we are
05:58at the very beginning of our actual HTML history.
06:01So at this point, we can say backButton.enabled is equal to false.
06:10But we also know that if the historyPosition is not equal to 0, then we can go back.
06:14So we will say else backButton.enabled equals true.
06:24Now, we need to actually check for the Forward button and we can do this using another property.
06:29So we will say if htmlLoader.historyPosition, now we are going to want to check
06:37and see if the historyPosition is equal to the end of the history and to do this, there is actually a property
06:46of the HTMLLoader object called historyLength.
06:49Now, there is one important thing to note though between historyPosition and historyLength.
06:54historyPosition starts numbering from 0, so the first site you go to would be historyPosition 0,
07:00your next one would be 1 and the following one would be 2 and so on.
07:04However, the historyLength starts with 1, so the first time you go to a new page, you will have a historyLength
07:10of 1, the next page 2 and so on and so forth.
07:13So in this case, we are going to check and see if the historyPosition is equal
07:17to htmlLoader.historyLength and then subtract 1.
07:26Now, in this case, it will tell you if you are at the end of the history.
07:30Now, if we are at the end of the history, we know that the forwardButton.Enabled needs to be equal to false.
07:41However, if we are not, we know that we can go forward and so we want to say forwardButton.Enabled is equal to true.
07:55Now, if we save our application and we go to Control and then Test Movie to test our application,
08:05we can actually go through now and we can go to a new page.
08:09But you will notice that yet both of our buttons are still enabled and there is one reason for that because we haven't
08:14yet told our application that every time we load in a new page, we wanted to update the HTML history.
08:19So, that's the last step of implementing the history functionality.
08:22We will close our application.
08:23We will now go back to the Actions panel and we will go under the onLoadComplete method
08:30and after updateScrollBars, we will bring in updateHTMLHistory.
08:35Now, we will save the application and we'll go the final time and go to Control and Test Movie.
08:42We will be able to see immediately that after the page is loaded, both of the buttons have been disabled
08:50because at this point, we are at the beginning of the HTML history and we are also at the end.
08:54But now, if we go to a new page and we hit Go, we will notice that our Back button is now enabled
09:02and if we go back, we will see that our Forward button is now enabled.
09:07We now can go to any URL.
09:08We can go forward and back within the HTML history and we also can track our position within the HTML history.
09:14And now, we will learn about some of the ways that we can really dive in deep
09:17and connect with the content inside of our browser.
Collapse this transcript
Using script bridging
00:00AIR enables new types of communication,
00:03between JavaScript and ActionScript and this is generally referred to as script bridging.
00:08This is a powerful feature that goes a bit beyond the scope of this series but we're going to use a few small elements of
00:14script bridging to complete the browser application. First let's examine what's possible with script bridging.
00:19It actually allows for JavaScript methods to call ActionScript. methods Now again this is different from actually using the external
00:25interface capability that you already have in Flas. This actually allows for JavaScript methods to call actual ActionScript methods.
00:32In addition it can work the other way so that ActionScript methods can call JavaScript methods.
00:37Now this is what we're actually going to be utilizing today. ActionScript what methods can communicate fully with the JavaScript
00:42document object model so ActionScript can respond to DOM events, ActionScript can manipulate style sheet data,
00:49as well as adding and removing items from the document object model.
00:52And finally JavaScript can even include ActionScript libraries.
00:56So there's a lot of capability with script bridging.
00:59But today we're going to use just a few small elements of this to complete our application.
01:03Now to add these items to our application we're first going to open out file.
01:07So we'll go to File,
01:08and then Open,
01:09and then we'll open BrowserApplication_03 in the Chapter 6 folder of the exercise files.
01:16Now within here we're just going to go straight to the Actions panel so we'll highlight Actions and then go to Window
01:21and then Actions.
01:23Now we're going to scroll down to our onLoadComplete method.
01:26Now currently we have two things going on inside of this method. We're updating scrollbars and we're updating the HTML history.
01:32Now we're going to do two more things.
01:34Now if you've noticed there's a few things that aren't quite perfect with our browser application.
01:39First if we go to a new page by clicking on a link, the URL input isn't updated.
01:44To demonstrate that we'll actually test the application.
01:47When the application loads up we're here at the lynda.com page and if we click on the Products item
01:52it'll actually take us to the new page. But we'll notice first of all, when we first went to the page, the URL input wasn't updated
01:58and any time we go to links it's not updated.
02:00The other problem in our application
02:03is right now it just says BrowserApplication_03 as the title for the window.
02:07However in most browsers, the title for the window is the actual title of the current page that you're on. So these are
02:13the two pieces of functionality that we're going to add by actually accessing the JavaScript document object model
02:18within ActionScripts.
02:20First we're going to add a new line below our updateHTMLHistory, and we're going to set the property of the URL input. So the way that
02:27we do that is we're actually going to say
02:30urlInput.txt and we're going to set that equal to the current location value
02:36in the JavaScript document object model and that can be accomplished by saying htmLoader.window
02:44and that's going to actually get us to the DOM and then we're going to say location. So now every time we go to a new location within a page,
02:50even if it's from clicking a link, even if it's the page that loads up automatically,
02:54or if we enter a URL ourselves,
02:56the page automatically update the URL input.
02:59And the final item is we actually want to set the title of our window. Now we'll cover a bit more about working with windows
03:05in a future chapter,
03:06but for the moment the thing that you need to know is inside of the stage,
03:10there is a current property for the current NativeWindow and then each NativeWindow has a property called title.
03:18And we just want to set this equal to the title of the current page.
03:22And this can be accomplished by going to htmlLoader.window.
03:27document.
03:30title.
03:30Now if we save our application,
03:34and we test by going to Control and then Test Movie.
03:38We should notice that right away lynda.com is entered into the URL input.
03:42In addition to the title has been added as the title of our window.
03:46And if we now click on a page, such as Products,
03:49we should notice that the URL has been updated
03:52and the title has been updated as well.
03:53And it also will be updated if we actually type of value into the URL input and hit Go.
03:59We can see that the URL is indeed updated
04:02as well the title for the window.
04:03So script bridging is a very powerful feature, allowing communication that wasn't previously thought possible between JavaScript
04:09and ActionScript. If you just beginning to work with JavaScript inside of ActionScript, accessing the JavaScript document
04:16object model is a great place to start.
04:18By using these pieces of functionality, we expanded our browser
04:21to where we now basically have a full featured web browser
04:24built entirely in Flash CS3 with AIR.
Collapse this transcript
7. Handling PDFs
Detecting PDF support
00:00In addition to being able to display HTML content,
00:04the HTMLLoader has the ability to display PDF content. Now, you were introduced to this concept in the Essential AIR series.
00:11And there is one important difference between HTML support in AIR and PDF support within AIR.
00:16HTML support is provided by AIR with the embedded WebKit engine. But PDF support relies on the Acrobat Reader, which does
00:23not come bundled with AIR.
00:25Because of this, the first step you will need to do when actually working with PDF documents in AIR is to detect if the
00:31user has a sufficient version of Acrobat Reader installed.
00:34And currently, the user will need Adobe Acrobat Reader 8.1 or greater to view PDF content inside of AIR.
00:41We are actually going to take the Browser Application that we have created and we are going to give it the ability to load a PDF from
00:46the hard drive.
00:47So first, we are going to open our file. So if we go to File
00:51and then Open and we look in the Chapter 7 folder of the exercise files, we'll go to Browser Application 01.
00:59Now, here within Browser Application 01,
01:01we are going to need to add one more button to the Stage. So if we go to the top right hand corner of our application,
01:06the first thing we are going to do is we are going to highlight the URL Input
01:10and we are going to select the Free Transform tool and we are going to hold down Alt on PC or Option on Mac and drag in from the right side.
01:17We are then going to take the goButton and will move it to be fairly close to even with the right side of the URL Input. Then,
01:23being sure that the UI Layer is selected, we will go under Window
01:27and then Components
01:29and we will drag a new instance of the button onto the Stage directly to the right of the goButton.
01:34We are going to give this new button an instance name of pdfButton.
01:40We are also going to give it a label of loadPDF.
01:45We will select a few of these items and be sure that we align them to center and now that we have added them, we can go ahead and
01:50begin working with our ActionScript. So I will close the Components panel,
01:54lock the UI Layer and then go to our Actions layer and then go to Window
01:58and then Actions.
01:59We are not going to need to import a class that defines the different level of support that a user's computer offers for PDF
02:05support in AIR and that specific class is going to be flash.html.HTMLPDFCapability.
02:13Now, we actually can scroll down and create a method
02:16that will be called when the application starts that will check and see if the user has sufficient capability to view
02:22PDF files inside of AIR.
02:23And what we are going to do is if they do have support for that, we are going to leave the PDF button enabled.
02:29But if for some reason, they don't, then we are going to make the PDF button be disabled on the screen so the user can't click it.
02:35So if we scroll down to our method section,
02:38we are going to create a new method
02:40and we are going to call it checkPDFSupport. It's not going to receive any arguments and it's not going to return anything so we can leave its
02:49return type as void. Now, the first thing we are going to want to do is actually check the PDF capability.
02:54Now, to do this, the HTMLLoader class has a static property that tells if the user can actually view PDF content. So we'll
03:02go if an HTMLLoader- notice especially right here I use an uppercase H
03:08because here I am not referring to our instance of the class but rather I am referring to a static property which means
03:14there is a single property for every instance in the class. So in this case, we will actually use the uppercase H.
03:19We will say HTMLLoader.pdfCapability and we want to be sure that that's equal to HTMLPDFCapability.
03:29And then we want to look for Status_OK.
03:32This will tell us that the user's Acrobat Reader is a sufficient version to view PDF content inside of AIR and if that's
03:39true and what we are going to do is we are going to be sure that the pdfButton
03:43.enabled is equal to true. Otherwise, we are going to want to set to false.
03:54Now, we are going to need to add a call to this method at the very beginning of our application. So I'm just going to highlight the name
04:01in the parentheses
04:02and move back up to the top of the application. And then directly after we have set up the Stage, I am going to go ahead and call
04:08the checkPDFSupport. And I am going to create a new section here
04:13that I am just going to call Initialization Methods and these are methods that would just be called automatically when the application starts.
04:21So now, when we launch our application, we should see the PDF button enabled because we do have a current
04:27version of Acrobat Reader installed.
04:29So in this case, we go to Control and then Test Movie
04:34and indeed the Load PDF button stays enabled. However,
04:38just as a way to test our code,
04:40if we go down to the method for checkPDFSupport and instead of saying equals, if we change it to not equals, now when we load
04:47our application, we should see that the PDF button is disabled.
04:50So we go to Control and then Test Movie
04:54and here we can see that the Load PDF button has indeed been disabled. Now, you can actually work this functionality into
05:00your application so that
05:01only people that have PDF support can interact with PDFs.
05:05Now that you can detect if the user has adequate PDF support on their local computer, you now can create an application
05:11that allows users to view PDF content within AIR.
Collapse this transcript
Loading a PDF file with HTMLLoader
00:00So you want to be able to load a PDF file into your AIR Application.
00:05Well if you have already detected that the user has the proper version
00:08of Acrobat Reader installed then you can load the PDF into the HTMLLoader class.
00:12Now what we want to be able to do is actually use the loadPDF button that we created previously
00:17and when the user clicks it let them pick a file from the local hard drive to view inside of the HTMLLoader
00:23so let's go ahead and wire everything together.
00:25First we are going to open up our file which can be found in the Chapter 7 folder of the exercise files
00:31and we are going to open BrowserApplication02.
00:35Once we have loaded it up everything that we need to do is actually going to be done in ActionScript so let's go ahead
00:40and select the Actions layer and then go to Window then go down to Actions.
00:44Because we are letting the user pick a file from their local hard drive we are going to need to import the file class.
00:49So we will say import flash.filesystem.File. In addition we are also going to want to limit what files the user can open
00:58so to do this we are going to need the FileFilter class which can be found in flash.net.FileFilter.
01:06Now we actually can scroll down and add the event listener for our PDF button
01:10so in the addEventListener section we then can add pdfButton.addEventListener we are going
01:18to listen specifically for the MouseEvent.CLICK event.
01:23We are going to respond to that with onPDFClick a method that we will create shortly.
01:28So now let's scroll down to our event handler section let's go down below the last one
01:32and we will create our new method, function OnPDFClick, and it will receive an event of type MouseEvent and it's not going
01:44to return anything so we can leave the return type void.
01:47Now in this case the first thing that we are going to want to do since we are prompting the user
01:50to select a file is we are going to go ahead and create a new instance of the file class.
01:54So we will say var and we will just call it F of type File is equal to a new File.
02:00Now after this we are going to want to listen for the Select event because once a user actually clicks a file
02:06from the dialog box it will dispatch the Select event.
02:09So we will say f.addEventListener and then we will listen for Event.SELECT
02:15and at that point we will actually call the onPDFSelect method.
02:20Now we are going to want to create our filter so that users can only select PDF files.
02:26To accomplish this we will say var filter of type FileFilter is going to be equal to a new FileFilter.
02:33Now we are going to need to pass a new parameters to the FileFilter class.
02:37First we want to give it a description so we will say PDF Files. That will be the name of the type
02:42of files that they will actually be selecting.
02:44Then we need to add the extension so in this case we will say *.pdf and that will tell it
02:49to only allow PDF files to be viewed in this dialog box.
02:54Now we actually can prompt the user to pick a file so we will use f. and then we will say browseForOpen
03:00and then we will actually need to pass in a title. We will say select a PDF file
03:06and then we will need to pass in an array of type filters.
03:10Now in this case we only have one but if we just put our filter in this parameter it would throw an error
03:15so we can actually use this short hand for creating an array,
03:18use the left and right bracket and inside of it we will put filter.
03:21This will create an array with a single parameter, in this case our filter.
03:27Now we need to create our onPDFSelect method so we will say new function onPDFSelect. It will receive an event
03:36of type Event and it's not going to return anything so we can leave the return type as void.
03:42Now at this point we are going to want to extract the file from the event so let's say var f of type File is equal
03:50to event.target but again, event.target can contain many different types of data so we need
03:55to specifically tell the application which type of data it's going to contain.
03:59In this case it will be a file.
04:01Now we are going to want to actually load the content in.
04:04Now HTMLLoader we know has a .load method and that's what we will use here.
04:08We don't need to do anything special for the PDF.
04:10We actually can just pass in the URLRequest as we have done before so we will say new URLRequest and now we are going
04:17to give it the actual URL of the file and we learned it in a previous video that every file has a property .URL
04:24that gives the native path in a URL formatted string.
04:26Now that we have added the onPDFSelect method we are actually ready to test our application.
04:35So now let's go to Control and then Test Movie.
04:38Now the first thing we should notice is that the Load PDF is enabled.
04:43This is because it actually has checked and we do have a current version
04:46of Acrobat Reader installed on this computer.
04:48So now we can click the Load PDF button.
04:50We will notice that we have the window popup that says Select a PDF file and that it's limited to PDF files.
04:56Then I have a file on a desktop it's actually a 20 meg PDF file that actually is a poster of the AIR classes.
05:02Now this is a poster that Adobe provides.
05:04But I wanted to illustrate two things with this. The first thing I wanted to illustrate is the ability of AIR
05:08to load items quickly that are coming from the user's local hard drive but also the ability to actually do a lot
05:14of different PDF capabilities within the HTMLLoader such as zoom in and move around
05:18and look at a larger document. So let's select this file and hit Open.
05:21It will take it a second as it actually loads the PDF but then you will see the interface that you are used
05:26to when actually looking at PDFs inside of Acrobat Reader and as you can see we can still zoom in
05:31and we still can use the Hand tool to move around the document.
05:37And it looks very much like Acrobat Reader.
05:40However, there is one problem with our application.
05:42Here inside of the HTMLLoader, we have scrollbars that are actually inside
05:46of the PDF component inside of the HTMLLoader.
05:48However we also have our scrollbars that we created that are on the outside of the application.
05:54So wouldn't it be great if we actually can hide the scrollbars from reviewing PDF data inside of the HTMLLoader?
05:58And that's what we are going to go ahead and add next into our application.
06:01This is a pretty easy fix.
06:03When we go to the onPDFSelect method what we will need to do is we will first say vScrollBar.v isible = false.
06:12We will also do the same thing for hScrollBar.
06:19Now we are actually going to need to be sure that they in-enabled for every time that we are viewing a URL.
06:25So to do this we are going to update another method.
06:27The onGoClick method is fired every time that the Go button is pressed and it is actually used to load a new URL.
06:34So we know a couple of things about this.
06:35Every time that we view a URL it's going to actually call this method.
06:39So let's now say vScrollBar.visible is going to be equal to true
06:46and then hScrollBar.visible is also going to be equal to true.
06:51Now if we save our application and then go back to Control and then Test Movie we will now see that we can load a PDF file
06:58and when it's viewed we have actually hidden the scrollbars that we added previously.
07:04And now you can see and use the scrollbars that actually are included with the PDF viewer inside of the HTMLLoader class.
07:10So now you have been able to create an application that first detects if the user has adequate support for PDFs.
07:16And you have actually created an application where they can select a local PDF from their hard drive and then view it.
07:21Now before you move onto creating applications that use PDFs there probably are a few things that you want
07:25to know about the PDF support inside of AIR.
Collapse this transcript
Limitations of PDF support
00:01Now there are a few limitations to PDF Support inside of AIR that you probably need to be familiar
00:06with before developing applications that use PDF Support.
00:09First as you have already learned, the user has to have a current version of Acrobat Reader installed,
00:15but in addition, there are other limits to the way the PDF content can be displayed within AIR.
00:20First, a PDF always sits at the top of the display order.
00:24This means that you can't create anything that actually is going to be in front of the PDF view.
00:29In addition, if you have a Custom Chrome window, you can't display PDF content inside of that window.
00:34PDF content also cannot be used in a window that is set to the Full_Screen or Full_Screen_Interactive state.
00:40Now we haven't covered these states yet, but we will actually cover them in an upcoming lesson and just know
00:45that in these cases you can view PDFs inside of these windows.
00:48In addition unlike any other element on the Stage, you can't adjust the alpha, scaling,
00:53or rotation of the PDF inside of the HTMLLoader class.
00:56And finally you must set the StageScaleMode to No Scale.
01:00However, after you know these limitations and you can develop your application around them,
01:04you can build powerful PDF Support into an AIR application.
Collapse this transcript
8. Using Native Windows
Introducing native windows
00:00Well many applications can exist with only a single window, in many cases, applications will need more than one.
00:06AIR provides robust support for applications that utilize multiple windows.
00:10In addition, AIR allows you to create windows that look and behave differently based on your needs.
00:15Also if there is not a window type that meets your needs, you can create a custom window
00:19and then implement the functionality yourself.
00:21All of this functionality is encompassed in the Windowing API for Adobe AIR.
00:26First there are some classes you need to be familiar with that we will be using throughout this chapter.
00:30First flash.display.NativeWindow and it's the base class for every window in an application.
00:36So even the windows that we have created so far, even though we have only referenced it once, actually use this class
00:43in addition flash.display.nativeWindow net options this basically just allows you to set all the options
00:49for a new window and then you can actually launch it after you set these options.
00:53Next flash.display.NativeWindowSystemChrome, it defines all the different types of chrome that you can have
01:00for your application and we will discuss more of what chrome is in a minute.
01:03Also Flash.display.NativeWindowType defines different window types, so there are different types
01:09of window that you can create within AIR.
01:11And then finally flash.display.NativeWindowDisplayState, this one defines the different display states for a window.
01:18So for example this also would include Full_Screen and Full_Screen_Interactive
01:22that we will look at later in this chapter.
01:25So AIR Window Customization, there really are three different ways that you can customize a window with an AIR,
01:30and we can change the following properties.
01:32First the Window Type, AIR gives you three different window types that you can work with
01:37and we will see what those are in a second.
01:39In addition, Chrome. Windows can use System Chrome or have No Chrome.
01:43You can create your own chrome and then implement some functionality yourself.
01:46And finally you can change the Transparent property, so that you can choose for your window
01:50to have a transparent background or if you set it to False you can have an opaque background.
01:54Let's look at the different window types, these are going to be specific to windows, the Mac windows will look similar
02:02but they all have views that are specifically tailored to OSX.
02:05Now window types are defined in the NativeWindowType class.
02:08You can see here the first we have a standard window, now up till now this is what we have worked with.
02:13You will notice that around the edge of the application, the chrome is a little bit smaller, there is not as much there.
02:19Next we have Lightweight window and you will notice that it has no chrome around it.
02:22In addition, Utility window and Lightweight window won't appear on the windows taskbar
02:26and they also won't be displayed in the Windows List for Mac.
02:30So what is Chrome? Chrome is a common layout
02:33that an operating system places around the outside of an application.
02:36Now this also helps the users to be familiar with how to interact with an application.
02:40Anyone that's use windows is going to recognize if you are on the right with the Close button with the Maximize button
02:46and the Minimize button and this is called the System Chrome.
02:50So applications that use Custom Chrome can have a custom look, but the developer will have
02:54to implement the chrome functionality with an ActionScript.
02:57The example on the right is one of the sample applications that Adobe provides with the AIR SDK
03:02that actually can be downloaded from the same site.
03:04Now applications that have Standard Chrome already have the drag, minimize, maximize,
03:08resize, and close functionality implemented.
03:10We have seen that in the applications that we have created already.
03:13So there is lot of advantage to using the Standard Chrome, but in the cases where you really want to customize the look
03:18in field, you can use Custom Chrome and then just add this functionality yourself.
03:22Next with Transparency, you can implement windows that have regular shapes as well as add filters
03:27such as a Drop Shadow to the outside of your application.
03:29So you are not limited to windows that are just rectangular, you can have circular windows,
03:33you can have windows in crazy shapes, however you would like to make them.
03:37But also note that when you turn Transparency on, your AIR Applications are going
03:41to use a little bit more system resources than they would have otherwise.
03:44Now to edit a Window's properties you can edit them inside of the applications
03:49and Installer Settings dialog box for the initial window.
03:52So in other words when you launch your application that first window you can customize everything
03:57within the application and installer settings dialog box.
03:59But please note with the window type Transparency and Chrome,
04:03these properties can only be set before opening the new window.
04:06So whether you are editing your initial window or you are creating a new window and launching it you have to be sure
04:11to set those properties before the window is actually opened.
04:14Since you now know the basics of the Windowing API inside of AIR,
04:18you are now ready to convert a single window application into a multi-windowed application.
Collapse this transcript
Creating standard windows
00:00Up to this point you have been able to create applications that utilize a single window within AIR
00:05but you are probably ready to expand and start working with applications that have multiple windows.
00:10For example the browser application that we have created utilizes a single window to load and view both HTML
00:15and PDF content but most browsers allow you to open up multiple windows to view multiple sites simultaneously
00:21so we are going to go ahead and add this functionality to our application.
00:25First we are going to need to open the file.
00:27We will go to File and then open and then we will select browserapplication01
00:32in the Chapter 8 folder of the exercise files.
00:35Now we are first going to need to restructure some elements of our application
00:39so that we can actually reuse our browser components so the first thing we are going
00:43to do is we are going to unlock our UIlayer.
00:46We are going to hit Ctrl+A or Cmd+A on Mac, select all the items in this layer and then we are going
00:51to press the F8 key and that will bring up the Convert To Symbol dialog box.
00:55We are going to name this browser be sure it is set as a movie clip, we are also going to be sure
01:02that we have checked Export for ActionScript.
01:05Now if you don't see these bottom items linkage and source you might not have the Advanced Options pushed so be sure
01:10that you click Advanced Options to see the additional items.
01:14After we check Export for ActionScript we are just going to leave the class
01:17as browser and we can just go ahead and hit OK.
01:20It will then tell us that a definition for this class cannot be found and that one would automatically be generated
01:25in the SWF file upon export and that's fine and we will click OK.
01:28Now we are going to want to select a browser application.
01:32We are actually going to move it to 00 on the Stage and now we are going to go in and position our items.
01:39So to edit this we can just double-click.
01:42Now that we have entered in we actually can be sure that everything is still selected
01:45and we will actually now position the elements where we want it to be.
01:49And that's about where they were previously and that should work fine for our application so now we are going
01:56to call this layer UI and now we can lock it.
02:00And now we are going to add an Actions layer and we will drag it
02:03to the bottom we will name it Actions and we will lock the layer.
02:08We will now go back to the root movie so we will click on Scene1 we will open the Actions layer, we will go to Window
02:15and then Actions to open up the Actions panel and then we will just press Ctrl+A or Command+A on Mac
02:21to select everything and then Ctrl+C or Command + C in Mac to actually copy everything to the clipboard.
02:27We will then close the Actions panel here, we will go into our browser by double clicking on the browser symbol,
02:33we will go to the Actions layer that we just created and then we will go to window and then actions
02:39and then we will paste everything by pressing Ctrl+V or Command+V on Mac and we have see
02:44that we have pasted in everything just as it was.
02:47Up to this point we haven't changed anything so now let's actually save our application,
02:52we are going to close this Actions panel, we will go Scene1 and we can go ahead
02:57at this point and delete all of the existing actions.
03:00So we will go back to Window Actions everything if it's still selected you can just press the Delete key,
03:06if not you can press Ctrl+A and select everything or Command+A on Mac and then press Delete.
03:11Now we can close this Actions Frame, we can press Save and now we can go to Control and then Test Movie.
03:17And we can see here that the core visual elements of our browser have been preserved.
03:24It's still able to load a URL so it has the scroll bar, still has the forward and back buttons,
03:29still has the Load PDF button- everything that we have expected from our browser is still functional.
03:35But we have actually now encapsulated it inside of a symbol so that it can be reused.
03:40Now at this point we are going to need to add one more button to our browser application so now instead
03:47of actually working here in the root movie to work with the browser we are going to double click on the browser symbol.
03:53Now we are going to actually move the forward and back buttons a little bit closer together
03:57so to accomplish this we are going to unlock the UIlayer
04:01and we will move the Forward button a little bit closer to the Back button.
04:05We will now highlight the URL input, select the Free Transform tool, hold down Alt on PC or Option on Mac
04:13and we will just drag it a little bit and leave it in for another button.
04:16Now we can open up the Components window by going under Window and then Components and now we want to drag
04:22out another instance of the button onto Stage.
04:25Now we can close the Components window, we are going to give our new button an instance name of New Window Button
04:34and then we will click on the Parameters tab and of the label we will actually just put in a plus symbol
04:40and we will also change the width of this particular item to 30.
04:45Now we can actually move it around to position it where we would like.
04:48I am actually going to be sure that it's going to be aligned with all the other items currently on the Stage.
04:55We will align it to center and then we will select the URL input one more time, select the Free Transform tool,
05:02hold Alt on PC or Option on Mac and actually move it back over.
05:05Now we are going to need to go into ActionScript and actually put in the codes
05:14that we can create a new window every time the new window button is pushed.
05:17So what we are going to need to do within the symbol, within the browser symbol we will select the Actions layer
05:24and we also can go ahead and lock the UI layer and then we will go under Window and then Actions.
05:29We are going to need to add an event listener for our New Window button.
05:33So we will say newWindowButton.addEventListener and we are going to listen for the MouseEvent.CLICK event.
05:42And then we are going to actually call the method onNewWindow so now we can scroll
05:50down to the event handler section and we will create a new method onNewWindow.
05:59It will receive an event of type MouseEvent and it's actually not going
06:03to return anything so we can set the return type as void.
06:06Now we are going to need to start the process of creating a new window.
06:11But to do this we are going to need to be sure that we have some classes imported so we will scroll back to the top.
06:17Now all the classes that we need actually exist in the flash.display package
06:23and as you can see we have already imported all of those items. So we are not going to have any additional items
06:29to import but just be sure when you are working with the NativeWindows that you are going to specifically need
06:34to be sure that you have flash.display.NativeWindow as well
06:37as flash.display.NativeWindowInitOptions so let's scroll back down to our method.
06:42Now the first thing we are going to need to do is to create a new instance of the NativeWindow init options
06:50so I will say var options it's going to be of type NativeWindowInitOptions and that's going
07:00to be equal to a new NativeWindowInitOptions.
07:05Now this is just going to enable us to set different values for the window before it launches.
07:13The first thing we are going to do is actually set the system chrome so we will say options.systemChrome
07:19and we are going to set that equal to NativeWindowSystemChrome.
07:25and we are just going to use standard.
07:30Next we are going to want to actually set the transparent value
07:36and in our case we are not using transparency so will just set that equal to False.
07:43Next we are going to change a few specific items that we have discussed previously.
07:47Now when we wanted our default windows to not be maximizable and to not be resizable we could adjust those values inside
07:53of the Application Descriptor file by using the application and installer settings dialog box inside of Flash.
07:59However in this case for a new window that you create you actually have to set those values
08:03with the NativeWindowInitOptions so we will say options.resizable is going to be equal to false
08:10and options.minimizable is going to be equal to false as well.
08:15Now that we have set most of the options we are actually ready to create our new NativeWindow.
08:20So we will say var window of type NativeWindow is going to be equal to a new NativeWindow.
08:28And to the constructor we are actually going to pass in our options variable.
08:33And this is how you actually pass your NativeWindowInitOptions into the new NativeWindow.
08:41Next we are going to need to actually set the width and height of the window so we will say window.width is going
08:47to be equal to 800 and then window.height=600.
08:55Now there would be another step that we would need to take but since we have already within our symbol actually set
09:01up the Stage properties for Stage.ScaleMode and Stage.Align we don't have to worry about setting those up again here.
09:11And now we need to actually add our browser to the new window so we are going to say var b and that will be
09:17for browser and this again is the symbol that we just created and that's going to be equal to a new Browser.
09:24And then what we are going to do is there is a Stage property inside of each window
09:30and we can just say window.stage and then just as we would add an item to the display list we are going
09:35to do the same thing here with the addChild method.
09:38We will say addChild and then just pass in P. Now the last thing we will need to do to actually open
09:44and activate the window is to use the window.activate method.
09:52Now let's review what we have done in this method.
09:54First we have created a new instance of the NativeWindowInitOptions class,
09:58we have set the SystemChrome, the transparent property, the resizable property as well as the minimizable property.
10:05We then created a new instance of the NativeWindow class and set the width and height.
10:09We have then added an instance of our symbol to the Stage of the new window and then we have activated the window
10:15which actually launches the new window and makes it the active window in the application.
10:19So now we are actually ready to jump in and test our application and see how it works.
10:24I will first save my application and then I will go to Control and then Test Movie to launch our application.
10:33So now we can see that we have our plus button here on the Stage.
10:36We can see that our browser still works even though we have now encapsulated it into a symbol
10:40and if we press the New Window button we now open up a new window that does the same thing
10:44and we can open up as many windows as we would like.
10:47Each of these can now view a different web page and in addition we can still use the Load PDF functionality
10:55to load a PDF from the local hard drive so we have now created our first multi-window application
11:01that uses the NativeWindow class as well as the NativeWindow init options inside of Adobe AIR.
11:07Now that you have done a standard window we will actually move onto working with some more complex situations
11:11where you would use some different properties for SystemChrome and for Transparent.
Collapse this transcript
Creating windows with custom chrome
00:00Now in many cases, you will want to give your application a custom look and feel.
00:04Now in these cases, you can use Custom Chrome. The important thing to know here is that this isn't ideal
00:09for all applications, you are going to be creating an interface that the user is not familiar with But in cases
00:15where you really need to provide a custom experience for the user, Custom Chrome is one of the best ways to do it
00:20and it gives you a level of customization not possible any other way.
00:24So we are going to go ahead and take our browser application and we are going
00:27to go ahead and make it work with Custom Chrome.
00:29So let's go ahead and open the file.
00:31We will go to File and then Open and then we will look in the Chapter 8 folder of the exercise files
00:36and we will go to Browser Application 02.
00:38Now we are going to need to adjust some elements within our browser movie clip,
00:44so let's go to the library, find Browser and double click.
00:47Now that we have loaded up our browser movie clip, we are going to need to create our Custom Chrome.
00:53So I am going to create a new layer and I am just going to call this BG for background.
00:58We are now going to drag out a rectangle, so I am going to select a rectangle tool and for this case,
01:02I am going to be sure that the Stroke is set to black and for the Fill Color, I am just going to select a dark grey,
01:09but then I am also going to go in and be sure that the Alpha is set
01:12and we will probably drop it down it down to be at 50%.
01:15Now we can go ahead and drag out our rectangle.
01:20Now in this case, I am just going to drag out a small rectangle and then I am going to be sure
01:24that we highlight the whole thing and then we are going to go in and set the width and height.
01:28The width of our entire application is 800, but we are going to set the width
01:31of the background to 790, I will explain why in a minute.
01:35And then for the height, we are going to set it to 590, so we are actually leaving 10 pixels, 5 on each side.
01:42Now we are actually going to want to set this at 5 and 5,
01:45so that we have left some additional space on the edge of our application.
01:49Now we are actually going to convert this background into a movie clip, be sure that we have it selected
01:55and then we will press the F8 key to bring up the Convert to Simple dialog box.
01:59We will just call this for the moment BG, we will leave it as a movie clip
02:03and then we will be sure to give it an instance name of BG.
02:06Now we are going to go ahead and add a filter.
02:09One of the things that we discussed earlier was that we have the capability now to add a filter to our Custom Chrome,
02:15so let's click on Filters, we are going to add a Glow and in this case I am just going to select black and we are going
02:23to be sure that we set quality to High and this will give us a shadow around the edges of our application
02:28and this is the reason that we also didn't have our background take up the entire width and height
02:33of the application to leave room around the edges for the shadow.
02:36At this point, we could launch our application, but we will still have the Standard Chrome set,
02:41even if we went and change the Open New Window option.
02:44So the first thing, we are going to do is change the properties for the initial window that is opened.
02:49So in this case, we can go under Commands, AIR Application and Installer Settings
02:54and we are going to change the window style.
02:57At this point, it is set to System Chrome.
02:59We are going to change it to Custom Chrome, Transparent.
03:03Now what this does is this actually sets multiple properties.
03:06It sets transparent=true and then it sets the systemChrome=none.
03:12So let's go ahead and select that value and then we will click OK.
03:16In addition, we are also going to need to go into our Actions layer,
03:19so let's highlight the Actions layer and go to window and then Actions.
03:23We will scroll down to our onNewWindow method which can be found in the Event Handler section.
03:28And the first thing that we are going to do is we are going to change the options.systemChrome instead
03:32of saying NativeWindow.systemChrome.STANDARD, we are going to say NativeWindow.systemChrome.NONE.
03:38And we are also going to want to change the Transparent property, so we will say options.transparent=true.
03:46Now we can save our application and we are going to go to Control and then Test Movie.
03:53We can see now that we actually have a Transparent and Custom Chrome application.
03:58We can see here that we can actually see under our application,
04:01we can see the items there, because our application is transparent.
04:04We also can see that around the edges of the application we have a very light shadow.
04:08However if you notice we now can drag our application anywhere.
04:12We also can close our application by using the normal Close button, so we are going to need to add some functionality.
04:17If you ever run into a situation where you have a window open like this, if you are on Windows you can just go
04:22to the taskbar right click and go to Close or in Mac you can go to the Dock and do the same thing.
04:27So now we are going to add some functionality to our Custom Chrome application.
04:31We want to be able to drag our application around, we also want to be able
04:34to close our application as well as minimize it.
04:38Now when you are working with Custom Chrome and you actually have to replace some of the chrome functionality
04:43with your own code, there are methods that are provided by AIR that will allow you to achieve the same functionality.
04:48First NativeApplication.exit allows you to actually close the entire application.
04:54NativeWindow.close actually closes the current window.
04:57NativeWindow.startMove allows the user to actually drag the window, so this way a user could actually click
05:03on your Custom Chrome and drag your application around the screen.
05:07NativeWindow.startResize allows the user to actually resize the window, so you could actually then wire this function
05:14in with width and the height of the Nativewindow.
05:17NativeWindow.maximize allows the user to maximize the window
05:20and NativeWindow.minimize allows the user to minimize the window.
05:23So by using these functions, you can get the same functionality that is provided with the Standard Chrome.
05:30So now within our browser application, we are going to go ahead and lock the BG layer.
05:34We are now going to move the items in the UI Layer down just a little bit, so I am going to press Ctrl+A
05:41to select everything on this layer and we are just going to move everything down,
05:44because we want to add room for some new buttons.
05:46In addition, after we have done this we will have to go in and actually reposition our HTMLLoader object as well.
05:52So first we are going to be sure that we are still on the UI layer, we are going to open window and then components
05:57and we are going to drag two instances of the button out onto the Stage.
06:00The first button, we are going to actually call the Close button and that will be the instance name.
06:08And instead of actually writing close inside of this, we are just going to use an X
06:13to almost make it mimic what would be in the Standard Chrome.
06:16We are only going to set the width here to 30 and we are going to select the next button and we are going
06:20to give it an instance name of Minimize button.
06:23We are going to set the width to 30 and we are going to be sure that we set the label here to underscore
06:31to also attempt to mimic what would normally be in the Standard Chrome.
06:35Now we can actually position our two elements on to the Stage.
06:45And I will just select both of these buttons, be sure that they are aligned to center and we will move them
06:51over just a little bit so that they are even with the right side of loaded PDF.
06:55Now we actually can begin working with these methods inside of ActionScript, so we can go ahead and lock the UI Layer,
07:01highlight the Actions layer and then we will go to Window and then Actions.
07:05As I stated earlier, the first thing you are going to need
07:07to do is reposition our HTMLLoader object, so let's scroll up for that.
07:12Now here you can see that we have set the width and the height and the x and y value for the HTMLLoader.
07:18In this case, we are just going to bump up the htmlLoader.y value to 75.
07:24Now we are actually going to put in the functionality that we need for our Close and for our Minimize button,
07:28so first we will need to add an event listener, so we will scroll down to the section where we add event listeners
07:32and we will create two new event listeners, first for Close button and then we will listen for the MouseEvent.CLICK event
07:45and then we will call the onCloseClick method which we will implement shortly.
07:51Then we have our Minimize button.
07:53We will do the same thing for it.
07:55We will add the event listener.
08:02We will listen for the MouseEvent.CLICK event and then we will actually call the OnMinimizeClick.
08:14So now we actually can implement these methods, so let's go to our Event Handler section.
08:17We will scroll down.
08:20The first one that will implement would be onCloseClick and then we will receive an event that will be
08:29of type MouseEvent and it's not going to return anything, so we can set the return type to be equal to void.
08:35Now at this point, what we are going to need to do is actually get the current NativeWindow
08:40that can be accomplished by going to Stage.NativeWindow and then we will call the Close method.
08:47Now we are going to need to implement our Minimize button, so we will see onMinimizeClick.
08:55It will receive an event of type MouseEvent.
08:59It's not going to return anything, so we can leave the return type = void.
09:04Now inside of here what we will do is we will call Stage.NativeWindow.minimize.
09:11Now there is one last thing we need to do, we stated earlier that we wanted to be able to drag our application around,
09:18to do this we are going to need to listen for a specific event on our BG layer.
09:22So we will go up and we will call BG which again is the instance name
09:27of our BG movie clip, we will add an event listener.
09:32We will listen specifically for the MouseEvent, instead of click this time we will be listening
09:37for mouse down and then we will say onBGMouseDown.
09:40We will highlight the name of this method and we can use it
09:47when we actually create the method, which is what we will do now.
09:49We will scroll down in the Event Handler section, we will create a new method Function on BGMouseDown
09:57and it will receive an event of type MouseEvent and the return type will be void.
10:04Now we just need to call one method to implement this, we will say Stage.NativeWindow.StartMove.
10:15Now this will ask to start the dragging, you don't have to call a NativeWindow.StopMove.
10:20AIR actually is intelligent enough to detect when the user stops dragging the application.
10:23Se we will now save our application and go to Control and then Test Movie.
10:29First, we should be able to click anywhere on our background
10:32and actually drag our application around which we can indeed do.
10:35We also should be able to go to our Minimize button and we should be able
10:38to click it and actually minimize our application.
10:41Finally, we should be able to actually close our application by clicking the Close button.
10:46So at this point we have created an application with Custom Chrome.
10:49We have mimicked several functions of the Standard Chrome.
10:52We have actually enabled a Close button, a Minimize button as well being able
10:55to drag the application around the screen.
10:58We have also created a transparent background that allows us to also add a custom filter
11:02so that we can have a custom glow on our application.
11:04Now again this is a very powerful feature that needs to be used only when needed
11:08because again we are creating an interface that the user is not familiar with,
11:12but in situations where you want a deep level of customization, Custom Chrome can provide that for you.
Collapse this transcript
Creating resizable windows
00:00In most cases, you will want to preserve the experience that the end user is familiar with.
00:05With this being true, most users are used to having windows that are resizable
00:08when you are using the standard system chrome.
00:10Now, responding to the resize event from the Native window, you can create windows that are resizable
00:15and resize the elements on the Stage accordingly.
00:17So let's go ahead and open up a file to work with.
00:19We will go to File and then Open and then we will open the Browser Application 02 file
00:24in the Chapter 8 folder of the exercise files.
00:27Now, the first thing we are going to need to do is go into our Browser symbol.
00:33So we'll double-click on the browser movie clip and then we go to the Actions layer
00:36and then we go to Window and then Actions.
00:39Now, we are going to want to listen inside of this movie clip to the resize event
00:43that gets dispatched by the NativeWindow.
00:44To do this, we are going to say stage.nativeWindow and this is how you get the current NativeWindow
00:51that this movie clip is in and then we are going to say addEventListener and then from here,
00:56we are going to listen for the Event.RESIZE and we are going to respond to that with a method onWindowResize.
01:06So now we can scroll down to our Event Handler section and begin working with that event.
01:11We will create our new method onWindowResize and it's going to receive an event of type event and it's not going
01:22to return anything so we can leave the return type void.
01:24Now, what we are going to want to do is resize any elements that need to be resized every time
01:32that somebody actually drags the corner of the application to resize it.
01:35The first thing that we are going to need to do is we are going to need allow users to resize our window.
01:39We currently have that disabled.
01:41If we go under Commands and then AIR Application and Installer settings,
01:45we'll need to go to the Advanced Settings and then we need to check resizable and then we can click OK.
01:52Now, let's take a look at our application.
01:54If we go to Control and then Test Movie, we can see that right now we can't drag the corner of our application
02:02but obviously nothing changes when we drag the corner because we have set the Stage scale mode to none.
02:08What we would like to have happen is every time we drag the corner of the application,
02:12we would want the HTMLLoader to actually grow with the application.
02:16We would want the URL input value to actually grow with the application and then the loadPDF
02:22and goButtons to actually move with the URL input.
02:25In addition, we want the scroll bars to maintain their functionality as well.
02:29So let's actually see how we can implement that in our application.
02:32I am going to go ahead and close the application and go back to the Actions panel.
02:36The first thing that we are going to need to do is scroll up and look at our HTMLLoader object
02:40when we actually positioned it on the Stage.
02:43You can see here that we already have set the width and height values in respect
02:47to the Stage width and Stage height values.
02:50This is important.
02:51When you are resizing an object, you can't use absolute values,
02:55so you couldn't set the width to 650 and the height to 400.
02:59In those cases then, when you went to resize it, it wouldn't actually scale with the application.
03:03But if we create things that are relative to the Stage width and Stage height,
03:07then we can know that these values can scale as the application scales.
03:12So I am going to highlight these two lines and we are actually going to reset the width and height
03:16of the HTMLLoader object every time that we resize the window.
03:21So let's scroll down and in the onWindowResize, we are going to paste these values in.
03:26Next, we are going to need to position the PDF button, the Go button and the URL Input value.
03:32Well, let's take a look at our application.
03:37The first thing that you will notice is the Load PDF button is up to the edge
03:41of the Stage with a little bit of padding in between.
03:44So we know that we can position everything off of this button as long
03:48as we set it off a certain number of pixels from the Stage.
03:51So let's go ahead and do that.
03:52Now, to accomplish this, we are first going to say pdfButton.x
04:00because the x value is the only value that's going to change in the PDF button.
04:03We are not going to make it bigger, we are not going to make it smaller, we are just going to move it.
04:07So we will say pdfButton.x is going to be equal to Stage.stageWidth.
04:13But then we are going to want to actually subtract a little bit so that it's back from the edge of the Stage width.
04:20So we will say we want 10 pixels off the edge.
04:23Now, in addition to that, because the x value occurs at the top left of the PDF button, we are also going to want
04:30to subtract the width of the PDF button itself.
04:38Now, in addition, we are going to want to position the Go button next to the PDF button.
04:43So we will say goButton.x is going to be equal to pdfButton.x and then we are going to want
04:51to have a little padding between those buttons as well, so we will say -10.
04:55From there, we are going to subtract the goButton.width.
04:59Now, the final thing that we are going to need to set is the width of the URL Input.
05:07So we will say urlInput.width because here unlike with the PDF button and the Go button, we do want the URL Input
05:17to shrink or to grow depending on how we are dragging the application, so we will say urlInput.width is equal
05:23to goButton.x. And then we want to subtract the little bit of space for padding.
05:28So we will say -10 and then we want to subtract the urlInput.x value.
05:34Now, we can actually test our application and see how things are working so far.
05:42We will go to Control and then Test Movie.
05:45Now, if we move to the bottom right corner of our application and we start to drag,
05:52you can see that indeed a couple things are happening.
05:55First, we are actually scaling the URL Input as well as the Go button and the PDF button.
06:02You can also see that we are scaling the HTMLLoader but our scrollbars are remaining the same.
06:07So we are going to have to reposition our scrollbars as well.
06:10Now, to accomplish this, we actually can copy some more code that we have already written.
06:17So let's scroll up to where we created our scroll bars.
06:20Now, what we are concerned with here are three values.
06:25For the vScrollBar, we are concerned with the x and the y values.
06:29We want to be sure that it's still positioned directly to the right of the HTMLLoader.
06:33In addition, we are also concerned with the height.
06:35We want to be sure that if we make the HTMLLoader taller
06:39that the vScrollBar still goes the entire height of the HTMLLoader.
06:43So we will highlight these three lines, we will copy and the important thing
06:48to note here is again we define the scrollbar in relative terms to the htmlLoader.x and y and width properties.
06:56By doing this, as the HTMLLoader grows, the scrollbars can also update themselves.
07:00So we will scroll down to the onWindowResize method and we will paste these values in.
07:09Next, we will do the same for the hScrollBar.
07:13In this case, we are concerned with the x and y properties and the width.
07:16So we will select these three and we will go down and paste them into our onWindowResize method.
07:28Now, we'll need to call one last function.
07:30We will need to call the updateScrollBars method.
07:32This way, the scroll bars will be updated with the new position of the HTMLLoader.
07:41Now, if we save our application and test it, we can see
07:50that indeed we can now scale our application, we can make it resizable.
07:54You will notice that the application grows and shrinks.
07:57You will notice that the URL Input grows as the application grows.
08:02You will notice that the Go and Load PDF buttons move with it.
08:05You will also notice that the HTMLLoader container grows and the scroll bars actually follow suit
08:12and grow to the appropriate size and also adjust themselves automatically.
08:16As we shrink the application, the track and the scrollbar get smaller and as we grow it, it gets larger.
08:23So now, you know how to create resizable applications within AIR by responding
08:27to the Resize Event from the NativeWindow class.
08:29We are now ready to move on to working more with Windows inside of AIR
08:33and moving on to some more advanced functionality.
Collapse this transcript
Creating full-screen windows
00:00In some situations, you want to be able to create windows that are full screen, up to this point you have been able
00:05to maximize windows, which causes a window to take most of the screen
00:08but you still have the System Chrome around the edge.
00:10But AIR gives you the capability to create full screen windows that actually take
00:14up the entire screen without any System Chrome around.
00:17Now, this creates an immersive experience that needs to be used carefully.
00:20But when used properly it can provide a very positive experience for the end user.
00:24So, we are going to go ahead and add full screen capability to our browser application, so let's go to File
00:30and then Open and we are going to open BrowserApplication03, which is the Chapter 8 folder of the exercise files.
00:38Now, we are going to go ahead and double click our browser movie clip and we are going
00:42to change some of the functionality of our application.
00:45Currently, we have a Go and Load PDF button. We're going to go ahead and look at our Load PDF button,
00:50we are going to unlock the UIlayer and we are going to change its instance name to fullScreenButton.
00:56In addition, we are going to change the label, so we will go to the parameters tab, we will make the label Fullscreen.
01:05Now, we are going to need to go into the ActionScript and remove any references to the PDF button.
01:11Now, this will occur in several places, so let's highlight the Actions layer and we will go to Window
01:16and then we will go to Actions and let's scroll down first and we will just go ahead
01:22and delete the event listener for the PDF button.
01:26In addition, we will need to go to our onresize event and while we are going,
01:30we actually can delete the onPDFClick, and onPDFSelect methods.
01:34And every time we see pdfButton here, we are going to need to replace it with fullscreenButton.
01:43And so I will just copy to fullscreenButton and we will paste it over all the references to the pdfButton.
01:48Now, we know that we have deleted all of the important references, if we can still run our application.
02:05If it throws an error that means we might have missed one; so let's Control and Test Movie and we can see
02:11that indeed there wasn't an error because there were few more places that we needed to delete it from.
02:15If we look at the compiler errors, we can tell that it gives us lines 159 and 161, so if we scroll down
02:21and look at those lines, we can see again we had our checkPDFSupport method.
02:26We actually can delete this method all together and then we can scroll back up to the top
02:31and we can remove this from our initialization methods.
02:36Now, we can save our application and test it again and we can see now that everything lies properly,
02:42so we have removed all the references to the PDF button.
02:46Now, if we go back to our application, we are going to need
02:48to know implement some functionality for our Full Screen button.
02:51So, we will go to the Add Event Listener section and we will create a new event listener for our Full Screen button.
02:57fullScreenButton.addEventListener and we are going to listen for the MouseEvent.CLICK event and we are going to respond
03:07to this with the onFullscreenClick method.
03:13So, now we can highlight the name of that method, we can copy it and then we can go down to our Event Handler section
03:21under the onWindowResize and we can say, onFullscreenClick that's going to receive an event of type, Mouse event,
03:31that's not going to return anything, so we can leave the return type as void.
03:35Now inside of here, what we are going to use is the StageDisplayState class.
03:40Now, this is important that you need to have this class imported, it actually is in the flash.display package.
03:46And if we look at our imports, we can see that that actually has already been imported, the entire package.
03:51But if you don't have the entire package imported then you will need to be sure
03:54that you import the StageDisplayState class.
03:57If you now scroll back down to our onFullscreenClick method, we are actually going to now check
04:03and see what state the application is in. So we will say if stage.displayState,
04:09which is the property that defines the current display state of the application,
04:13if that is equal to StageDisplayState.NORMAL, which is the default value. If that's True,
04:24then what we are going to want to do, is we are now going to want
04:27to set the stage.displayState = StageDisplayState.FULL_SCREEN.
04:39Now, in addition we are also going to want to change the label of the Full Screen button,
04:46so we will say fullscreenButton.label = End FullScreen.
04:54This way the user can know that the button will now function differently by taking them out of full screen mode.
04:58Now, we are going to also put in an else statement because if the display state is not in the normal property then
05:05at this point we are in the full screen mode and so we are going to want
05:08to say stage.displayState is going to be equal to StageDisplayState.NORMAL.
05:19Now, we notice one error we made up here, currently,
05:23we are saying if stage.DisplayState equals, using the comparison operator, StageDisplayState.NORMAL
05:29and that is correct.
05:29But under, we actually want to use the assignment operator,
05:33so we'll say Stage.DisplayState=Stage.DisplayState.FULL_SCREEN,
05:37just as we have done down here with Stage.DisplayState=Stage.DisplayState.NORMAL.
05:43And here, we are also going to want to change the label back.
05:45So we will say fullscreenButton.label is going to be equal to Fullscreen.
05:52So, we will set it back to its default value. And I see just another quick typo.
05:56You need to be sure that we type fullscreenButton.
05:59So, now we actually have implemented the functionality to take an application and make it go full screen
06:04by pressing a button, so let's test our application and see how it works.
06:07I will first save the application and then I will go to Control and then Test Movie.
06:11We can see now that we have the fullScreen button and if we click it, our application takes up the entire screen
06:19and because we actually have made a resizable window, it also resizes to the proper size.
06:23However, there is one thing to note here, we can click here on the URL input, but we can't type anything.
06:29If we click the search box inside of the web page, we also can't type anything,
06:33that's because there are actually two different full screen modes.
06:36The current mode that we are in,
06:37StageDisplayState.FULL_SCREEN, has also been available in Flash for sometime.
06:42However, now we actually have the ability inside of AIR to use a new display state full screen interactive;
06:48that allows for the user to also interact with your application while it's in full screen mode.
06:53So, let's look in full screen and then click the Close button and now let's go back to our onFullscreenClick method
07:00and instead of saying StageDisplayState.FULL_SCREEN we will say StageDisplayState.FULL_SCREEN_INTERACTIVE.
07:09Now, we can hit Save and we can now go to Control and Test Movie and now when we click Fullscreen,
07:19we will now be able to not only see the application in full screen mode,
07:23we will also be able to interact with it as well, now we will click Go.
07:29And you can see there, now we have gone to Google's page and we can see that now we can interact with the application
07:34in full screen mode, so we can now click in fullScreen and now we can close our application.
07:40Using the full screen modes, should be used sparingly.
07:42Again most users don't like it when their entire desktop is taken
07:45over by an application, unless that's explicitly what they want.
07:49It can be a great feature to enhance an application but in most situations, you shouldn't play in for you application
07:54to just automatically operate in full screen mode and now that you know how to use full screen mode,
07:58we are going to work with the few more properties of NativeWindows inside of AIR.
Collapse this transcript
Setting a window to always be on top
00:00In some situations, you are going to want a window of your application to always reside on top of other windows
00:06that are being displayed by the operating system.
00:08The nativeWindow class actually gives you a property alwaysInFront that allows you to set this value.
00:14So let's go ahead and open up a file to accomplish this.
00:16We will go to File and then Open and then we will open up Browser Application04
00:21in the Chapter 8 folder of the exercise files.
00:23Now in this case, we are going to double-click on our Browser movie clip and we are going to scroll over
00:28and we will see that we have our Full creen button.
00:30We are actually going to change this button to be our alwaysInFront button.
00:37We are also going to change the label. So we'll go to Parameters and we will say Always In Front.
00:43And we are also going to make this a toggle button,
00:46so we are going to go where it says Toggle and we change that from False to True.
00:50Now we can actually go into our Actions layer,
00:53so we will highlight the Actions layer, lock the UI Layer, go to Window and then go to Actions.
00:58The first thing that we are going to have to do is remove any references to our Fullscreen button,
01:02so we will scroll down, we will find our fullscreenButton addEventListener. We will delete that event listener.
01:07We will also scroll down to our event handlers and we will delete the onFullscreenClick method.
01:14Now we actually can scroll up and we can actually go back to the section where we add our event listeners.
01:21Now here we are going to want to add an event listener for our alwaysInFrontButton.
01:29And we are going to listen for the MouseEvent.CLICK event.
01:35We are going to respond to that with an onTopClick method,
01:40because this method will allow the window to actually remain on top.
01:43So let's scroll down to our Event Handler section, we will create a new method OnTopClick
01:52and it's going to receive an event of type MouseEvent.
01:56It's not going to return anything, so we can leave the return type as void.
02:00Now inside of here, we are going to want to check and see what the current alwaysInFront value is set to.
02:05So we will say, If we are going to want to a get to a reference of the current nativeWindow
02:10that this movie clip is in, so we will say stage.nativeWindow
02:14and then we are actually going to check the alwaysInFront property.
02:20We will say if that is equal to True then we are actually going to set it equal to False
02:26then we'll say stage.nativeWindow.alwaysInfront = false.
02:36But if it's not, then we are going to want to set it to stage.nativeWindow.alwaysInfront=true and that's all we need
02:48to do to actually implement this functionality.
02:50So we can save our application, go to Control and then Test Movie, oops! And we do have an error that we have run across.
03:00We have one additional place that we have added the Fullscreen button and that's actually
03:04in the onResize method so let's go and actually replace every instance
03:07of the fullscreenButton with our alwaysInFrontButton.
03:13We will just copy this and paste it everywhere the fullScreenButton appears.
03:26And be sure that we have referenced all of them just by looking over the method
03:29and now we can save our application and go to Control and then Test Movie.
03:33We can see now that it appears with no errors and that's what we want.
03:39Now to illustrate this functionality, I am also going to go ahead and open up another window.
03:43I am going to open up Internet Explorer.
03:48So we will go and we will visit Google here on Internet Explorer and we will notice
03:53that this window right now currently resides directly beside our application and when we click on our window,
03:59it will be in front of it, but then when we click back on Internet Explorer, it will go in front of our application.
04:04However, if we go back to our application and we click alwaysInFront, we now can click on Internet Explorer
04:10and you will notice that it remains behind our application.
04:13As a matter of fact, no matter how many instances we open up,
04:16this window that we have created will always be in front of other windows.
04:20But if we disable this button, if we untoggle it, we will now notice that we can click back on Internet Explorer
04:25and it will actually go in front of our application window.
04:28So the nativeWindow.alwaysInFront property allows you to create a certain window
04:33that will always be in front of other windows.
04:35This can be very useful if you are creating an application that is going to reside
04:39on the user's desktop while they are working within other applications.
04:42Again this is another bit of functionality that's added to you
04:45within the nativeWindow class in the windowing API of Adobe AIR.
Collapse this transcript
9. Managing Multiple Windows
Showing and hiding windows
00:00Now we have already worked with many different ways to show and hide windows within AIR.
00:04And so we are going to review these and look at a few more.
00:07First the nativeWindow.activate method brings the window to the front and makes the window visible.
00:12Now if you have created a nativeWindow and have not
00:15yet opened it this will actually create the window and open it as well.
00:19nativeWindow.maximize maximizes the current window, nativeWindow.minimize minimizes the current window.
00:25Now we have used both of those already within our code.
00:28And nativeWindow.restore returns the window to it's previous state either before it was minimized or maximized
00:34so let's look and see how this works within an actual application.
00:38Now that we are in Flash I am going to go ahead and open up a sample application that utilizes these methods.
00:44First I am going to go to File and then Open and then in the Chapter 9 folder
00:49of the exercise files I am going to open BrowserApplication01.
00:53Now in this application we actually have the capability to test and see what these methods are going to do
01:01so let's go ahead and go to Control and then Test Movie.
01:04This is the same browser application that we have seen previously.
01:09We are going to go ahead and hit the Plus button to create a new window.
01:14However, now instead of seeing a new browser window we have the show and hide methods that are going to allow us
01:20to interact with the window that will soon be opened.
01:23First we can choose to activate the new window and the window has then been launched because it
01:28yet hadn't been made visible by calling the activate method we actually made the window visible.
01:33Now if we choose to maximize the window it's actually going to take up the full size of the screen.
01:39Now the important thing to note here is it this will happen even when we are on Mac OS X. Normally
01:45on Mac OS X the Maximize functionality does not work this way.
01:49Usually the user is able to set a preferred size and then by going to Maximize it will actually go
01:54to that preferred size, however, with AIR in Mac OS X the Maximize function works the exact same way
02:01as it does on the PC version.
02:03In addition to the maximize method we can then restore and it will put the application back
02:08to where it was before the Maximize command.
02:11In addition we can call the Minimize command and it will actually minimize the window
02:15and then we can use restore to bring the window back.
02:18Finally we could call the closeApplication and it actually would close everything within the application.
02:25So let's look and actually see the code that accomplished that.
02:28This was actually contained in a movie clip called Show Utility.
02:33Now if we open up the Actions layer by highlighting the Actions layer and then going to Window
02:38and then Actions we can see the code that actually made this possible.
02:41First we imported the NativeApplication class.
02:45Then this particular symbol has a reference to a window.
02:48And we actually passed in the window that was to be launched.
02:51Finally we created a combo box with an event listener that fired the onActionBox method.
02:57And we can see here that just as we learned previously
02:59to maximize the window we called the nativeWindow.maximize method
03:04and the same thing for minimize, restore and activate.
03:08So with this code you are able to actually control how a window is displayed and how it's interacted with.
03:14You can utilize this with custom chrome as we did previously but you also can use this as a way to communicate
03:19between different windows of an application.
03:22When a user opens one window you can automatically minimize another or if you knew that a user was going
03:27to need a certain tool palette that was available in a different window you actually could bring that one
03:31and make it visible when they open another window.
03:33This level of support provides and additional capability
03:36that the developer can take advantage of inside of the Windowing API with AIR.
Collapse this transcript
Changing window order
00:00In addition to being able to show and hide specific windows that you have opened for your application,
00:05there are times when you are going to want to change the order that these windows appear.
00:08Now to accomplish this, AIR provides several methods that are all methods of the NativeWindow class.
00:14For example, we have NativeWindow.orderToFront and this is going to bring the window
00:18in front of all other application windows.
00:21So if there is ever a point when you want one application to move all the way into the front,
00:25in front of all your application windows as well as any other operating system windows, you can use this method.
00:30You also can tell a specific window to go in front
00:33of another specific window, this is the NativeWindow.orderInFrontOf.
00:38Next you can actually move a window to the back behind all other opened windows
00:42in the operating system, this is NativeWindow.orderToBack.
00:46Next you have NativeWindow.orderBehind which works similar to the orderInFrontOf method
00:51in that you can move a window behind a window that you actually pass in as a parameter.
00:56And then finally, and we have seen this one before NativeWindow.activate brings the window
01:00to the front and makes it visible.
01:02This can actually be used to launch a window that has not yet been made visible.
01:07So now let's go back to Flash and actually see how this works within in an application.
01:11Now let's go ahead and open up the application file.
01:14If we go to File and then Open then we are going to open browser Application02
01:19in the Chapter 9 folder of the exercise files.
01:22Now we are going to double click on the Browser symbol in the library.
01:27Now we are going to change this Fullscreen button to actually be a Move To Back button.
01:37In this way, when we actually press this button, it will move our current window to the back
01:42of the display order for all of the windows.
01:44So now we are going to need to go in and adjust a little bit of the code removing any references
01:51to the Fullscreen button and will also want to change the label to Move To Back.
01:57So now let's highlight the Actions layer and then we will go under Window and then Actions.
02:02We know that first we added a reference to the Full Screen button in the event listeners, so we will remove that.
02:17We also know that we have a reference inside of the onWindowResize method, so we will go ahead and rename that.
02:25And we can then just copy and then paste that over the other references.
02:29Next we can actually remove the onFullscreenClick method.
02:46And then finally, we should be ready to add the information to actually move our window to the back,
02:51so let's go to the section where we add our event listeners and we are going to say moveToBackButton.addEventListener
03:01and then we are going to listen specifically for the MouseEvent.CLICK event.
03:09And then we are going to actually fire the onMoveToBack method.
03:19So now we can go to the section where we have our event handlers, we will move to the end,
03:24we will create our new function onMoveToBack.
03:25And then this will receive an event of type MouseEvent and it's not going
03:36to return anything so we can leave the return type void.
03:42Now we are going to want to get a reference to the NativeWindow the current window that we are
03:46in which can be found as stage.nativeWindow and then we are just going to need to call the orderToBack method.
03:56Now by calling this method, we are going to move our current window behind all other windows currently opened
04:01by the operating system.
04:02So let's test our application and see how it works.
04:05We will now go to Control and then Test Movie.
04:12And let's say, we want to open up a couple more windows.
04:17So now we actually have 3 windows that are open, we should be able to now go to the Move To Back button and press it
04:23and we will see that our window disappears.
04:26Not only did it move behind the two windows that we had opened, but it actually moved behind Flash as well.
04:31Now I can prove this, I am going to press the button for each of these windows as well.
04:34And now we are back to Flash and now if we minimize Flash, behind it we will see the three instances of our windows.
04:41So there will probably be many times as a developer when you will want to adjust the order of your windows.
04:46By using the methods that are provided by the NativeWindow class, you can have fine grained control
04:51over which windows are in front that your user can interact with and then what other windows are either moved
04:55to the back or minimized so that the user can see them at the given time.
04:59By capitalizing on this, you move one step closer to creating a full featured desktop application with Adobe AIR.
Collapse this transcript
Listening to multiple windows
00:00Now when you create multiple windows in a single application in most cases you are going to want those windows
00:05to be able to communicate one with another.
00:08Now one of the approaches to doing this is by using the openedWindows property of the NativeApplication class.
00:15This property is an array that contains a reference to each of the openedWindows in your application.
00:20So by using this you can actually loop over each of the Windows and perform a specific action.
00:25So by doing this you can cause the actions in one window to then be represent across the other windows as well.
00:31So to accomplish this we are going to go ahead and open up our application.
00:35We go to File and then Open and then we will open BrowserApplication03
00:40in the Chapter 9 folder of the exercise files.
00:42Now once we have actually gotten into the application we are going to want to go into the Browser symbol,
00:50so we will click on the Browser movie clip and if we double-click we should be now into our movie clip.
00:55Now we are actually going to drag two more instances of the button out on the Stage.
01:00So to do that we are going to need to make a little room, now just note this is not going
01:04to be a permanent change this is actually just a change that we will do for testing
01:08and then we will implement a more elegant solution later.
01:11So let's go ahead and unlock the UI Layer then I am going to select the URL Input,
01:17I am going to get the Free Transform tool and then I am going to hold down the Alt key or the Option key on Mac
01:22and then I am just going to drag this in so we have got room for a few more buttons.
01:26Then I am going to go to the Components window by going to Window and then Components.
01:31And then I am going to drag two instances of the button onto the Stage.
01:40We will move a few things around so we have some more room for our buttons.
01:49And now we will position our buttons in place and we are going
01:55to give the first button and instance name of cascadeButton.
01:58And we are also going to give it a parameter label of Cascade.
02:05Now we are going to go to our next button and we are going to give it an instance name of hideOthersButton
02:15and we are going to change the label to Hide Others.
02:19Now that we have actually added our buttons to the Stage and positioned the items
02:25where we want them we are actually going to go ahead and lock the UI Layer go
02:29to the Actions layer and then go to Window and Actions.
02:32Now the first thing that we will need to do since we are working with the openedWindows property
02:37of the NativeApplication class we are going to need to actually import NativeApplication.
02:42So this can be accomplished by saying import flash.desktop.NativeApplication.
02:50Now that we have imported our class we are ready to begin adding the event listeners for our two buttons.
03:00So now that we are in our Event Listener section we are going to start off
03:03with the Cascade button. We will say cascadeButton.addEventListener
03:09and we are going to listen for the MouseEvent.CLICK event.
03:17And we will respond to that with the OnCascade method.
03:21Next we are going to need to add an Event Listener for our Hide Others button
03:26so we will say hideOthersButton.addEventListener and we are going to want to listen also for the MouseEvent CLICK method.
03:39We are going to respond to that with onHideOthers.
03:46Now that we have added our event listeners we can go ahead and add our event handlers.
03:52So we will go to our event handler section we will scroll to the end and then we will create our two new methods.
03:58The first method that we will need to create will be onCascade and it will receive an event of type MouseEvent
04:10and it's not going to return anything so we can leave the return type void.
04:15Next inside of this method we are actually going to want to loop through each of the windows.
04:19To do this we are going to be using a for loop.
04:21If you are not familiar with the for loop you might want to go back and review some
04:25of the other ActionScript 3 Series here at www.lynda.com.
04:29We will say four and then we are going to create our iterator which we will just call i.
04:34That will be an unsigned integer and we will set it equal to 0.
04:39Then we are going to want to be sure that i is less then NativeApplication.nativeApplication.
04:49and then here is the property that I mentioned in the introduction, openedWindows.
04:55And since this in an array we know that it also has a Length property.
04:59So we are going to want to be sure that i is less then the length of the openedWindows array.
05:04Next we are just going to increment our iterator and now we have actually successfully set up our loop to go through all
05:14of the different windows within our application.
05:17Now we're going to go ahead and create a variable for the window, it will be of type NativeWindow.
05:24And then we are actually going to set that equal to NativeApplication.nativeApplication.openedWindows
05:34and then we are going to set it equal to the current value of the array from our iterator.
05:41Now we are going to need to position the x and y of this window.
05:44Now the goal is going to be that the first window will be positioned at the top left of the screen.
05:50Then the next window will be a little bit down and a little bit to the right of the first window.
05:55It also will be on top of that window.
05:58So it will be positioned so that the windows basically form a cascade from the top left
06:02to the bottom right corner of the screen.
06:05Now we are going to set the window.x property.
06:08And we are going to set that equal to a very specific formula.
06:12We are going to say 25 times i. Now what this will do the first time
06:19through since i will be 0 it will position the window to 0 for the next time
06:23through because it's one it will position the window at 25 and then 50 and 75 and so forth.
06:28Now we are going to make one small change because we don't want the windows to be flushed with the edge
06:33of the desktop so we are just going to add 10.
06:36Next we are going to set the window.y property
06:41and in this case we actually can just copy our previous formula and use that here as well.
06:49Now the next thing we are going to do is actually very crucial.
06:52We are going to want to use the OR in front of method of the NativeWindow class.
06:57And we are going to want to position the current window in front of the previous window
07:02but obviously the first window will not have a previous window.
07:06And so if we don't add some type of an If statement in here that checks to see
07:10if it's the first window it will throw an error when you try to run your application.
07:14So we will say If i is greater than 0 and this will just ensure that it is not the first time through it will ensure
07:24that it's at least the second time looping through.
07:26And then we will say window.orderInFrontOf and now we will want to get a reference to the previous window that looped.
07:35So to do this we will say NativeApplication.NativeApplication.openedWindows
07:46and then we will want to say instead of saying i, which will be the current window, we will just say i minus 1.
07:59Now we are going to implement the onHideOthers method.
08:03It's going to receive an event of type MouseEvent and its return type is going to be void.
08:18Now we need to loop through each of the windows in this method as well.
08:22So in this case we can just copy everything and then we will just drop it over to our new method.
08:28Now we are going to need to delete everything from here down.
08:32And now we are going to want to do something specific with the onHideOthers method.
08:37We are going to want to basically minimize every window accept the current window that we are working on so we need
08:42to ensure that we don't minimize that one.
08:44So we will say if stage.nativeWindow does not equal window then we will know at that point that this window
08:59that it's looping through is not our window so yes we can minimize it so then we will just say window.minimize.
09:10Now we can save our application.
09:11We will go Control and then Test Movie and we can see that our application comes
09:19up with our Hide Others and our Cascade buttons.
09:21Let's go ahead and open a few windows.
09:24So here I have opened four windows. Let's say that I want to grab this window and I want to hide all
09:28of the other windows of this application.
09:30If I hit Hide Others we can see that the other windows are indeed minimized.
09:35And now if we take these windows again then we move some of the positioning around and just put them
09:40in different places actually on the screen.
09:41Now if we hit the Cascade button we will notice that all of the windows are nicely lined up on the left side.
09:47They cascade down so as you can see the windows have been positioned correctly not only in their X
09:53and Y positions but also in their stacking order.
09:55You will notice that the first window that is furthers to the left is actually in the back of the stacking order
10:00and then it increments all the way up unto the window that's furthest
10:03to the right is actually on the top of the stacking order.
Collapse this transcript
10. Using Native Operating System Integration
Introducing native operating system integration
00:00The cross-platform compatibility of AIR provides a great platform to build applications for both Windows and Macs.
00:06AIR has the capability to work with many elements of the core operating system in both Windows XP and Vista,
00:11and Mac OS X. Understanding what these items are is essential to a developer,
00:16who is developing an application within Adobe AIR.
00:19So let's look at some integration issues when we are building applications that are going to be cross-platform.
00:23First, we are going to look at some differences between Windows and Mac within Adobe AIR.
00:28In Windows, we actually have support for the System Tray, but in Mac we have support for the Dock.
00:33Now these items have some similarities, but they also have some differences that will have to be addressed
00:37when you are creating an application that will run on both platforms.
00:41Windows actually has Nativemenus for a Nativewindow
00:45and Mac they actually have Native menus for a NativeApplication.
00:49So there is a big difference in the way that you actually have to add your items to your menus.
00:54So now let's go on and let's look at some of these items specifically.
00:57I have stated that in Windows, there is a Native menu for a NativeWindow and a mini-bar can be added
01:02to an Application window but not the entire application.
01:06So as you can see here with just the version of Notepad that comes with Windows by default
01:10that you can see there is an actual Menu bar that's attached to the window instance.
01:15In Mac, however a Menu bar can be added to an application but not to a single window.
01:20Here you see an example of the menu bar that's the default in Mac OS X and you can actually see that one application,
01:27no matter how many Windows it has only has, only has one Menu bar.
01:31Now inside of Windows, we have Taskbar support and a Taskbar is used to list currently opened windows as well
01:36as display icons for currently running applications in the System Tray.
01:40Now AIR supports the use of a custom icon in the Taskbar for your application and in addition,
01:45we also can attach Menus and ToolTips to these icons.
01:48And we also can utilize a system for notifying users of key events.
01:53With the dock, the dock is used to list currently opened applications as well as shortcuts to other applications,
01:59but the dock can also be used to notify the end user of events.
02:03So in AIR, we actually can attach a Menu object to a Dock icon as well.
02:08So here are some things that we need to consider when we start going
02:11down the road to creating cost-platform applications.
02:13First we will need to test the application in both Mac OS X and Windows, if you are using both sets of functionality.
02:21When you just spend time working in the other operating system, so that we can create a more consistent experience
02:25for the user, it can be very tempting to just do things the way that you have always done them without actually going
02:30and reviewing some of the other operating systems.
02:32And then that can cause problems when you are trying to create and immersive experience with users
02:36that are coming from different operating systems.
02:39Next, since your ".air" file can be installed on any computer with AIR installed,
02:43you just can't ignore an unfamiliar operating system.
02:46You really need to dive in and learn it so that you can build the best possible application.
02:51The cross-platform integration that's provided with AIR is a huge benefit and it shouldn't be a burden to the developer.
02:56It opens up a lot more power and so we are going to do take some time to look at each of these items specifically
03:01and determine how we are going to implement them inside of our AIR application.
Collapse this transcript
Using application menus
00:00Now I have exported a version of the browser application that already has a NativeMenu integrated in it.
00:05So I am going to double click on the application.
00:08When we see it launch here, you can see that in the top left corner of the application here
00:12where we normally have the File options and stuff within Windows, we actually have a Menu here as well.
00:16We have the File option.
00:18We can open a PDF, close and exit the application.
00:21We also have a View option here for Cascade, Hide Others and Always on Top.
00:25So we have integrated this in using a NativeMenu.
00:28Now in this video, we are going to go through the process of recreating this NativeMenu.
00:33We are not going to yet attach it to a window, but we are going to learn how to work
00:36with the flash.display.NativeMenu class as well as the flash.display.NativeMenuItem class.
00:44So when we wok with NativeMenus, those are the two classes that we will be using
00:47and the NativeMenu class specifically is a menu or sub-menu within the application.
00:53You can pretty much guarantee that it's going to have child elements that are going to be of the type NativeMenuItem.
00:57And any time that you will actually have an item within a menu, for example,
01:02in the example I just showed, the LoadPDF item. That was a NativeMenuItem.
01:07So here is the structure one more time that we are going to recreate in this video.
01:11First, we have a root NativeMenu and then we have two NativeMenuItems under that, a File menu and a View menu.
01:19Then under each of those, they each have a NativeMenu as a child.
01:23And this is actually the sub-menu that contains the other options.
01:27And then inside of those sub-menus, we have more NativeMenuItems
01:30that actually contain the different options that are found on our menu.
01:33So let's go through and actually create a portion of this NativeMenu from scratch.
01:38So now that we're back in Flash, let's go to File and then Open and we are now going to open Browser Application01
01:44in the Chapter 10 folder of the exercise files.
01:47Now we are going to actually double click on the browser movie clip and now we are going to be sure
01:52that the Actions layer is selected and we are going to go to Window and then Actions.
01:56Now the first thing to check is to be sure that we have the NativeMenu and NativeMenuItem classes imported.
02:02Now in this case, we have imported the entire flash.display package
02:06so we actually already have these classes imported without any additional work.
02:09Now we are going to add in several methods to our application,
02:13so let's scroll down to the section that contains our methods.
02:16Now the first method is going to create our root menu, it's also going to create the File
02:21and View items that exist under that menu.
02:24So the first thing we need to do is create our method and it will be called createRootMenu and then within here,
02:31it's not going to accept any parameters and it's not going to return anything.
02:35So now that we have created our createRootMenu method, we can go ahead and create a new instance of the NativeMenu.
02:42And I am just going to comment things, so that we can keep things clear, this will actually be the Root Menu
02:47and we will call this one nm for NativeMenu and that's going to be equal to a new NativeMenu.
02:58Now from here, we are going to want to create the two items that we had discussed the File menu and the View menu
03:04and each of these actually start out as a menu item and then they have a sub-menu property
03:09that contains the options for within those items.
03:11So the first thing we will do is we will say var fileMenu and this will be up type NativeMenuItem.
03:20Now within NativeMenuItem, you are actually required to give it a label, so when we finish our constructor,
03:25it will prompt us to input something for the label. For here, we are just going to say File.
03:30Now this is important to know, because whatever you put here is what is actually going to show up. If you are in windows,
03:36it will actually show up on your Window default menu.
03:40Next, we are actually going to create the View menu.
03:57And we are going to give it the label name a View.
04:01Now let's go back and look at the File menu for a moment.
04:04We are going to want to create a sub-menu, now we learned first of all
04:08that a NativeMenuItem is actually the item that's displayed as an item within a menu, now in this case we are wanting
04:14to add an entire menu to the file, NativeMenuItem so that when we click on File, another window pops down.
04:21This is a standard feature, but to accomplish this, we are going to have to create another instance
04:25of the NativeMenu class and we are going to call this one File Sub-Menu, so we will say var fileSubmenu,
04:32it will be of type NativeMenu and it will be equal to a new NativeMenu.
04:40Now this would be the normal way that we would create it, but in this case to actually keep from stacking so much code
04:48into this one method, we are actually going to delegate the creation of our sub-menu to another method.
04:53So we will go back and instead of saying that it's equal to a new NativeMenu, we are actually going to say it's going
04:59to be equal to createfileMenu and we will create that method shortly.
05:06Obviously that method will be returning a NativeMenu.
05:09So in this case, we will pretend that we actually already have that item and we will say fileMenu
05:13and anytime you are actually wanting to add a sub-menu to a NativeMenuItem,
05:18you simply have to just add it as the submenu property.
05:21So we will say fileMenu.submenu = fileSubmenu and now that will actually be used
05:30as the submenu for the fileMenu NativeMenuItem.
05:33Now the last thing we need to do is we haven't yet added our fileMenu to the NativeMenu that we have created first,
05:40the root menu. So to do that, we are just going to say nm, which is the name of our NativeMovie, .addItem
05:47and then we are going to pass in whatever item we want to add.
05:51In this case, we are just going to want to add in the fileMenu.
05:53Now let's actually go down and implement the createfileMenu method.
05:59So we will scroll down below our current method and we will create a new one.
06:03We will say function createfileMenu and it will not accept any parameters, but it will return a NativeMenu.
06:13Now inside of here, we are going to want to add several options, but the first thing that we are going to do is
06:24since we need to return a NativeMenu, we are going to go ahead and create a NativeMenu to add our items too.
06:28So we will say var fileSubmenu and this is the same name that we used before. This will help us remember
06:35that when we return this item, it actually will be passed into the fileSubmenu and this is going to be
06:40up type NativeMenu and it will be equal to just a new NativeMenu.
06:47Now we actually can go ahead and scroll down below this and return this value as well.
06:55We will say return fileSubMenu.
06:58Now we can actually add the items that are going to be inside of this menu.
07:02First, we are going to want to add the Open PDF option so we need to create a new NativeMenuItem
07:08because again here we are creating an item that's actually going to be a part of a menu.
07:13So we will say var pdfItem is going to be of type NativeMenuItem, will be equal to a new NativeMenuItem.
07:24Now again with the NativeMenuItem, we have to pass in a label, in this case our label is going to be Open PDF
07:33and that will actually be what's displayed within our menu.
07:36By default, your menu items don't do anything. Even if you use common words such as Exit or Close they are not going
07:43to do anything unless you actually add an event listener to them.
07:46So in this case, we are going to add an event listener, let's say pdfIten.addEventListener.
07:52And then we are going to be listening for a specific event, because every time a user clicks a specific menu item,
08:00it's going to dispatch the Event.SELECT method. So we will listen for the Event.SELECT.
08:05And then we will respond to it by calling the onPDFSelect method.
08:11Now we have actually already implemented this functionality in a previous video.
08:15If you are not sure how you would proceed from here to actually configure the listener to prompt the user
08:20for a file in their local hard drive then I would suggest going back and looking
08:23at the PDF chapter here within these series.
08:27Next, we actually can add the item to the fileSubmenu,
08:30so we will say fileSubmenu.addItem and it will actually add the PDF item.
08:36Now this is the exact same process that we will follow for the other two items that we are going to add.
08:42We will say var and the next one will be closeItem, it will be of type NativeMenuItem and that will be equal
08:55to a new NativeMenuItem and that will receive a label and this one will just have the label of Close.
09:02It will signify the user so they can close the current window.
09:05We will follow the same step that we did before.
09:07We will say closeItem.addEventListener and we will listen for the Event.SELECT method.
09:14And we will respond to it by calling the onCloseItem method.
09:20Now the next thing we are going to do is we are actually going to add in a separator because if you notice,
09:25in our sample movie in between Open PDF and Close, there is an actual line, a file separator.
09:32And this is a special property that you have with inside of the NativeMenuItem class.
09:38So instead of actually going through here and creating a new NativeMenuItem and then adding an event listener,
09:42what we are just going to do is we are just going to create the menu item and we are going to pass
09:46through to the second parameter of the constructor.
09:48So we will say var, we will just call this sep, for separator. That's going to be equal to a NativeMenuItem
09:56and we are going to say that's equal to a new NativeMenuItem.
10:00And then we are going to want to pass in a label, in this case it really doesn't matter what we pick,
10:06but we are going to say isSeparator and we are just going to say true, this is a separator.
10:10All items that get added to a menu also have some additional properties, for example, if you notice in the sample movie
10:19when we open the sample movie, we now have some keyboard shortcuts that we can use
10:24to access some of these pieces of functionality.
10:26For Open we can do Ctrl+O and for Exit we can do Ctrl+Q that is actually a property of the NativeMenuItem class.
10:33So for example in PDF, we could go up and say pdfItem.keyEquivalent is equal to
10:41and in this case we could just say o, and it will automatically append either Control or Command depending
10:47on if you are on Mac or PC to the beginning of this command.
10:50So just by simply putting keyEquivalent it's actually going to listen for the keyboard event, respond accordingly
10:55and then dispatch an event so that you can actually react to this.
10:58Pretty much adding all items to a menu is just as easy as doing what we have just done.
11:02Well you can create very complex menus, you can create very complex nested menus,
11:07it can be used in many different places throughout your application.
11:10But to create a basic menu, one things stays the same however, you are going to be using the NativeMenu
11:15and the NativeMenuItem class to create your menus, menus that you will use in your Window menus
11:20in your Application menus, in your Context menus, in your Taskbar menus, pretty much all of the menus
11:26that you can create within AIR are going to be based on these two classes.
Collapse this transcript
Using window menus
00:00One of the major differences between Mac OS X and Windows is the way
00:04in which default menus are attached to an application.
00:07As you learned in the introduction to this chapter, in Windows these are attached to the Individual windows,
00:12but in Mac these are attached to the application as a whole.
00:15Now, in this video, we are going to be able to take the menu that we created in the previous video and we are going
00:21to actually take it and attach it to an application window of our browser.
00:24So, let's go ahead and open the file.
00:26If we go to File and then Open, we are going to open BrowserApplication02
00:32in the Chapter 10 folder of the exercise files.
00:34Now, we are actually going to double click on the browser movie clip and now we have actually loaded up our browser.
00:41Now, we are going to go ahead and go to the Actions Layer and we are going to do a bit of review.
00:46If we scroll down, the first thing I want you to notice is that now I have actually added a section for all
00:52of our NativeMenu and event handlers code.
00:54It's quite a bit of code, so we want to be sure that we just know where it is
00:57and that we keep it separate from the others.
00:59If you look, you will see that as we discussed in the previous video, we have implemented both the File
01:03and View menu, we also have implemented the methods that add items to those.
01:08So, currently in the View menu we can Cascade, we can Hide Others and we can set the value to be Always on Top.
01:15Now, we are actually using code from previous videos to accomplish this,
01:20so if you are not sure about how this code works, you can go back
01:22and look at previous video to determine how these methods work.
01:26And if we go to the File menu, we now have a few specific options as well, we can open a PDF, we can close a window
01:32or we can exit the application and we have also added in a separator.
01:37We also were using the key equivalence that we discussed in the previous video
01:40to make keyboard shortcuts for these items inside of our menu.
01:45Finally, if we look we are actually calling the createRootMenu method at the very beginning
01:52of our application in the initialization methods section of our code.
01:56So, now with all of that we are going to need to add this actually to our application window.
02:01If we launch right now, our menu is nowhere to be seen.
02:05It has not yet been added to the application.
02:08This actually is not a difficult process, but again because we are working
02:11with cross-operating system issues here, we need to be sure that we are actually either on a Windows machine
02:17or on a Mac machine before we decide how to handle our menu.
02:20So, let's close this window. We will go back into our application. We are going to actually scroll
02:26down to the createRootMenu method, that's now in our menu section of our code.
02:32At the very end of the createRootMenu method, we are going to add in a little bit of code.
02:37The first thing we are going to say, we are actually going to basically ask the AIR application a question,
02:42we are going to say if NativeWindow.supportsMenu.
02:49Now, we were on a Mac and we were actually running this application, it would come back and it would say "False-No."
02:54The Nativewindow doesn't support a menu on Mac; the NativeApplication does.
02:59And the same is true for Windows in the opposite.
03:01It does support a menu for NativeWindow, but it doesn't support a menu for the NativeApplication.
03:07So, in this case we actually can know that we are working with a Windows machine, so we will say Windows.
03:15So everything inside of this if statement will only execute,
03:18if we are on an operating system that supports menus for a NativeWindow.
03:22So, now we can say stage.nativeWindow and to attach this menu to the NativeWindow,
03:31you only need to actually set the menu property of the NativeWindow equal to your root menu.
03:36So, we will say nativeWindow.menu is equal to nm for our NativeMenu
03:42that we have created at the beginning of this method.
03:44Now, if we save our application and we go to Control and Test Movie.
03:48We will now see that we have actually created our browser application with the NativeMenu
03:54that has been attached to the NativeWindow.
03:57In this case it works and that we have all the options that we plan
04:00to have including the separator between Open PDF and Close.
04:03We also could open up multiple windows and we could see that our Close method does indeed work.
04:08We also can test and see that if we do Ctrl+Q, it closes our application and that's
04:14without configuring any keyboard events for our application,
04:17we simply have just added the keyEquivalent property to the NativeMenu item.
04:21Now, that you have developed NativeMenu integration inside of Windows,
04:25we will need to look how to integrate with the Mac.
Collapse this transcript
Using context menus
00:00The Application menu for Mac OS X application is tied to the entire application.
00:05However, it can be edited and configured in the exact same way that you would for a Windows machine.
00:10So, let's go ahead and take the previous application that we had where we added support for the Windows menu bar
00:16and let's go ahead and also add support for Mac, so that we can have an Application menu for our application.
00:23So, let's go to File and then Open and then inside of the Chapter 10 folder
00:27for the exercise files, we will go to BrowserApplication03.
00:33Just to do a very quick review, if we go to Control and Test Movie,
00:37we have actually created our normal Browser application, but with the menu bar
00:45that includes several different options encompassed into submenus for File and View.
00:50So, now let's close our application.
00:53If we go back to the Browser movie clip by double-clicking and now we go to the Actions layer
01:00by highlighting the Actions layer and then going to Window and then Actions.
01:05We now can actually scroll down to our createRootMenu method, it will be in our NativeMenus
01:13and EventHandlers section and we see here that we have actually integrated it already for Windows.
01:19Just with these three lines of code, we have actually been able to add our menu bar to Windows' NativeWindow.
01:25But we now want to add our menu bar to a Mac NativeApplication. So I will first add a comment
01:33so I can remember when I come back to this code why I added these lines. And now for Mac we say,
01:40just as we asked the question for Windows, does the NativeWindow support a menu?
01:45In this case, we are going to ask our application NativeApplication, does it support a menu?
01:55If the answer is yes, then we know that we are working on a Mac and because
01:59of that we can now set the NativeApplication.nativeApplication.menu equal
02:10to our NativeMenu, which we named "nm" and now if we save our movie we can now test it
02:19and see what it would look at like on a Mac.
02:21So, I have actually installed the application on a Mac, I am going to go ahead and launch the application
02:28and we will see that everything looks just as it did.
02:30One of the great benefits of AIR is that your application really does look the same on Mac
02:34or PC, with the few exceptions that we stated.
02:36But notice here that we do preserve our File and View menus.
02:41As long as our application is selected we can go under File and we see our Open PDF, our separator is preserved,
02:46Close and Exit as well as our keyboard shortcuts were preserved and one of the benefits of this is because we are
02:53on Mac and Mac users generally don't use Ctrl shortcuts, it automatically converted those to Command Shortcuts,
02:59so now Command+O can open the PDF and Command+Q will close the application.
03:04We also have all the view options as we did previously.
03:08Now, as you can see, we can now fully support the application NativeMenus inside of Mac
03:13with our AIR applications even though we have created our AIR applications on a Windows machine and this is one
03:18of the great benefits of AIR the cross-operating system compatibility that you gain.
Collapse this transcript
Setting up context menus
00:00Context menus are staple of user experience.
00:04Most users who use computers on any regular basis are actually going to be very familiar with Context menus.
00:10For example if you are in a browser and if you have ever right clicked, this is a Context menu.
00:15It's basically going to give you information based on what you right clicked on.
00:19And you also can add Context menus within AIR and the great thing about Context menus
00:24within AIR is they have been using the same menu classes
00:27that you are already familiar with, NativeMenu and NativeMenuItem.
00:31To illustrate how easy it is to create a Context menu once you have actually created your menu structure,
00:37we are actually going to add a Context menu to our application.
00:41So let's go ahead and close our browser and we will go back to Flash, and we go to File and then Open
00:51and then in the Chapter 10 folder of our Exercise Files we are going to open BrowserApplication04.
00:57Now we are going to double click on the Browser movie clip, now we are going to go to the Actions layer
01:05and we are going to go under Window and then Actions.
01:09We are now just going to scroll down until we get to our createRootMenu method which is at the bottom,
01:15you can see that we have already added our code for Windows and Mac and directly below this we are going
01:20to go ahead and just add code for our Context menu.
01:23Again if you already have your menu created, it's just as easy as saying this.contextMenu = nm.
01:32The one thing that does need to be understood about Context menus is that you can only right-click
01:38on an interactive object on the Stage to view a Context menu.
01:42So it needs to be something that can accept user input.
01:45I will illustrate this now by testing the application.
01:48If we go to Control and then Test Movie, the first thing I want you to notice is
01:54that there already is a default Context menu within HTML.
01:59If you right-click, you are not going to see your Context menu.
02:02However, if we go up and look at the top of our application and we right-click, you can see the exact same File
02:08and View menu options that we created for the menu bar here within our application.
02:13So it's just as easy as passing your NativeMenu instance to the contextMenu property
02:19of any interactive object on the Stage to create a Context menu.
02:23Context menus can be a great asset if used properly.
02:27However, if used improperly they can create a confusing user experience.
02:31So take some time to examine how other applications are using them before you decide
02:36that they are right for your application.
Collapse this transcript
Using system tray interaction
00:00The system tray in Windows is a place where icons for programs reside.
00:04These icons are also unique and that they can have millions attached to them as well as tool tips.
00:09Now, there are many used cases for system tray icons including applications
00:13that don't launch with a visible window.
00:15But in this case, we can add some additional functionality to our browser application by adding an icon
00:21to the System Tray and then connecting an instance of one of our menus to that as well.
00:25So to get started, let's go ahead and open up the file.
00:28We will go to File, Open and we are going to open up BrowserApplication04
00:34in the Chapter 10 folder of the exercise files.
00:37Now, we are going to go ahead and double click on the Browser movie clip and then we are going to be sure
00:44that the Actions layer is selected and we are going to go Window and Actions.
00:47Now, we are going to actually scroll down to the method section,
00:52which should be under our Event Handlers, and we are going to create a new method.
00:58This method is going to be called setUpIcon and it's not going to take any parameters and it's not going
01:07to return anything, so we can set the return type equal to void.
01:11Just when we are working with NativeMenus, we can ask AIR questions
01:15about the application and what type of icon it supports.
01:19In this case, since we will be working on Windows we are going to want
01:22to ask the NativeApplication if it supports a system tray icon.
01:27So, to do that we are first going to just add in a comment, so we know that we are adding in code that's meant
01:32for Windows, and then we are going to say if and then we are going to say NativeApplication.supportsSystemTrayIcon.
01:44So if it returns True then we know that we are on Windows system that supports the system tray icon.
01:51So, now we actually can begin the process of loading in an image to use as the icon for the system tray.
01:57So, the first thing we are going to need to do is create an instance of the Loader class, so we will save var loader is
02:03of type Loader and we will just set that equal to a new Loader object.
02:08Next, we are going to actually add an event listener. We will say loader.contentLoaderInfo.addEventListener
02:22and we are going to listen for the Event.COMPLETE method and that will tell us
02:30when our actual content is done being loaded.
02:33And when that's done, we are going to call the onIconLoadComplete method.
02:39And now, we will go ahead and create the shelf for this method that will be using later.
02:47We will scroll up to our Event Handler section, we will go under our last one,
02:51we will create a new function that will be named onIconLoadComplete.
02:56We know it will accept an event of type Event and it's not going to return anything.
03:04Now, let's go back down to our setupIcon method.
03:07We now have told our application to listen for the COMPLETE event, now we need to actually load
03:13in what we are going to be using for our icon.
03:16If we open the Chapter 10 folder of the Exercise Files, you will notice that there is an Icons folder inside of it
03:22and inside of this Icons folder are just some icons of different sizes that we used earlier in the series.
03:28Now, inside of here is one called icon-16.png.
03:33By default system tray icons inside of Windows are 16x16 pixels,
03:38so we are going to use this image as our system tray icon.
03:42We can cancel this window and now we can tell the loader to load that specific file.
03:47We will say loader.load and then inside of here, we are going to need to pass it a new URLRequest
03:55and for this URLRequest we can just say icons/icon-16.png.
04:05We can close our URLRequest and then close our load call and now we are ready
04:13to set a few properties of our NativeApplication.
04:16Now, the first thing that we will need to do is we will need to reference our NativeApplication class,
04:21so we will say NativeApplication.nativeApplication and then we are going to actually go to the icon property.
04:30However, if we are on Mac, this icon is actually going to be of type dockIcon,
04:36but since we are on a PC this is going to be of type system tray icon.
04:41So, we need to actually cast this so that the application knows which we are dealing with.
04:46Now we can do that by going to the beginning of this reference and saying SystemTrayIcon.
04:58And we actually can then put everything in parenthesis up through the icon.
05:04Now, we can set the tooltip value and we will just set this equal to Browser Application.
05:14This is what will actually appear when the user's mouse hovers over our system tray icon.
05:21In addition, we can actually attach an instance of the NativeMenu to our system tray icon,
05:28so that if the user right-clicks or clicks on our system tray icon they will actually see our menu.
05:34So, in this case we will also say system tray icon
05:39and then we will say NativeApplication.nativeApplication.Icon
05:47and we'll say .menu.
05:51Now, in this case we don't want our entire NativeMenu to be added. Instead we only want to add a portion and it's nice
05:58in the system tray icons to have the ability to close the application or maybe to do some key pieces of functionality,
06:04but not necessarily everything and if we look down inside of our NativeMenu and event handlers,
06:09we can see the method createFileMenu returns a NativeMenu and it actually gives us the option
06:16to open a PDF, close the item or exit the application.
06:20So, in this case we just set the .menu Property of our system tray icon to createFileMenu
06:28and it will actually return the instance of our NativeMenu that we will be using here.
06:32Now we have pretty much set up what we need to have set up inside of our setupIcon, but now we are going to need
06:39to respond to the Event.COMPLETE method that was dispatched when the loader loaded in our icon.
06:44So we will scroll back up to the method that we created and what we are going to use now is we are going
06:50to use the bitmap's property of the NativeApplication.icon to actually set the system tray icon.
06:57So we'll say NativeApplication.nativeApplication.icon.bitmaps.
07:08And as you can see, it actually is plural so it's actually looking for an array.
07:13We are actually only going to pass it one value, but when we need to create an array from a single item,
07:19we can just use the square brackets for the shorthand for an array, so we will go ahead and create our short brackets
07:25and then inside of here, we are going to enter some information about the event. We will say event.target
07:32and that target was the loader object. So then we'll say content and this will actually return the image,
07:39it was actually brought back from this loader and then we will go one step deeper and we will say bitmapData.
07:44And this will actually return the BitmapData from the image that was loaded in,
07:50the nativeApplication.icon.bitmaps property is now set to this BitmapData and the system tray icon will be updated
07:57with the icon that we have actually passed into our application.
08:01So, let's test it out and see how it works.
08:03We will go to Control and then Test Movie and we're going to get an error and the reason is is because we have not
08:12yet imported the SystemTrayIcon class. So to accomplish that let's go back to the top section of our code
08:19and we are going to now import flash.desktop.SystemTrayIcon.
08:30Now, before we test our application again, we are actually going to have to tell the application to go ahead
08:35and set up our icon, so under Initialization Methods, under createRootMenu,
08:40we then can go below that and say setupIcon.
08:44Now, the application will upon launch actually set up our system tray icon
08:49and place an instance of it in the system tray.
08:51So, now let's save our application and we will go to Control and then Test Movie.
08:55We can now see that our icon has been added, we do have our tool tip that says browser application,
09:02if we right-click on, we do have the options that were contained
09:05within the File menu to Exit, Close, and then Open PDF.
09:09System tray support just gives you another layer that you can use to connect to the local operating system.
09:16People that use Windows are familiar with using system tray icons, so again by grabbing onto this common piece
09:21of user experience, you can create more engaging and rich applications.
Collapse this transcript
Using dock integration
00:00Now that we have built an application that utilizes the system tray support within windows, we now are going to want
00:05to build an application that can also take advantage of the dock support within Mac OS X. So to accomplish this,
00:11we are going to need to add some code to our setupIcon method.
00:14So let's go ahead and open the file.
00:16If we go to File and then Open, we are going to now look for Browser Application05
00:21in the Chapter 10 folder of the exercise files.
00:24When we open this, we are now going to double-click on the Browser movie clip,
00:29then we are going to select the Actions layer and then we are going to go to Window and then Actions.
00:36We are going to scroll down to our setupIcon method which is in the Method section of our code.
00:49And we can see that we have clearly delineated this section for Windows.
00:53We are now going to create a section of code that's going to specific for Mac.
00:56We are now going to ask a different question.
01:01Instead of NativeApplication.supportsSystemTrayIcon, we are now going to ask AIR, NativeApplication.supportsDockIcon?
01:15If this comes back as true then we know that we are now actually working on a Mac.
01:19So now it's actually going to take less steps for us to get everything setup, there are a couple reasons for that.
01:27First of all, we automatically get an icon on the dock in Mac,
01:31so we don't have to worry about loading in an icon externally.
01:35The icon is used for our application that will appear on the dock.
01:39In addition we don't have the capability to add a tooltip so we don't need that.
01:43By default in the dock, your icon already has a menu, but the great thing is within AIR,
01:48we still can set the menu property of the NativeApplication.icon and this will just add our items
01:54on top of the existing menu that exists for the application with its dock icon.
01:59So now to accomplish this, we are going to need to import another class.
02:03So let's scroll back up to the top of our application.
02:10Under where we say import flash.desktop.SystemTrayIcon, we will say import flash.desktop.DockIcon.
02:21Now we will scroll back down to our setupIcon method, which again is in the Method section, and now we're going
02:29to cast NativeApplication.nativeApplication.icon. So we will say DockIcon and then we will cast it by using parenthesis,
02:38and we will say NativeApplication.NativeApplication.icon, and then we will close the parenthesis
02:49in this way the application knows that in this case the application .icon is actually a DockIcon.
02:56And then we will go to the menu property, and then we will set that equal to createfileMenu.
03:05So now we have actually mimicked the menu support that we have within the system tray. Since on Mac OS X,
03:12it already supports an icon, the only code that we really need to add to mimic the support that we have in Windows is
03:18to add our menu items to the existing dock menu.
03:21So now let's test our application and let's see what this looks like on the Mac.
03:26I have launched the application now on the Mac and we will see what we were able to accomplish.
03:30If we go down to the dock, we move our mouse to the bottom of the screen, we will see a pop-up.
03:36We can see here that it's preserved the icon, this is actually just the default icon for all the AIR applications,
03:41but in addition to that if we right-click on the dock icon, we can now see that it has added our options of Open PDF,
03:48Close and Exit on top of the existing items that are already supported within the Dock.
03:53There is a great deal of flexibility with this. You don't have to choose between the traditional dock menu
03:58or your own custom menu. You actually can have the best of both worlds by just combining them together.
04:03So within AIR, you simply need to adjust your application icons to change the dock icon
04:08and then you can use the menu property to add your own custom menu options to the dock menu for your dock icon.
Collapse this transcript
Setting up event notifications
00:00One of the core components of an operating system is its ability to notify the user when key events occur.
00:06Now this can be done in several ways. It can bring up pop-up window, maybe it has a flashing icon on the system tray.
00:12AIR supports a few cross-platform ways that we can inform users when events occur.
00:17Just as with many of the elements that we have worked with this chapter, there is a specific way to do it
00:21in Mac and a specific way to do it in Windows.
00:23So we are actually going to have an alert that goes out to our users
00:26after each web page is fully loaded within our browser.
00:29So let's go ahead and open the file.
00:31If we go to File and then Open, we are now going to go to Browser Application06
00:38in the Chapter 10 folder of the exercise files.
00:41We're going to double-click on our Browser movie clip, we're going to highlight the Actions layer
00:48and then we are going to go to Window and then Actions.
00:51We are going to scroll down to the Method section and directly below where we added the code to set
01:02up our icon, we are going to create a new method.
01:04And this one is going to be called notifyUser.
01:11It's not going to accept any parameters and it's just going to return void.
01:16Now we are going to ask the same questions that we have asked before of AIR,
01:23so that we can determine which system we are running on.
01:26In this case, we are going to ask if NativeApplication.supportsSystemTrayIcon?
01:37This will tell us if this is true that we are on a Windows computer.
01:40So we can now go and we will put a comment that at this point we are dealing with Windows and then we will go
01:47and ask another question that will tell us if we are working with Mac.
01:50We will ask if NativeApplication.supportsDockIcon.
02:03Now to actually notify the user of an event, there actually is a method named notifyUser that's attached
02:09to the NativeWindow and this only works if you are actually in Windows.
02:13So we will say stage.nativeWindow.notifyUser and then we can choose to pass
02:24in basically a string that tells how critical this alert is.
02:28These different types of alerts are actually defined in the NotificationType class.
02:32So we are actually going to need to import this class into our application.
02:36So if we scroll back to the top of our application where our inputs are, we are going to go right below the Dock Icon
02:42and we are going to say import flash.desktop.NotificationType.
02:51Now we can scroll back down to our notifyUser method and inside of the notifyUser method,
03:02we can actually pass in one of a few values.
03:04We'll say NotificationType. You can see that we have two options here, we have Critical and Informational.
03:13It will actually cause the alert to behave differently based on whether you just say it's an Informational alert
03:17that the user can respond to or maybe not whereas if it's a Critical alert,
03:21the system is going to keep alerting them until they actually take notice of it.
03:24So in this case, we are going to start off actually using the Critical alert.
03:28So we can see its functionality.
03:30Now to actually notify the user inside of Mac, it's a bit different.
03:35Inside of Mac the dock icon can actually bounce thus signifying to the user
03:39that there is something they need to pay attention to.
03:41So to do this, we are first going to look at the NativeApplication.icon property.
03:46We will also need to cast it again as a DockIcon.
03:49So we will say DockIcon and then inside of our parenthesis we'll say NativeApplication.nativeApplication.icon
04:00and then outside of the parenthesis we can say bounce.
04:06Now with this method just as with the notifyUser method we can pass in which type of notification this is.
04:13In this case, we'll also say NotificationType.CRITICAL.
04:22There are a couple important things to remember, however, about notification.
04:26Notification when it occurs only is displayed to the end user if your window is not activated.
04:33So this operating system expects that if your window is activated and you need to alert the user of something,
04:38you can do so in a more efficient manner.
04:40However if your application is minimized and it needs to tell the user
04:44that something is happening then the alert will actually occur.
04:47In Windows, the Taskbar reference for your current window of your application
04:51that sent the notification will actually flash.
04:54If you have set it to NotificationType.INFORMATIONAL, it will flash one time.
04:59However if you have set it to Critical, it will continue to flash until the user activates that window.
05:04The operating system assumes that at that point you can inform the user
05:07of what action they need to take and then it will stop flashing.
05:10With Mac, the dock icon will bounce one time if you actually set it to NotificationType.INFORMATIONAL,
05:16however, it will keep bouncing if you set it to NotificationType.CRITICAL.
05:20So how we are going to trigger the notifyUser event, just for the sake of testing,
05:24we are going to go to our onLoadComplete method.
05:29And if you remember, this is the method that is actually executed every time an HTML page has completed loading.
05:36So we will go and we will create a new line and we will say notifyUser.
05:44So now we can save our application. We will go to Control, we will Test Movie.
05:51We will actually minimize it, we will click on Flash and we will actually see that now
05:58since the page has finished loading the reference for that current window is flashing and you will notice
06:03that it's continuing to flash and that's because we have set the NotificationType to Critical.
06:08Now if we select that window, it will stop flashing.
06:11We now can close our application.
06:13If we go back to our application and we set NotificationType to Informational, we will notice a different response.
06:19So if we scroll down to the notifyUser method again and we change NotificationType to Informational,
06:30we can save our application. We will test our movie, which will load our application.
06:35We will minimize the window.
06:37We will notice that now when it completes, it will flash one time and it will remain solid.
06:43But it won't flash anymore.
06:45This will still tell the user that something needs to happen,
06:48but they will also know that it's not something as critical.
06:51Now let's take a look at what the notifications look like on the Mac.
06:54So I have loaded up the Browser application and we are going to test the actual notification functionality.
07:00So the first thing I am going to do is I am going to go here into the URL box and I am going to just put in the name
07:07of another site, we will just type in Google.
07:10Then as soon as I hit Go, I am going to have to switch back. I have opened up a Safari window directly behind this.
07:16The reason is as we stated earlier notification only works if your window isn't active.
07:22Now this window is going to actually attempt to notify the user as soon
07:25as the page is downloading, so we will have to switch pretty quick.
07:27If we hit Go and then move to the other screen, you will see now that the page is downloading and indeed
07:33because we have set the NotificationType to Critical, the dock icon continues to bounce.
07:40If we would set it to NotificationType.INFORMATIONAL the Dock Icon would have bounced one time
07:45and that would have been it.
07:47And here now, if we actually select the dock icon when it bounces, we actually can activate our window.
07:52So now you can see that not only do we have the functionality to notify the user within Windows
07:58to the Taskbar, but we also can use the DockIcon.bounce method to notify the user inside of Mac OS X.
Collapse this transcript
11. Monitoring Network Connections
Understanding the service monitor framework
00:01One of the additional benefits of AIR that we haven't yet discussed
00:04is AIR's ability to be an online/offline application.
00:08What this means is,
00:09AIR is designed so that an application could easily receive information from the internet
00:14and then also be able to store that information locally on the hard drive
00:17and then be able to actually pull a local copy of the data if there isn't an internet connection available.
00:22There is a framework built into AIR called the Service Monitor Framework
00:26that exists to be able to detect if the user does have a valid connection to the internet.
00:30At a basic level,
00:32you can just monitor and see if the user can get to a certain URL.
00:35At a more advanced level, you can even check and see if the user has a path to a specific host on a specific port.
00:41So the Service Monitor Framework is very powerful within Adobe AIR.
00:45However,
00:46to use it you actually have to do something that you haven't had to do for any other AIR components.
00:51That is you are actually going to have to drag
00:53an instance of the ServiceMonitorShim from the Components window
00:56into your application.
00:58So let's go ahead and take our Browser application
01:01and let's go ahead and equip it so that we can work with
01:03the Service Monitor Framework in the upcoming videos.
01:06We'll go to File
01:08and then Open and
01:10then we open BrowserApplication01 in the Chapter 11 folder of the exercise files.
01:16Now we are going to need to go under Window and then Components
01:20and then you will notice that we have the ServiceMonitorShim component.
01:25It's actually listed under AIR ServiceMonitor.
01:27If for some reason you don't see this you might want to go back and be sure that you have installed the AIR update for
01:32Flash CS3 Professional.
01:34We will drag an instance of the ServiceMonitorShim into our library.
01:39We can now close the Components window,
01:42and now we are actually ready to begin working with the Service Monitor Framework
01:46with Adobe AIR inside of Flash CS3 Professional.
Collapse this transcript
Using the URL monitor
00:01One of the benefits of using the Service Monitor Framework is that it truly does allow your application
00:05to react differently based on whether the user has a valid internet connection at the time.
00:10The easiest way to get started with the Service Monitor Framework is to use the URL Monitor.
00:15And as I mentioned in the last video to be able to access this class you actually have
00:19to have the ServiceMonitorShim component that's been added to your library.
00:23So let's go ahead and actually work with our Browser application
00:26so that our Browser application can work differently when it's offline.
00:29In this case we will actually disable the Go button when the user is offline
00:33and then reenable it again when they are online.
00:35So let's go to File and then Open and we are going to open BrowserApplication02
00:40in the Chapter 11 folder of the exercise files.
00:44The first thing we are going to do is double-click
00:46on our Browser symbol then we will highlight the Actions layer and we go Window and then Actions.
00:52Now the first thing we are going to need to do is import two classes that we know we are going to be dealing with.
00:58First we are going to need to import air.net.URLMonitor
01:06as stated earlier you must have the ServiceMonitorShim component for this to work.
01:11Next you are going to need to import a specific event that's going to be flash.events.StatusEvent.
01:20Now that we have imported the classes we can begin actually creating our method
01:23that will set up the internet connection monitoring.
01:26So we will scroll down to the method section of our code
01:28and we will create a new method and we will call it monitorConnection.
01:36It's not going to receive anything as parameters and we will set the return value equal to void.
01:42Now the first thing we are going to do inside
01:44of this application is we will create a new instance of the URLMonitor class.
01:47Say var monitor of type URLMonitor. It's going to be equal to a new URLMonitor.
01:59Now this URLMonitor is expecting something in the constructor. It wants a URLRequest
02:03and dictates which URL you wanted to visit.
02:06In this case we are going to create a new URLRequest.
02:08We will say var request of type URLRequest it's going to be equal to a new URLRequest
02:18and we are actually going to set the URL for that equal to Google.
02:20Now that we have created our new URLRequest we actually can pass the request value into the URLMonitor.
02:28There is one more item that we do however.
02:31Adobe AIR gives us the capability to work with different HTML headers than what we are used to in the past.
02:36Normally we could just use certain methods such as post and get.
02:40However inside of AIR we now can use the method of just retrieving the headers.
02:45This saves greatly on the amount of data that has to be sent back and forth between your AIR application and the server
02:51that you are checking to see if you have a valid internet connection.
02:54So we will say request.method is going to be equal to HEAD.
03:00Now the next step that we need to do is actually add an eventlistener into our URLMonitor.
03:05So we will say monitor.addEventListener and we are going to listen for the StatusEvent.STATUS and we are going
03:16to respond to it with the method onStatusEvent.
03:20We are going to need to set one more property of the URLMonitor class
03:26and that's going to be the Polling Interval.
03:28So we will say monitor.pollInterval and this is going to be the number in milliseconds that it waits
03:36in between each check to see if you have a valid internet connection.
03:39In this case we are going to set it to 1000 milliseconds or at one second.
03:43Next we are ready to actually start our URLMonitor.
03:46So we will now say monitor.start.
03:50Next we actually can begin working on the OnStatusEvent method.
03:53So let's scroll up to our event handler section, we will add in a new method OnStatusEvent and it's going
04:03to receive an event of type StatusEvent.
04:08Now aside of this StatusEvent we are first going to want to pull the URLMonitor out from the event.target.
04:14So we will say var monitor of type URLMonitor equal to event.target
04:23and as I stated before the event.target can contain many different types of data
04:27so we will tell us specifically to expect a URLMonitor.
04:30Next we are going to need to check and see if the monitor's connection is available.
04:35To do this there is a property inside of the URLMonitor called available
04:40and this will tell us if the connection is available.
04:41So we will say if monitor.available is going to be equal to True then we need to actually enable the Go button.
04:51So we will say goButton.enabled is equal to True.
04:58But we know that if the monitor is not available that means we don't have a valid internet connection
05:04so in those cases we can set the goButton.enabled = false.
05:12Now with this in place we are actually ready to go ahead and test the functionality of our application.
05:17So if I had to go to Control and Test Movie it will actually bring up our movie
05:22and in the beginning everything looks fine.
05:24However, I have got my network connections window open in the background and I am going
05:28to disable my current internet connection.
05:32As I disable it you will see that the button instantly turns to the disabled state.
05:37One of the reasons that it did that so quickly was
05:39because we set the polling interval to be 1000 milliseconds or one second.
05:43Now the downside of this that means there is a lot of data that's being transferred back and forth even
05:47if you are using the head for the Request method but now we can enable our connection
05:53and we will notice that our button was enabled again.
05:56So this is a basic introduction to using a Service Monitor Framework and the URLMonitor.
06:01Again, if you have a specific server that you know that your application is going to be interacting
06:06with you can use the URLMonitor to monitor the endpoint of that server to ensure that the user has a valid connection
06:12to the internet that can be used with your AIR application.
Collapse this transcript
Using the service monitor
00:00Another powerful feature of the AIR Service Monitoring Framework is the Socket Monitor.
00:05It works similar to the URLMonitor.
00:08And a matter of fact we are actually going to replace our current URLMonitor with the SocketMonitor in the application.
00:13But it gives you much more power and that you are not just monitoring a URL,
00:17but you can monitor a specific host name and a port on that host.
00:21This can easily be expanded into developing an AIR application that would monitor the status of a web server
00:27for example, or the status of a server that had multiple servers such as Apache and MySQL running at the same time.
00:33So we are actually going to begin working with the SocketMonitor inside of our browser application.
00:38So we go to File and then Open, it will open BrowserApplication03, we now double click on the browser,
00:46to bring up the movie clip, we will highlight the Actions layer and then go to Window and Actions.
00:52Now to use the SocketMonitor as you can see we had to change one of our imports.
00:57Instead of being air.net.URLMonitor we have already changed it to air.net.SocketMonitor.
01:03Now in addition we are also going to have to change any reference in our application from one to the other.
01:09So you can see that in our onStatus event we have updated it. Instead of being a URLMonitor, it's now a SocketMonitor
01:15and we also have cast the event.target as a SocketMonitor.
01:18The final change, if we go down to the monitorConnection method, we have actually changed all
01:27of the code here to reference a SocketMonitor.
01:29And as you can see we have actually entered in a host name and then in addition to that we have entered in a port.
01:35In this case we are going to want to check, for instance at ynda.com,
01:40and see if port 80 is running. The button should be enabled if it is.
01:45Now this port 80 is the generic port for most web servers, so we actually can test this just to see
01:51if the server is responding on this port.
01:53There are a lot of uses for this if you will think about it.
01:55Most applications actually get data through HTTP, which is going to be through on port 80.
02:01But in a lot of situations you might develop an application that talks to a server on a custom port
02:07or you might develop an application that needs to monitor if a database server is actually running on a certain port.
02:12The SocketMonitor can give you this capability and even more.
02:15So this is just a brief introduction to what is possible with the SocketMonitor,
02:19so let's go ahead and test our application.
02:23And as we can see the button is enabled so we can see that the SocketMonitor has detected
02:27that port 80 is running properly on the lynda.com server.
02:32The Service Monitoring Framework in AIR gives you the ability
02:35to truly create powerful online and off line applications.
02:39They function perfectly well when they can access online data and then maybe store some of the data
02:43on the local hard drives that it can be accessed when the application isn't online.
02:47This framework can be leveraged in many different ways and is certainly a tool that needs
02:51to be in the arsenal of any AIR developer.
Collapse this transcript
12. Using the Local Database
Using the Contacts application
00:00The sample application that we'll be working with in this chapter is going
00:04to be specifically related to a server side component.
00:07Now this server component is going to be installed using the XAMPP installed Web server.
00:12Now if you are not familiar with how to install this you can go to Chapter 17
00:16and view the first video and we cover it in depth there.
00:19For this we are going to need to add a directory to our web server as well
00:23as we are actually going to import some data into a database.
00:26So to accomplish this, the first thing we need to do is just to go
00:29to our local host page and our default XAMPP installation page.
00:32Now that we have brought up the XAMPP window we are going to be going to the phpMyAdmin tools.
00:38Now we are going to be using phpMyAdmin to import some of our data.
00:42So let's go ahead and click on phpMyAdmin to go to the page.
00:45Now that we are here at phpMyAdmin the first thing we are going to do is we are going to create a new database oh
00:53and also if you see any warnings at the bottom telling you that you have to configure without a password as long
00:58as you are just on a local machine you are not a server that's actually
01:01out on the internet you should be okay just for development purposes.
01:04But you should always reset your password if you are using a production box.
01:07Now we are going to create a new database named Contacts and we can just click Create
01:15and now we are going to go to the Import option.
01:20We are now going to open a file that can be found under the exercise files in Chapter 12
01:27under Data and then the contacts.sql option.
01:32We can leave most of the other settings the same and we need to be sure that it is set as an SQL file
01:37and then we will hit Go and it will take a minute as it reads in the file
01:41and populates the database with the pre-included values.
01:45Once it's done it will inform us that several queries have been executed and we can test to be sure
01:50that things are working properly by clicking on the Person table and it tells us that it has a 1000 rows.
01:55If we click browse we can see some of the data that we will be dealing with.
02:00This is all just generated names and addresses that have all been generated just at random and now we are actually going
02:06to look at the structure and we can see that we have many different fields inside of this table we have an ID,
02:13a first name, a last name, street address, city, state, email and phone.
02:17And so we are going to be creating an application that allows us to view this data but also an application
02:21that uses the embedded SQL database so that we can store this data
02:25so that we can access it even if we are not online.
02:27Now the next thing we are going to need to do is we are going to need to open up the XAMPP directory which for me is
02:36under C and then XAMPP and then we are going to need to go under htdocs and we are going to create a new folder.
02:42We will say New Folder and we are going to call this Contacts.
02:48Now that we have opened up this directory we are going to open up the php directory inside
02:56of Chapter 12's exercise files and we are going to copy everything inside of this directory and we are going
03:01to drop it in to the Contacts directory under XAMPP.
03:06Now that you have configured the server side we are actually going to being looking
03:09at the actual application that we will be using for this chapter.
03:13Now the application that we will be dealing within this chapter actually takes advantage of many of the things
03:18that we have already learned throughout this series.
03:20So let's go ahead and open the sample movie.
03:22We can go to Control and then Test Movie.
03:27We can see here that we had a Custom Chrome application.
03:29We see that we can drag the application around, we see that we also have Custom Close
03:33and Minimize buttons that function properly.
03:35In addition we have got a list and when we click items on the list and it actually pulls data
03:40in from the server and actually displays it on the screen.
03:43This is just a basic Contact Manager application.
03:45We are going to assume that the server keeps all the data for us but we are going to want to be able
03:49to actually store it on our local hard drive so that's what we will be doing.
03:52But let's take a quick look at the actual code behind this application so that we will all be caught
03:56up by the time we jump into programming with the SQL live embedded database.
04:00So I will go ahead and close the application and now I will go look at the code.
04:08We have imported several classes and we also have defined a location.
04:12This location value is equal to one of the php scripts that you actually installed on the machine.
04:17Next we actually have a property called Connection State
04:20and this will let the entire application know if it's online or off line.
04:24We have a new method that actually loads in the data from the server
04:27and then we have some different properties that are set on some of the buttons.
04:30We have added in several event listeners as we have done many times before including an event.ChangeListener
04:36on the actual peopleList which is the list on the left side of the application.
04:39The loadData method actually uses the URLLoader to go and download XML from the server.
04:45The server will return an XML file with all of the contacts.
04:49Currently this is at a 1000 so when it loads in a 1000 contacts to the XML
04:53and then when it's done loading it actually passes it
04:56to a different method it passes it to the onLoad or Complete method.
04:59So if we look at the onLoad or Complete method it actually goes through and creates an object
05:04for each person that's listed inside of the XML and actually adds that item to the peopleList.
05:10In addition, we also have a method called setData that actually assigns the current selected person in the list
05:17so that their information is actually displayed on the right side of the application as you saw.
05:22Next we have a URL monitor that actually monitors the connection to the server.
05:27So this way if anything ever happens and for some reason our local server goes
05:30down our application will know it and should be able to act accordingly.
05:34By the end of this chapter you should be able to keep sync data between the server as well
05:38as your application with the embedded SQLite database.
Collapse this transcript
Introducing the SQLite local database
00:01SQLite expands on what we have even thought possible with AIR even up to this point.
00:05SQLite is an amazing addition to Adobe AIR that allows us to store data in the local hard drive
00:11and access it in a very quick and efficient manner.
00:14There are sometimes when storing data in files make sense; other times storing data in things
00:19like the encrypted local store also makes sense.
00:21But a lot of the time if we are going to store large amounts of data and work with it within AIR,
00:26the best choice is using the SQLite Embedded Database.
00:30Now you might be wondering, how does a database fit in?
00:33You might have worked with things like MySQL or you might have worked with things like SQL Server and these all seem
00:38to be server side implementations, so how does this actually fit in with Adobe AIR?
00:42Well let me give you an example.
00:44The first thing that you will need to know is that SQLite files are just files, the entire database is contained
00:52within a single file and I actually have one here on the desktop
00:55and we are going to be working with that one momentarily.
00:58But the other problem that you come into with that is a lot of database developers are used to working with tools
01:03such as PHP MyAdmin or working with some other GUI tools that come in with MySQL to do the work.
01:09So how do you work with SQLite databases?
01:12Well one of the tools that will be very helpful to you is from Christophe
01:15and Adobe who has developed the SQLite Admin.
01:18And it actually was developed inside of AIR.
01:20You can see the URL here on the screen and I would recommend downloading this application
01:25and installing it whenever you are working on an application that is going
01:28to be using the embedded SQLite support inside of AIR.
01:31I am going to go ahead and open up the application, and it is going to let us actually open up a database.
01:37So to prove to you that this context file on the desktop is actually a database, we are going to select an existing one.
01:43So we will just go to desktop and we will select Contacts and we can look here and we can see
01:50that this just has some basic information, ID, last name, middle initial, so on and so forth
01:56and we actually can even query this data.
01:58Now this is going to seem a lot like working with some of those tools that you are used to working with.
02:03And the queries are going to seem a lot like the normal queries that you would write for MySQL or for SQL Server.
02:08So we can just go in if we wanted to and say Select all from Contacts, and then Execute Query.
02:19And now we would see all the results returned.
02:21So working with the SQLite database inside of AIR and while it is encapsulated inside of a single file,
02:27still gives you the developer, the familiarity of working with SQL statements and working with queries
02:33but it just happens to be very efficient and works very well.
02:36That entire query was made on a dataset of over 10,000 entries and so the speed that you can access data within AIR
02:42through the SQLite Database is also a great asset as you code your applications.
02:46So let's begin to look at this functionality and see how we are going
02:49to integrate it into our Contact Manager application.
Collapse this transcript
Working asynchronously vs. synchronously
00:01Just as with File System Support inside of AIR,
00:03the embedded database provides two different programming models for interacting with it.
00:07First being synchronous allows you to chain multiple commands together without having
00:12to worry about responding to event handlers.
00:14Asynchronous is quite different.
00:16Commands can be executed in sequence simultaneously but you have to know
00:20that they are completed by using event handlers.
00:22So let's give an example of what the code would look like for each.
00:26Now I know we haven't covered any of these classes yet but we are going to go in depth into them in the next videos.
00:31But I just wanted to give you an example of what it would look like for each of the two programming models.
00:36So first, with the synchronous example, we create a new SQLConnection, we then actually open the connection and we know
00:41that that is synchronous because we didn't call the openAsync method, we created a new SQLStatement,
00:47we then create a query, we execute it and then we get the results back.
00:51All of this is done within only 7 lines of code.
00:54And not only that but this code could reside inside of one single method.
00:59The asynchronous example is quite different.
01:01It starts off by creating an SQLConnection, but then we immediately see that we have added an event listener
01:06that tells us when the connection has actually been opened.
01:09Then we actually open an async connection.
01:11Once the event SQLEvent.OPEN is fired, then we can actually create the SQLStatement, we create the query
01:17and then we add yet another event listener to tell us when the query has been completed.
01:21Then we execute the query.
01:23Finally when the query has been completed the onResult method is called
01:27and then the results are actually extracted from the SQLStatement.
01:31So we can see that there is quite a lot more programming involved in the asynchronous programming model.
01:35But there are some things to understand.
01:38First, as we said the asynchronous connection to the embedded database will have a lot of additional code.
01:43Now this becomes even more complicated if you are chaining multiple queries together, which leads us to the next point.
01:49If you are using transactions with a lot of queries this can become even more complicated,
01:53to be sure that everything is handled in the proper order.
01:56But in the end asynchronous still provides the end user with a more quality experience.
02:01Because of this, the examples that we are going to be using are going to be asynchronous.
02:05The other reason for that is if you can program
02:08in the asynchronous model you don't have any trouble using the synchronous programming model
02:12in situations where it is appropriate.
02:15Now because of the speed of the embedded database you can consider using the synchronous programming model
02:19when you are working with small datasets.
02:21So if you are in a controlled situation and you know that the data is not going to grow to be a variable
02:26in a large dataset, there are situations where synchronous programming is okay.
02:29And another great use of synchronous programming is when you are developing prototypes of applications,
02:34it is a lot quicker to develop a code with synchronous than it is with asynchronous.
02:38So we are going to keep this in mind but we are actually going to stick with the asynchronous model
02:42when we are building our applications in this chapter.
Collapse this transcript
Creating a database
00:00Now that you have heard all this wonderful talk about the power that you will have as a developer working
00:04with the embedded database, you are probably ready to jump in and start working with it.
00:09The first step obviously for database support is to actually create a database.
00:13Now it's a little bit different within AIR as it is from working in something like MySQL.
00:18So we are going to cover the whole process from beginning to end on how to create a database within AIR.
00:23So we are going to go to File and then Open and then we are going to open the Contact Manager01 file
00:29within the chapter 12 folder of the exercise files.
00:34Once our application loads up, we are going to highlight the Actions layer and then go to Window and then Actions.
00:40Now we are going to scroll down, you can see that we have already organized the code, but we are going to go ahead
00:45above the section that has event handlers and we are going to add a new section to our application.
00:51We are going to keep all of the code for our database in one place, so we can easily refer back to it.
00:58So we will just say this is going to be database code and we will just enter tag.
01:05Now the first step to creating a database is actually creating a reference to a file,
01:11then you actually connect that file to the database.
01:15Now the good thing is that if a file already exists,
01:17it won't be created again, it will just open the existing database.
01:21So we actually can pretty much contain all of this code inside of a function that we will call openConnection.
01:26So we will say function openConnection and it's not going to receive any events, because this is something
01:34that we are actually just going to call when the application launches and then it's not going
01:38to return anything, so we can leave the return type as void.
01:41Now inside of here, the first thing that we are going to need to do is actually create an instance of the File class,
01:46but for us to be able to do that, we are going to need to be sure that we have imported some classes.
01:51So let's scroll back to the top of our application.
01:54Now we already have imported flash.desktop and we are going to need to import a new set of classes and those are going
02:01to be the classes that relate to the database.
02:03Now there are many, many different classes that we are going to need,
02:06so we are going to just import it in entire package.
02:08We'll say import flash.data.*.
02:13You can quickly see that if you have to import a lot of different classes it is a lot easier at times
02:18to import the entire package and in a lot of situations it makes sure codes are lot cleaner as well.
02:23So let's scroll down back to our method openConnection and we are going to start off by saying var dbFile of type File is equal
02:35to and we are going to actually point it to the applicationStorageDirectory.
02:39So we will say File.applicationStorageDirectory.
02:43and then we will use the resolvePath method and then we will pass in the name
02:48of our database file, in this case, contacts.db.
02:54Now AIR does not require that you name your files .db or .sqlLite.
02:59You actually can choose whatever extension you would like.
03:03Now the important thing also to remember here is because we are saving it in the Application Storage Directory,
03:07we can then access this whether it's on Mac or PC because we are using the reference to Application Storage Directory
03:13which will be automatically updated for each of the OS's.
03:15Now that we have created the reference to our file, we now can actually connect that to an instance
03:21of the SqlConnection class and that's the class that allows you to actually open a file for database use.
03:28So we will say var conn:SQLConnection = new SQLConnection.
03:38And now here is where we are actually going to choose between doing synchronous calls
03:46within the database and asynchronous calls.
03:48As we stated in the previous video, we are going to choose to use asynchronous calls because in almost all situations,
03:54it's going to provide for a better user experience.
03:56So we are going to say conn.openAsync and then we can actually pass in the reference to our file.
04:05Now there is an option here, you can choose not to pass in a reference to a file
04:10and it will actually create a temporary database that exists only in memory.
04:14It will last as long as the application is open, but then when the application is closed, it will be deleted.
04:19In some situations, this can be useful.
04:21For our application, we are not going to be using this functionality.
04:25So now we are going to pass in the reference to the file.
04:27We will say dbFile.
04:30Now because we are using asynchronous methods we are going to need to be sure that we listen
04:35for when the connection is actually ready to use.
04:38So before we actually call the openAsync method, we are going to add an event listener to our conn object.
04:43And now we are going to listen for the SQLEvent.OPEN event.
04:54And then we will know that the connection has actually been opened and we can work with the database file
04:59and we respond to that with the onDBOpen.
05:04However there might be situations where there is an error, maybe the file that we have configured is corrupted
05:10or maybe there has been a mistake in our code that's actually leading up to this point,
05:12so we are also going to want to listen for one more event conn.addEventListener.
05:18We are actually going to listen for another event that will be SQLErrorEvent.ERROR.
05:26Now in this case, this could be caused by a multitude of things, but basically what it's saying is
05:33that for some reason we could not open the database connection the way that we would like.
05:37So we are also going to listen for this and we will call the onDBError.
05:44So now we are going to go ahead and create those two methods.
05:46First we will create the onDBOpen and it will receive an event of type SQLEvent and it's not going
05:58to return anything so we can set the return type as void.
06:02Next we are going to create the onDBError method and it's going to receive an event of type SQLErrorEvent
06:13and it's also not going to return anything.
06:15So we can leave the return type as void.
06:16Now we are going to go ahead and just make notes of where we are in these methods.
06:23Ready to work with database and down here we will put a trace statement just so that we know that's been an error.
06:30We will say "Error Opening Database."
06:35Now just with this code, you have been able to first of all create a reference
06:39to a file that will soon be your database.
06:42You have learned to use the SQLConnection class, you have learned to listen
06:45to the SQLEvent.OPEN event as well as the SQLErrorEvent.ERROR.
06:50You have opened an asynchronous connection to the database file and now we are actually ready
06:54to start creating tables inside of our database.
Collapse this transcript
Creating tables
00:01Now that we have created a connection to a database within AIR,
00:04we are now ready to actually create the table that will hold the data.
00:07So now to accomplish this, we are going to be introduced to a new class SQLStatement.
00:11So let's go ahead and open up our application and work with it.
00:15We will go to File and then Open and we are going to go to Contact Manager02 that's
00:19in the Chapter 12 folder of the exercise files.
00:23Now we are going to be sure that we are on the Actions layers
00:27and then we are going to go to window and then actions.
00:31Now once inside of here, we are going to scroll down to where we actually created our database connection
00:37and we are going to change one piece of code that we have already written.
00:40This works great for our sample before in just showing how to connect with database.
00:44One of the things that you will learn is with the SQLStatement class you will actually need
00:48to pass it a reference of the SQLConnection, so we are actually going to make this SQLConnection a property
00:55that can be accessed from the entire application, so we will go ahead and take just this section of code right here,
01:01we will cut it and we will scroll up to the top.
01:05Now you see here, we have a section called Constants and Properties.
01:08When I press Enter and we will go ahead and paste this in.
01:12We don't need to do anything else to it yet.
01:15Now we can actually scroll down into our openConnection method and now we can just say conn = new SQLConnection.
01:24By doing it this way, we have now just made it a lot easier to get to our SQLConnection object.
01:29Now we actually can begin working with the SQLStatement.
01:32Once we know that we have connected to the database, we now can start working with the database file.
01:37So inside of onDBOpen, we are going to call a method called createTable and now we need to create this method.
01:44So we will scroll down below our onDBError and we will create a new function called createTable.
01:49It's not going to return anything, so we can leave the return type as void.
01:54Now the first thing that we are going to need to do is create a new instance of the SQLStatement class.
01:59So we will say var query:SQLStatement= new SQLStatement.
02:11Now the next thing that you are going to have to do for each of your SQLStatement objects is you are going to need
02:15to pass it a reference to your SQLConnection, so we will say query.SQLConnection is going to be equal to and we are going
02:24to set this equal to our connection object which is just con.
02:27Next we actually can begin constructing our actual query.
02:31So the first thing that we are going to need to do is actually load up phpMyAdmin.
02:36So let's open Internet Explorer and we are going to look at the way that the database is structured on the server side.
02:42So we will go to local host, then we will go to phpMyAdmin and then we will look on the side,
02:48we will find the contacts database and then we will find the person table and then we will look at its properties.
02:54We are going to need to create 8 different fields within this table.
02:57We are first going to have a person ID, then we are going to have a first name, a last name,
03:02street address, city, state, email and phone.
03:06So we are actually going to keep this window open over to the side
03:10as we begin working with the database inside of Flash.
03:13So we are going to go ahead and resize Flash so that we can still see the window from phpMyAdmin.
03:20So let's be sure that we are on the Actions layer and we will press Window and then Actions.
03:25And we actually can scale this so it will fit into the window.
03:30So we will actually begin creating our statement by saying var queryText
03:37and you can choose whatever you would like, it's just going to be a String.
03:40And we are going to begin now crafting the query.
03:42We are going to say "CREATE TABLE IF NOT EXISTS,"
03:49this way we can ensure that we are not actually writing over the table if it is already created.
03:53If some of this looks unfamiliar to you, it's okay.
03:55You might want to take some time just to go back and research some basic SQL statements.
04:00We are going to be using createStatements and selectStatements and then insertStatements
04:04and so these statements are actually very basic in nature.
04:06We are not going to be going and doing very complex joins or other complicated SQL procedures and a lot of times in AIR,
04:12you are not going to be doing that either, so just brushing up on some of the basics might be helpful
04:16to you if any of this is looking strange.
04:18So we are going to say "CREATE TABLE IF NOT EXISTS" and then we are going to say "CREATE TABLE person" and now we are going
04:24to need to actually create each of the specific fields.
04:28Now we are actually going to place the name of the table in single quotes and now we actually can leave a space
04:34and then we are going to move this down to the next line.
04:37Now inside of here we are going to need to start listing names of each of the fields.
04:42So we will say first that we are going to want to create the field personid and it's going to be
04:47of the type INTEGER then we can put a comma, we will leave a space and then we will move down to the next line.
04:54Next we are going to create firstname and it's going to be all lowe case to match what's
05:00on the server and that's going to be of type TEXT.
05:02Then we will leave a space and then we will move to the next line.
05:06Then we will create lastname, TEXT.
05:09We will leave a space, move to the next line and after that we will do street address and that will be of type TEXT,
05:17leave a space, move to the next line and after street address, we will do city,
05:21TEXT and move to the next line then we will do state, it will be TEXT as well.
05:28Then we will actually do email and I bet you will never guess, yes it's TEXT too.
05:33And then after email we will do phone and in this case we are actually going to make phone TEXT as well
05:38because it actually will possibly contain some special characters and actually we don't need to leave a comma
05:44after the last one. Then we can add our closing parenthesis and then we can actually close our statement.
05:52Now the important thing to understand here some of these items might not look
05:55like they exactly match the types that are listed on the server side.
05:59SQLite actually has a different way of looking at it,
06:03instead of actually calling them types each column has what's called an affinity type
06:07and an affinity type is a little bit different and functions differently.
06:10Now for the purpose of working with the database in AIR, you can actually find a type that corresponds very closely
06:15to a type inside of MySQL but whatever your server side database is and then just choose to use that.
06:21In this case, everything should map fine between server side and between here locally with the embedded database.
06:27Now after we have created our query text, we can now actually assign that as the query text for our query,
06:35so we will say query.text is going to be equal to queryText.
06:41Now we are going to need to add some of event listener, so we can find out if our query actually succeeded,
06:46so we are going to say query.addEventListener and we are going to listen specifically for the SQLEvent.RESULT
06:54and then will actually call the queryResult method.
07:00Next, we are going to add another event listener just as we did with the SQLConnection to be sure
07:06that there wasn't an error. So now we will listen for SQLErrorEvent.ERROR.
07:13And in this case, we are going to call a method that we have already created onDBError and in this case we also can give
07:19that one a much more generic trace statement.
07:23We will just say "Error with Database."
07:27Now before we actually implement the queryResult method, we actually need to execute our query
07:32and it's actually done by just saying query.execute.
07:36Next we actually can go and create a new function and of course this one is queryResult
07:43and it receives an event of type SQLEvent.
07:47It doesn't return anything, so we can leave the return type as void and now inside
07:51of here we can just say for the moment, "Query was Successful."
07:56At this point, we will actually put in a trace statement that also says Successful.
08:00And we will actually put a breakpoint here so that when we debug our application, it will actually let us know
08:06if it was successful in the same way open a breakpoint next to the onDBError method.
08:11Now that we have actually added these items in we are ready to actually start executing some things with our database.
08:17First we are going to have to call the openConnection method at the very beginning of our application,
08:23so we will go ahead and highlight the name of that method.
08:26We will scroll up to the top, under where it says INIT Methods,
08:29and right under loadData, we are going to call openConnection.
08:33Now again remember the loadData method that's already included in the application doesn't have anything to do
08:37with the embedded database at least not yet, it just loads data from the server.
08:41So here is what will happen.
08:42We will call the openConnection method.
08:45The openConnection method will fire to create your reference to the file, create a new SQLConnection,
08:51assuming it opens properly, it will respond by calling the onDBOpen method and again it's opened synchronously.
08:58When the onDBOpen method fires, it will call to createTable method which will then call the query,
09:04which will then be executed, and then if everything works as it should, it should call the queryResult method.
09:12So let's go ahead and go to Control and then Test Movie.
09:17And that's going to give us an error that we have not yet included in the file inside
09:22of our application so we actually can quickly remedy that.
09:26Let's go up to the top and we will say import flash.FileSystem.File.
09:33Now we can save our application and now this time since we know that we have actually fixed that error,
09:39we are going to want to actually debug our movie, so we will go to Debug, Debug Movie.
09:44It will take it a second as it's loading and we can see here that it actually blended in our breakpoint successful,
09:53so that means that our table was created and it actually was created with the fields that we wanted.
09:57So now at this point, we have actually gone a long way in creating SQLConnection and then executing a query
10:03that created a table within our database.
10:06Now at this point we should be ready to create and execute SQL queries on the table that we created.
Collapse this transcript
Creating SQL statements with parameters
00:01Now at this point you have actually done a lot with the database.
00:04You have learned how to actually create a reference to a database file as well
00:07as create a database in memory if you need to.
00:09We have also walked through the process of creating a table and basically learning how to use the SQLStatement class
00:15but now we are going to take that one step further.
00:17We are going to work with several things for the first time in this video.
00:20We are going to learn how to work with parameterized queries.
00:23We are also going to use Insert and Delete statements for the first time so let's go ahead
00:27and jump into our application and let's make it work.
00:30We will go to File and then Open and we are going to open ContactManager03
00:35in the Chapter 12 folder of the exercise files.
00:37We will open the file and before we jump into the code we are going to need to add one item to the Stage so I am going
00:44to go ahead and I am going to lock all the layers except for the Components layer and I am going
00:48to select the lists currently on the left side.
00:51I am then going to go to the Free Transform tool and then I am going to select the list and then I am going to hold
00:56down the Alt key or the Option key on Mac and we are just going to bring this
01:00up a little bit to liver him for a button below.
01:02Now I am going to go and drag a button from the Components window
01:08and just drag it on to the Stage directly below the list.
01:15Now in this case I am going to highlight first the list and then the button and then we are going to make sure
01:20that they match size by pressing the Match Size button then
01:23at this point we will be sure that they are aligned to the left side.
01:28We will be sure everything is positioned properly and now we need to give our button an instance name.
01:33We are going to call this button syncButton.
01:35Then we are going to also want to change the parameters because let's face it, label is not that descriptive.
01:43We are going to call it Sync to Database.
01:47Okay now that we have created our button, put it on the Stage, given it an instance name, we are ready
01:54to actually jump into the code. So I am going to lock the Components layer.
01:57I am going to highlight the Actions layer and then go to Window and then Actions.
02:01The first thing that we need to do is add an event listener for our Sync button.
02:04So let's go down to the section where we add event listeners and we are going to say syncButton.addEventListener
02:12and then we are going to listen for the MouseEvent.CLICK event
02:16and then we respond to that with the onSync method.
02:22So now let's go ahead and scroll down to our database code and we are just going to scroll to the end and we are going
02:29to create a new method called onSync and this is going to receive an event of type MouseEvent and it's not going
02:36to return anything so we will leave the return type as void.
02:39Now let's think a minute about what we need our application to do.
02:42Now that we have created a table we are going to want to be able to push a button
02:46and download all of the contacts from the server.
02:50At that point we are going to want to be sure that those are the only ones that are actually in the database at that time
02:55so we don't want any old records left behind only what's on the server and then we are going to want these to stay
03:00on our hard drive so that if we need to open up our application at some point
03:03and we don't have an Internet connection we still have access to our contacts.
03:08So the first thing we are going to need to do is we are going to need to run an SQL statement that will delete all
03:12of the records from the person table inside of our database.
03:16As I said before this will ensure that we are dealing with only the newest data
03:19so let's go ahead and create a new SQL statement.
03:22We will say var q of type SQLStatement is equal to a new SQLStatement.
03:32Then we will attach it to our SQLConnection and we will just reference it to the conn variable.
03:39Then we need to actually put in a text for our query.
03:42In this case it's actually going to be pretty easy.
03:44We are going to say q.text is going to be equal to Delete From, and then we will put in single quotes, person.
03:54And that's the name of our table and you will know this if you are familiar with SQL.
03:57When you run a delete command you can say delete from person where first name equals David if you want.
04:04But if you just say delete from person, it's going to delete everything in the entire table so you want to be sure
04:09that this is what you want to do before you enter a command like this but it is what we want to do so we want
04:14to go ahead now and add event listener so we can then respond to this.
04:17So we will say q.addEventListener and we listen for the SQLevent.RESULT that will be fired
04:23when our query is run successfully and then we are on to another method that will create called addContactData.
04:30Next we are going to want to listen for an error and that will be an SQLErrorEvent.ERROR and then we will respond
04:43with the method that we have used previously onDERROR.
04:47Now we are actually ready to execute the query so we will say q.execute.
04:53Now this is a query that we have done before.
04:55This is very similar to the way that we setup or Create Table query
04:59but now when we build our addContactData method we are going to use another new technique, parameterized queries.
05:05So let's go ahead and create the new method addContactData.
05:10We will receive an event of type SQLEvent and it's not going to return anything so we can leave the return type
05:18as void so what we are going to do is we are going to go and look at the list.
05:21When we opened up the application the application called the server, downloaded all of the current items
05:27and then stored it inside of the list that's on the left side of the application.
05:32Now that list contains a property called dataProvider and that is actually of the type DataProvider
05:38and there is a function in the DataProvider class that allows us to extract from that basically all the data
05:44in the form of an array and so that's what we are going to use but to do that we are actually going to have
05:48to import the DataProvider class so let's go ahead and scroll back up to the top where we have our imports.
05:55Now this point we are going to import fL.data. DataProvider and we will scroll down back to our method.
06:03Now we are going to want to loop through each of these items so to do that we are first going to need
06:09to extract the array from the data provider and then we can loop over it using it for each statement.
06:13So first let's go ahead and grab the data out of the data provider so we will say var contactData of type Array
06:22and we are going to set that equal to the peopleList which again is the list on the left side
06:27of our application, .dataProvider and then we will call the toArray method.
06:33And that will return all the items as arrays.
06:36Now that we have our array we can look through it by saying four each.
06:40We will say var o Object in contactData.
06:47Now again what this means is it will create an object for each of the items in the contact data
06:54and then we will loop through them each one by one.
06:56Now at this point we are going to need to run a query that actually will insert each item into the database
07:02so we are actually going to run an insert query so we will start off
07:06by creating our new SQL statement. var q SQLStatement and we will just use q because that's short for query
07:13and at this point you know what's next we are going to go ahead and add the reference to our SQL connection.
07:21Then after that we are going to go ahead and type the text for our query so here is what we are going to need to do.
07:26We are going to use a new format for the entries within our query.
07:31We are going to say Insert Into and then of course we use our table name which in this case would be person, Values.
07:40Now we can move down to the next line and here is where we will start adding in our parameters.
07:45So the first parameter that we are going to enter is personid.
07:48Now to make it known that it's a parameter, we are going to put a colon in front
07:51of it so we will say colon and then personid.
07:55The next we will say colon and then firstname.
07:59Then we will say colon and lastname and we will just go ahead and do it for each of the items in the query.
08:15So now we have created our query with parameters.
08:18Now because we use parameters there is one extra step.
08:21We now have to actually assign a value to each of the parameters.
08:25Now at first this might seem like a lot of work and you want to know why do we do it this way.
08:28And if you remember back to some of the other code when we don't use parameters, number 1, we run the risk
08:33of not actually treating our data as it should be treated.
08:36When we use parameters it actually looks and finds the affinity type of the column it's supposed to insert data in
08:41and we can actually format that data appropriately so for example it knows that it doesn't need to put integers
08:46in single quotes but it does need to put text in single quotes.
08:49In addition queries can look horrendous without using parameters because you are going to have
08:53to concatenate a lot of different data types in with the text so in this case parameters may occur much more stable,
08:59more legible and it's certainly going to be a lot easier to deal with when we have to debug anything.
09:04So the way that you enter a parameter is you are going to look at the parameters property of the SQLStatement.
09:10So we will say q.parameters and then we just need to tell it which parameter we are talking about. So
09:16in this case we are talking about personid and notice that we also did include the colon here as well so we will say
09:22that parameter is equal to o.personid and we will just need to go ahead and do this for all of them
09:28so to make it a little bit easier I am just going to copy this line.
09:31I am going to paste it 7 more times and now we are going to go through and change.
09:37The next one would be firstname then we will do lastname.
09:52Then after streetaddress we will do city and then finally we will do phone.
10:07Now we are going to need to do one more thing before we execute our query.
10:10It's generally a good practice that if you are using parameters within an SQLStatement you are going to need
10:14to call the clearParameters method of the SQLStatement.
10:17Now this is especially important if you are reusing your SQLStatement classes.
10:21If you actually get into the habit of doing this before you actually enter your parameters you can ensure
10:25that you will never have any problems.
10:27Now next we are going to need to add our event listeners.
10:29So we will add our event listeners.
10:31The first one we will say we are going to listen for SQLEvent.RESULT
10:36and that will fire the onInsertResult method.
10:44The next we are going to listen for the error.
10:51And that will go to our onDBError method and then now we are ready to actually execute the query.
10:59Now I am going to make one more change that we actually can look at the data that we have actually put in.
11:05If you look when we actually created our connection to the database we created our database inside
11:11of the application storage directory and that's fine.
11:14As a matter of fact that's where you would want it for your application
11:17but just so that we can preview our actual data fairly easily we are actually going to take and we are just going
11:22to put it on the desktop directory for the moment. So this will actually store our database file, contacts.db,
11:29on the desktop. So now we can go ahead and save our application and everything should work properly.
11:35Just to be sure we are going to be sure that we have some breakpoints set.
11:38We do at this point actually have one more method that we need to create and that is our onInsertResult method
11:42so we will go to create a new function, onInsertResult, and that's going to receive an event
11:51of type SQLEvent and the return type's void.
11:56Now we don't really need this to do much because this will actually be happening a lot of times really,
12:00really fast when we actually push the Sync button. So we just want to actually put a trace statement in so
12:05that we can actually get some feedback on what's happening when we are
12:08in Debug mode and we will just say "Insert Successful."
12:12Now it looks like everything is about ready to go.
12:14I am going to go ahead and put one breakpoint here inside of the onInsertResult so now we can go ahead
12:20and save our application and go to Debug and then Debug Movie.
12:29So now we can see we have actually got a breakpoint left over from another query.
12:32If you actually have a breakpoint in your code that you want to be sure
12:35that it doesn't hit again during your debugging session you actually can just click it and it will revert
12:39from having a red circle with the arrow to just having the arrow.
12:41Then we will press Play which will move through to the next breakpoint.
12:46We can see here that it says successful and that was for when our table was created.
12:50Now we can open our Contact Manager and we can actually sync this to the database
12:55and that's actually going to pass back another SQL event.
12:58That's actually the breakpoint that we set directly inside addContactData and then we will press one more time
13:05and we can see here that we had a successful event on our onInsertResult. It came back without any errors
13:11and you actually could go through here and see more properties of the SQL event and the SQL statement
13:15but this just tells us that everything is working properly. So now again if we hit the Continue button it's going
13:20to keep going through every time it's trying to insert data so we also can just press the break points
13:26so that it doesn't fire again and then we will go ahead and hit the Continue button and it will cycle through
13:30and you can see all the insert successfuls that are coming in from our queries.
13:34We will go ahead and let that finish up and this just shows you how to use parameterized queries in this case
13:39with an insert statement but you can easily expand on this and use this for select queries as well so we are going
13:45to take what we have learned from this and we are going to finalize some
13:47of the online/offline capabilities of our application.
Collapse this transcript
Selecting data and retrieving results
00:00So now that you know how to actually execute queries and parameterized queries within the embedded database in AIR,
00:06we are now going to work on how to retrieve results from a Select Statement.
00:09So to accomplish this we are going to need to open our application.
00:12So let's go under File and then Open and we are going to open ContactManager04 which is
00:17in the Chapter 12 folder of the exercise files.
00:19Now pretty much everything we are going to need to do in this video is going to be within the Actions panel
00:25so we will select the Actions layer and then go to Window and then Actions.
00:29Now here is the theory of what we are going to do.
00:31We want our application to be able to function online or offline.
00:35Now we did most of that actually in the last video where we took and we actually inserted all
00:39of the values from the server into the database.
00:42Now at this point we are going at the application when it starts up to detect whether it's online or offline.
00:48And then depending on whether it's online or offline either load data from the server or from the database.
00:54The first thing that we are going to need to do is look at our loadData method.
00:58Currently inside of our loadData method as you can see we just use the URLLoader to actually load in the XML.
01:04But now we are going to want to actually have it check to see if it's online.
01:08So if you notice we created a connectionState variable this actually either holds the word Online or Offline.
01:14And so we are going to be using that when we actually test
01:16when the application launches to see if it is online or offline.
01:20In addition we are going to create one more parameter,
01:22Initialize it will be Boolean and we will set initially to False.
01:29And the reason that we are doing this is, we want the application to check one time when it's launched.
01:34After it's checked to see if it's online or offline then at that point we will load data from the appropriate method.
01:40So at the moment we can go ahead and delete the loadData method from the Init Method section of the code
01:44and then we will add it back in a moment.
01:48So let's go to our loadData method, we are going to go ahead and put and if statement,
01:52we are going to say if connectionState is equal to Online then we are going to want
01:59to execute the code that we have been executing.
02:02However, if it's not then that's where we are going to start working with our SQL statement.
02:08So then we will say else and then we are going to create a new instance of the SQLStatement class we will say var q
02:15of type SQLStatement is equal to a new SQLStatement.
02:19And then we will say q.sqlConnection is equal to conn, which we defined previously.
02:25After that we are going to go ahead and add our query text which will be q.text
02:29and that will be equal to Select, then asterix(*), From Person.
02:35And this is just the way that an SQL you basically say go and grab everything from this table,
02:39we want all of the different columns and all of the data just go ahead and bring it back.
02:43And so now that we have added that we could add our event listeners and we are going
02:47to be listening firstly SQLEvent.RESULT and that will take us to the onLoadSQL method which we will create shortly.
02:55And we also want to listen for any errors so we will say addEventListener SQLErrorEvent.ERROR.
03:02And then we can use the method that we have been using previously onDBError.
03:06Now that we have added our event listeners we can actually execute our query so we will say q.execute.
03:15So this is only going to be executed if the application starts in an offline mode.
03:21Now to actually tell the application to start the process of checking to see if it is online we are going to have
03:26to move one method call up to the Init Method section of our code.
03:29So we will copy the name here of this method, which is monitorConnection. Basically it is just sets up a URLMonitor
03:35that checks the local WebServer to see if we can access it and then it calls a method called onConnectionStatus,
03:40which we will be heading to in just a second.
03:42And finally it actually starts the URLMonitor.
03:44So we will move this call to monitorConnection directly up after openConnection.
03:52Now we will scroll down to the method that we referenced with the URLMonitor and here is
03:59where that initialized property is actually going to come in useful.
04:02We are going to come down here and say "If a value of initialized is false" then we are actually going to want
04:10to first set initialize to true and then we are going to want to call the loadData method.
04:17So that every times it loops through and it is checking the URLMonitor it isn't trying
04:20to load the data each an every time.
04:22So now we actually can head back up to the SQL section and we are going to create a new method onLoadSQL.
04:31It's going to receive an event of type SQLEvent. It's not going to return anything
04:38so we can leave the return type equal to void.
04:41Now inside of the onLoadSQL method we are going to remove all of the people that are in the peopleList
04:46and then we are going to loop through the results for the query and place those people's names inside
04:49of the peopleList inside of our application.
04:51So the first thing that we need to do is just say peopleList.removeAll
04:56and that will give us a fresh place to start.
04:59Next we are actually going to grab the SQL statement out of our event.target property
05:03so we will say var q SQLStatement is equal to event.target as SQLStatement.
05:14Next we are going to create a variable that's going to be results and it's going to be of type SQLResult.
05:20And we are going to set that equal to the method of the SQL statement class that actually returns the results.
05:25So we can just say q.getResult.
05:27So this is actually going to pull the results back.
05:31Now inside of the results variable that we have created there is going to be a property called Data
05:36and that's actually going to contain the data from the SQL query so next we are going to go
05:41down at this point we are going to add in the trace statement that says we are going to check values.
05:45So we are going to actually set a breakpoint right here next to this trace statement and we are going to look
05:51at what is actually returned from the SQL query.
05:53So we need to be sure that a few things are true, first we need to be sure that if we disable our internet connection.
05:59But for me I am actually going to have to go one step further because I am using the local Web server so I am going
06:05to actually go and I am going to shut down the local Web server.
06:10You obviously don't have to worry about that step it you are using a server that's somewhere else
06:14or if you are using a shared Web server somewhere.
06:16But now since we disabled the Web server, when we go to the loadData method it should actually see that it's not online
06:24and we will actually put a breakpoint here as well.
06:27Then it will start executing the SQL statement it will select all of the records from person
06:31and then will add the event listener and it will go to the onLoadSQL method, if it's executed properly.
06:36If not, if there is some type of an error, it will go to the onDBError method
06:40and we already have a breakpoint next to that.
06:41So at this point we should be ready to test the first part of our application.
06:45Now notice we haven't inserted any values yet into the actual peopleList but using this we are actually going
06:51to be able to see the results that come back from the SQL query so let's go to Debug and then Debug Movie.
06:59Okay we can see our first query result has come back and this is when we created the table.
07:03We still have a breakpoint there, so we can go ahead and just select
07:06that breakpoint to unbreakpoint and then keep going.
07:10Here you can see we have ended up at the loadData method and we actually could go through and check and we would see
07:14that the connectionState is equal to Offline so it should actually loop through and go to our SQL code.
07:19And we can see again that we have ended up here at our SQLResult so we can see
07:23that we have actually queried the database and got results back.
07:26And you can see here that our results variable is of type SQLResult.
07:30If we open it up we can see here that it has several properties and data is the one that we are concerned with.
07:36So if we click on Data it will take it just a second because it's having to look through a lot of values
07:43but then it will load up and you can see that each of the items that comes back is an object and inside of each
07:48of those objects or the properties that are in the database for that given person.
07:52So we can now use this data to populate the peopleList and now truly have a nice online offline application.
07:58So let's end our debugging session and let's finish up the application.
08:02Now we can delete this trace statement and we can start the process of looping through the results.
08:06We will say for each var o, which will just be a generic object, in results.data.
08:16Now for each of these we are going to want to add them to the peopleList
08:21so we will say peopleList.addItem and then I want to add the object.
08:29Now the great thing is this requires a lot less code than when we loaded in the data from XML because when we loaded
08:34in the data from XML we actually had to parse it and we sure that all the data was in the right format, here however,
08:39we can just add the data to the peopleList.
08:41There is one additional item that we have to do however. We need to go to our peopleList. Each of the objects inside
08:47of the peopleList also has a label property and this label property is equal to last name, first name.
08:52So we will add that in as well we will say last name, then we will put a comma and a space and then say o.first name.
09:01Now we should be able to save our application and since we have already done our debugging
09:06at this point we should be able to actually just go to Control and then Test Movie and notice again
09:11that our Web server is not running we can see that Apache doesn't have running next to it
09:15and also our internet connection is disabled so I have nothing up my sleeves and then we can go to Control
09:20and then Test Movie and we can see that all of our values have been pulled
09:25in even though we are offline we are actually syncing data from the local database and we can use the application just
09:31as we did previously to retrieve information for different contacts within our list.
09:35So this is the beginning of a powerful Online/Offline application.
09:39You might also want to develop an application that allows the user on the AIR app to add a context and then send
09:44that data back to the server, developing a true two-way form of communication as opposed to just one way.
09:50However you use it, the SQL support inside of AIR is powerful and you can use it to create a lot
09:55of different types of applications not just Online/Offline applications.
09:58We have now looked at two different ways to store data on the user's local hard-drive.
10:02Now we will look at one other option that's available to store encrypted data.
Collapse this transcript
13. Using the EncryptedLocalStore Class
Working with byte arrays
00:00Another one of the powerful classes that's available within AIR is the ByteArray class.
00:04And in this chapter we will be looking specifically at the encrypted local store which allows you
00:08to store encrypted binary data on the user's hard drive using native operating system encryption methods,
00:14but to do this you going to need to be familiar with ByteArray.
00:16But the good thing is even though a ByteArray might seem a little foreign to you at first;
00:20working with the ByteArray is very similar to working with the FileStream.
00:23So we will be moving forward with it and some of these methods should look fairly familiar to you.
00:27Now there are different ways that ByteArrays can be used, in this case, we are going to be working
00:31with the encrypted local store, but in addition to that, if you are going to be working with files
00:35on the user's hard drive, you will be working with ByteArray data which basically just means a stream of binary data.
00:40So we are not talking here about strings and arrays, we are actually dealing
00:43with actual ones and zeros that exist for a given file.
00:46And then you also have to use ByteArray instances inside of the encrypted local store as I mentioned.
00:51When we actually get data to store in this encrypted local store,
00:55it actually has to be in the ByteArray format when we pass it in.
00:57And then finally and we will be doing this later, if you are going to download and update for an AIR application,
01:02you will be using ByteArrays to actually get data from the URL stream and then save it to the user's hard drive.
01:07So let's look at the sample used for ByteArray.
01:09We are going to take a string and write it into the ByteArray and then we are going
01:13to take that same string and read it back out.
01:15So if you notice here we just have defined a string and then we create a new instance of the ByteArray class.
01:20Then we use a method called writeUTFBytes.
01:23Now this is the same name that we used when we worked with FileStream earlier.
01:27This is basically what you are going to use anytime you are working with strings.
01:30So you actually write it into the ByteArray, but then you can actually take the ByteArray
01:33and use the readUTFBytes method to return the string back to you in its original form.
01:38There is also a property that we use here called ba.bytesAvailable which will be a property of your instance
01:43of the ByteArray class that will tell you how many bytes are available.
01:47You can pass that into the readUTFBytes and it will return the entire string.
01:50Now the important thing to understand is that there is a different one
01:53of these methods for each of the different data types.
01:56In addition there is even some multiple data types for some numeric values.
02:00So you just want to be sure that you use the appropriate method for your data type.
02:03And here are some of the common methods here.
02:05We have already talked about write and read UTF bytes, but you also can write an int, read an int,
02:09and then write a Boolean and read a Boolean as well.
02:11ByteArrays can do a lot of different things, this basically can allow your application to read files of any format,
02:17but in this instance we are going to using it specifically to read data into the encrypted local store inside of AIR.
Collapse this transcript
Inserting data
00:00We are now going to begin working with the encrypted local store.
00:03Now the first task that we are going to take in is actually inserting data into the local store.
00:07And you might be asking yourself, why would I want to do this and that's a valid question.
00:10The encrypted local store is a little bit different in the way that it stores data, it gives you some advantages
00:16over storing sensitive data either in a file or in the database, because the truth is with a file,
00:21it's just a file saved on the computer, it can be opened by any other application.
00:25The same thing for the database. Even though it's a SQLite database, it's still a file on the hard drive.
00:30By default other applications whether they would be AIR applications or even other applications
00:35that support SQLite can easily go in and open your files and view the data.
00:38So when you are dealing with sensitive information, you either want to encrypt the file or you want to look
00:43at storing data within the encrypted local store.
00:46It gives you the capability to store small bits of data that you can then come and access at a later time.
00:51Now I know though this isn't for storing tons of data, there is a 10 MB limit per AIR application
00:56for the encrypted local store, so only to keep that in mind is you are planning your application.
01:00Now we are going to extend our application that we created previously that was the Contact Manager.
01:05We are going to add some login functionality so that not everyone can see our list of contacts.
01:10And we are going to be storing the user credentials inside of the encrypted local store.
01:13So let's go ahead and open our application.
01:17We are going to be in the Chapter 13 folder of the exercise files and we are going to start
01:21with ContactManager01 and then we will click Open.
01:26Now if you will notice, if you are really astute a few small things have changed.
01:30First of all, we have added a new movie clip that we will be working with called AddUser and it's a window that's going
01:36to pop up and give you, the administrator the ability to add a username and password
01:40and then add that user to the encrypted local store.
01:43Now to actually launch this window, we are going to have to add a new button to the Stage.
01:47And so we are just going to bring it a button and place it on the Components layers and we are just going
01:59to make this button the adduserButton and we are going to also change the label to AddUser.
02:09So now we actually can go in and begin to wire in our button.
02:13So if we go to Actions, we can go to Window and then Actions and view the Actions panel.
02:19And I want to show you one thing so that you don't think that I cheated.
02:22We have already added in the code for launching the window, we covered the Windowing API
02:26in pretty good detail a few chapters ago.
02:28So if you need this, code looks forward to you, you can go back and check it out.
02:32But basically we create a new window, we start with creating a new instance of the NativeWindowInitOptions
02:37and this is going to be a lightweight window with no System Chrome.
02:41And then we basically just positioned the Window in the center of our current window
02:45and then we also have configured some custom controls that I will show you in a second on that movie clip
02:50that will control the minimizing and closing of the window.
02:53And then we finally just activate the window.
02:57But we need to actually go ahead and add our event listener, so let's go ahead and scroll up to the section
03:01where we add our event listeners and we are going to go ahead
03:04and highlight the name before we head up there for launchAddUserWindow.
03:07And we will add in a new event listener, we will say addUserButton.addEventListener
03:18and then we will listen specifically for the MouseEvent.CLICK event.
03:25And then we will respond to it with the method that we highlighted launchAddUserWindow, you can go ahead
03:30and save our application and we can go back to the Stage and now we are going to double-click on the AddUser movie.
03:36The rest of the code that we are going to do for this video is going to be inside of this movie clip.
03:41Now you can see it's already got a couple of layers, it's got to Display layer,
03:44a Background layer and then an Actions layer.
03:46We are going to want to notice the instance name of this button, it's going to be addUser.
03:50So we are going to want to be sure that we reference that inside of our ActionScript.
03:54And the plan is that you the administrator will enter a username and password and then click AddUser
03:58and then it will store that value inside of the encrypted local store.
04:01So let's highlight the Actions layers and then go to Window and then Actions.
04:06You can see that we already have a few pieces of functionality.
04:08We have imported the flash.data.EncryptedLocalStore class as well as the flash.util.ByteArray class.
04:15In addition, we have already configured a button that will actually close the window.
04:18This way the user can actually close the window if they decide that they are done entering in users.
04:23But now we need to actually wire it together with the encrypted local store.
04:26So we will go ahead and add an event listener for our AddUser button.
04:29We will say addUser.addEventListener.
04:36We will listen for the MouseEvent.CLICK event and then we will respond to it by calling the onAddUser method.
04:44Now we will create a new method onAddUser and it will receive an event of type MouseEvent and it's not going
04:57to return anything so we can leave the return type as void.
04:59Now what we are going to want to do inside of here is take that username and password value
05:04and pass it in to the encrypted local store.
05:07The encrypted local store works by having a key that's in plain text, you can then store value with that key.
05:14When you go to retrieve it, you will give it the key and it will give you back the data as well.
05:17So in this case, we are going to use the username as the key and then we are going to store the binary data
05:22of the password inside of the encrypted local store.
05:24So first we need to create a new instance of the ByteArray class,
05:28we will just call it BA for ByteArray equals a new ByteArray.
05:34And then we are actually going to write the password into the ByteArray.
05:41Now if you remember from what we talked about earlier with ByteArrays, we can use the write UTFBytes method
05:47to actually write data into the ByteArray that's in the string format, so we will say ba.writeUTFBytes
05:55and it will pass in the value of the password.
06:01Now in this case, the two text inputs on the Stage are named username and password, so we will pass in password.text.
06:10So now we have actually created our ByteArray and populated it.
06:12Now we are actually ready to interact with the encrypted local store.
06:15Now the EncryptedLocalStore uses only static methods, so we don't ever have to create an instance
06:21of the EncryptedLocalStore class, but rather we just use the actual static instance of the class
06:26and we will say EncryptedLocalStore and then we will use the setItem method when we want
06:33to actually put a value into the EncryptedLocalStore.
06:37Then first, it asks you for the key or the name for this piece of data and so we are going to use the username
06:42for that value so we will say username.text and then we want to pass in the data which in this case will be a ByteArray.
06:49Now we want to do one more thing when the user hits AddUser, we want to go ahead and clear the username
06:55and password field, so that they will know that it is actually being entered into the encrypted local store.
06:59So we will say username.text equals and that will set it to a blank string and the same thing for password.
07:06So now just with that amount of code, we have actually created a custom window
07:12that will let us store data inside of encrypted local store.
07:15Let's test it out.
07:17We go to Control and then Test Movie.
07:20We see now that we have our AddUser button, we can click our button and see that it displays our window.
07:28We can now enter in the username, I will enter in David and then for the password,
07:32I will just enter in 12345 and then hit AddUser.
07:36And then we can see that the values disappear and it's actually been entered into our encrypted local store.
07:41We now can close this window and we are back to our application.
07:45We will go ahead and close our application as well.
07:47Now there is a couple other things to know about the encrypted local store,
07:51each application has its own encrypted local store.
07:53In addition, the encrypted local store that an application contains when it's being debugged
07:58with the AIR Debug Launcher is not going to be the same as when it's installed,
08:02so you can't guarantee that values you set during development will actually remain.
08:06There needs to be a way for you to enter those pieces of information after the application is installed.
08:10So the encrypted local store is a great way for storing data, but now we are actually going to need
08:14to use it to extract data to validate our users.
Collapse this transcript
Retrieving data
00:00Now that we can actually set data inside of the encrypted local store we are not going
00:04to want to be able to extract that data.
00:06There is a lot of used cases for this.
00:07In this case we are going to be using it as a log in for our contact manager application.
00:12But in addition you could use it if you are working with some type of an API that required a username
00:17and password you could store the credentials inside of the encrypted local store as opposed to actually having
00:21to store it in a file somewhere or inside of a database.
00:24This way you know that the data is secure because it uses the Nativeoperating system encryption algorithms
00:30and actually stores the data in such a way that it can only be accessed by your application.
00:34So now let's go ahead and open our file if we go to File and then Open we will then go to the ContactManager02 file
00:41that can be found in the Chapter 13 folder of the exercise files.
00:44Now you will notice that one thing has changed immediately.
00:48I have just added a login window there is really not a whole lot but we will go ahead and look and see what it contains.
00:53Inside of this movie clip we have got a username and a password text input
00:58and then we also have a status dynamic text input and then we have got a button called loginButton.
01:05Now this already has an Actions layer and this is what we are going to be doing most of our work so let's go ahead
01:09and go with the Actions layer and then just go to Window and then Actions.
01:12Now I have already set up some of the code.
01:14We have imported flash.data.EncryptedLocalStore and we have imported flash.utils.ByteArray.
01:20We also have already added an event listener for our loginButton and now we are actually ready
01:24to write the code for our onLogin function.
01:27So the first thing that we going to want to do is we are going to want to basically check the user name and password
01:35and see if they match what's in the encrypted local store.
01:37Now we are going to go ahead and create a new instance of the ByteArray class, we will say var ba of type Byte Array.
01:44Instead of creating a new ByteArray we are actually going to extract our data from the encrypted local store
01:51and that will return data in the byte array format.
01:53So we will say EncryptedLocalStore and then we are going to use the getItem method.
02:00We used the setItem before it and now we use the getItem.
02:04So now it's just going to want to know that one piece of information that was the key or the name.
02:09So in this case we can use username.text as that value.
02:14This will look in, see if any pieces of data have been stored under this key inside of the encrypted local store.
02:20If it can find it, it will return the binary data from the password into the ByteArray object.
02:26Now we are going to want to check and see if it returned anything.
02:29If it didn't return anything then we will know that that value was not stored inside the encrypted local store.
02:36That would mean that you have not yet entered a user name for that user and saved it in the encrypted local store.
02:40So if that's the case if there is not a ByteArray that is returned we know
02:46that we can just tell the user we will set the status.text value equal to User Not Found.
02:58But if it does return the ByteArray then we can begin the process of comparing the password that the user entered
03:06with a password that's actually in the encrypted local store.
03:09So we are going to say var returnedPassword and that's going to be a String. It's going to be equal to,
03:19and we are going to set it equal to our ByteArray, .readUTFBytes and then it's going to want
03:27to know how many bytes it's supposed to read and we will tell it to read all of them
03:31by using the bytesAvailable property of the ByteArray.
03:38So now this gives us the actual password that we'll store
03:41in the encrypted local store where we can actually do some comparison.
03:45So now we'll add another if statement and we'll say if password.text is equal to returnedPassword. If that's true then we know
04:00that the password is correct and what we will do is we'll just set this.visible = false
04:07and this is what will hide the login window but we can then say else and we'll set status.text = Incorrect Password.
04:17So if everything works we should have now implemented a login method for our contact application.
04:27So let's review the process.
04:28We first created a ByteArray and then we actually pulled an item out of the encrypted local store based
04:33on the username that the user entered on the screen.
04:36Next we actually extracted the password data from that byte array in string form and then we compared
04:42that with what the user entered in for the password field on our login screen.
04:46So now let's go ahead and save our application and we go to Control and Test Movie.
04:50We will see that we are presented with the window to enter in our login information and we can type in the password
04:58that we have created before for me was David and then for the password, 1, 2, 3, 4, 5.
05:03And then we hit Login, I will see that indeed it works.
05:07We are now able to login to the application.
05:09And again this is all done using comparison of usernames and passwords
05:13that are actually stored within the encrypted local store.
05:15Just a reminder if you are ever going to store sensitive information whether it be user credentials or information
05:20about the user that you don't want to have accessible to any other applications your best method for storing that data
05:25within AIR is going to be encrypted local store.
Collapse this transcript
14. Invoking Your Application
Using command-line arguments
00:00Another way that you can connect your AIR application with the operating system is being able to work
00:04with command line arguments that are passed into your application.
00:07This can just give you another level of communication between your application
00:11and other applications running on the user's computer.
00:14Now we are going to go ahead and open up the sample, we will go to File and then Open and then we are going to look
00:19in the Chapter 14 folder of the exercise files and we are going to look at Contact Manager01.
00:26This is the same application that we worked with in the previous chapter except that I have made one change.
00:30When we launched the application; the Login window is actually going to be set to not be visible.
00:35But we are going to go ahead and we are going to go to the Actions layer,
00:37we are going to go to Window and then Actions.
00:40Now the important thing to know is that every time an AIR application gets launched
00:45or it has new arguments passed to it, it receives an Invoke event.
00:50This event has several pieces of information; we are going to be focussing specifically
00:54on the Arguments property of this event for this video.
00:56So the first thing that we are going to do is we are going to need to add an event listener.
01:01Now when you want to listen for the Invoke event, you are actually going to add an event listener
01:05to the NativeApplication, so we will say NativeApplication.nativeApplication.addEventListener
01:13and we are going to listen for the InvokeEvent.INVOKE and then we are going
01:22to respond to this with the onInvoke method.
01:26So let's go ahead down in our event handler section, and we are going to add a new method, onInvoke.
01:42Now our goal for this is going to be- we are going to want to be able to launch the Add User window that we created
01:47in one of the previous tutorials just by passing in a command line argument.
01:51So the Invoke event is going to receive an event of type InvokeEvent.
01:58It's not going to return anything, so we can leave the return type equal to void.
02:02Now we are going to want to examine the arguments that are passed in.
02:07Now the arguments are passed in under the event.arguments property and it's actually passed in as an array.
02:13When you enter in arguments, it's going to consider each space to be at a delimiter.
02:16So if you enter the line 'David is cool', just as an example- you might think that, you might not-
02:23but it would actually divide that into three separate items within the array.
02:27So that will be passed in as three different arguments.
02:29So for this specific example, we are going to look
02:31and see if the user entered the phrase "add user" as the first argument.
02:36So we are going to say if event.arguments, and then we are going to look at the first argument which will be zero, equals
02:46and then we are going to look for addUser.
02:49Then we are going to want to call the method launchAddUserWindow.
03:01One other item just to notice, you will notice that the argument
03:05for the launchAddUserWindow method is actually configured so that it can take a MouseEvent or by default it is Null.
03:11So by launching it this way without actually passing it an event,
03:14we can still launch the window without throwing an error.
03:16So now we can actually save our application and now we are actually going to need to package it.
03:22In all honesty, working with command line arguments inside of Flash CS3 for AIR is a bit more difficult than dealing
03:28with them for people that develop AIR applications using Flex.
03:32In this case, the easiest way to test your application is to actually install the application
03:36and then pass command line arguments that way.
03:39You also can use the command line tools with ADL, the AIR Debug Launcher but that becomes a bit more difficult.
03:44So let's go ahead and go to Commands and then create AIR file.
03:48It's going to ask as for the certificate.
03:51We have the same one that we used previously and we will enter in the password of 12345,
03:56again you chose a better password, we will say OK and then it will take it a second
04:00and it will tell us if the AIR file has been created.
04:03So open back up, the Chapter 14 folder and you will see that here is our application, we are going to go ahead
04:08and double click it and that will start the process of installing it.
04:11We will say Install, and we will just install it in the Program files.
04:14It will say Continue.
04:16It will say Installation Complete.
04:19And here is our application, as I stated earlier, for this specific purpose,
04:23I went ahead and disabled the Login method, so we can go ahead and close this application.
04:29Now we are going to go ahead and go to the desktop.
04:33You can see that we now have an icon for our application and now we are going to open up the command line.
04:37If you are inside of Windows, you can go to the Start and then Run or in Vista, you can go to the Start Search.
04:42We are just going to type in "cmd" that will bring up the command line.
04:46If you are on Mac, you are actually going to go to the Terminal option to open up the Terminal.
04:51Now we are actually going to find where our application is installed, so in this case we are going
04:55to change directory C:ProgramFiles and then we are going to look for Contact Manager01.
05:03Now we can actually list all the files in the directory and we will see our executable file
05:08which is going to be contactmanager01.exe.
05:11Now if we just run this file without passing in any arguments, it will actually bring up our application
05:23and this is the way that the operating system actually launches your application.
05:26However, now if we go in and type contactmanager01.exe, and just a quick note for Mac users,
05:32your executable file will not be a .exe file ,but you should be able to find your contactmanager01.app
05:38and then you can launch it from there, besides that everything should be fairly similar.
05:42But now we are going to launch it and this time we are actually going to pass in 'addUser.'
05:46And when we pass this in, you will notice that the window pops up.
05:51Now the unique thing about this is, is this can actually give you a layer of compatibility
05:55between different programs on the same operating system.
05:58Right now, AIR does not have the power to open up other applications or to communicate with other applications,
06:04but through this other applications, it can actually pass information
06:07to AIR applications if you have configured it that way.
06:10So this is just another way to invoke your application and then pass in data and arguments
06:15that can be used within your application.
Collapse this transcript
Using AIR to open files
00:00In addition to receiving onInvoke events when applications are first launched as well
00:04as when they are sent command line arguments another time that they can receive arguments is
00:08when they are called on to actually open a file.
00:11In those cases they will receive an Invoke event in which the first argument will be the path
00:15of the file that they are called to open.
00:17To illustrate this I have created a basic text reader.
00:19This application should be able to actually display any text file within this area in the middle.
00:24However if I take the sample text file and drag it over the application and then drop it
00:29onto it the application launchers it is invoked but yet nothing happens and so we are going to actually have
00:34to configure our application for how to handle those kind of Invoke events so let's go ahead and open up Flash.
00:40We are going to go to File and then Open and then we are going to open TextReader01
00:46in the Chapter 14 folder of the exercise files.
00:48Now we are going to go to the Actions layer.
00:52We don't have anything in our Actions layer yet.
00:54You will notice that on the Stage the only thing we have is you have a text area with an instance name of text data
01:00so we can now lock that layer and we can go to Window and then Action that so we select the Actions layer.
01:05Now we are going to need to import a few classes to begin with.
01:08We are going to go ahead and import flash.desktop.*.
01:12We'll just import the whole package. That will have NativeApplication and some other ones that we'll be using.
01:16We are also going to want to import the entire flash.filesystem package
01:21as we will be working with FileStream, File and FileMode.
01:25So the first thing we are going to need to do is listen for the onInvoke event
01:30so we'll say NativeApplication.NativeApplication.addEventListener
01:37and we'll listen for InvokeEvent.INVOKE and when that happens we will call onInvoke.
01:44Now we are going to go ahead and create that method. Say function onInvoke and then we will pass in the InvokeEvent
01:53that the application receives and then we will return void.
01:58Now inside of here we are going to want to create a new instance of the File class
02:03from the argument that's actually passed into the application but first we want to ensure
02:08that there are actually being arguments passed in.
02:10If not we don't need to create a new instance of the File class and attempt to read it so we will say
02:15if event.arguments.length > 0 and we know that we actually have been passed in arguments.
02:25If not we can just let it pass through and have nothing happen
02:28so the first thing we will do is we will create a new instance of the File class, we call it f. It will be equal
02:33to a new file and then inside of the constructor of the file we are going to pass event.arguments 0.
02:40So we will pass the first event that's received. Because if your application is ever called
02:44to open a file the path will always be passed in as the first argument.
02:48Next we are going to need to create a new instance of the FileStream class.
02:52If you need more information on the FileStream class you can feel free to go back and look at the chapter
02:57that we did previously on the File system.
02:59We will now create a new FileStream then after that we are going to want to add an event listener.
03:07This event will actually fire when the FileStream has done reading a file and we will call it onComplete.
03:13After we added the event listener we are ready to actually open our file.
03:17So we will open an asynchronous connection.
03:21We will pass in the file and then we will tell it we wanted to be in FileMode.READ because in this case we are not going
03:26to be saving or writing over these files we just want to be able to view them.
03:30Now we can go ahead and create our onComplete method.
03:37It will receive an event of type Event.
03:39It's not going to return anything so we can leave the return type equal to void.
03:44Now the first thing we are going to do is actually grab the FileStream from the event.target property
03:49so we will say var fs of type FileStream = event.target as FileStream.
03:58Next after that we are actually going to extract the text from the file and then set that inside of our text area
04:07so we will say textData.text is going to be equal to FS, which is our FileStream, .readUTFBytes and then we are going
04:19to need to pass in the amount of bytes we wanted to read and in this case we wanted
04:22to read everything so we will say fs.bytesAvailable.
04:26Finally we can close the connection from our FileStream.
04:30Now we can go ahead and test our movie before we package it as an application.
04:37We will just go to Control and Test Movie and we will see that the application launches without
04:41and errors so we will close the application.
04:44We will now go to Commands and then create AIR file and then the AIR file will actually have been created
04:50so we can now go to the Chapter 14 folder and then in this case it be published as TextReader01.air.
04:56You can double click the file and it will walk you through the process of installing the application.
05:00Now we can actually go back to the desktop and we can see that we now have a TextReader01 option and that's going
05:11to be our new application so we can delete the old shortcut.
05:15We will drag our new one out and we should be able to drag our sample text file on top of the application.
05:20We will see that indeed it brings in the text file.
05:24It just has a few words in it.
05:26Now we can close our application and we can get something a little bit more intense and the Apache Conf File
05:32that we dealt within a previous video, even though it doesn't technically end in a .txt format, it's still a text file
05:38so we can drag that on top of the application as well, open it up and we can see it will open
05:43up the entire Apache Configuration File and we can view it inside of our application.
05:47Now this is very useful when you are working with applications
05:50that have specific file types that they normally deal with.
05:53Now that you know how to respond to the Invoke event to open a file you will now be able to create a custom file type
05:58that the operating system will associate with your application.
Collapse this transcript
Custom file types
00:00Now that you can open a file by Invoke event this opens up doors to what's possible with you inside of AIR.
00:06In addition to being able to just open files AIR gives you the capability to create custom file types
00:11for your application that the operating system will associate with your application so let's go ahead
00:16and open up the text reader that we had created previously.
00:19We go to File and then Open and we will see TextReader02 in the Chapter 14 folder
00:24of the exercise files and then we will click Open.
00:26We will now go under Commands and then AIR Application and Installer Settings.
00:31Now we are going to spend some time looking here under the Advanced Settings.
00:39You can see here at the top we have associated file types.
00:42Now if you want your application to work with a certain file type by default you are going to need
00:46to add it here inside of the Advanced Setting dialog box.
00:49We want to add a new file type so we will click plus and then we will give it a name.
00:54Now since we are talking about the power of the API in these circumstances we are just going to call it AIRAPI
01:00for the name of the file type so we will say AIRAPI.
01:03Now we have to give an extension, we are also going to make the extension airapi. We will just keep it lowercase
01:10and again here notice that we didn't put the period before the extension.
01:13We actually just used the later part.
01:15We can give it a description we will call it air api text file and then we will give it a content type. I happened
01:23to know that the mime type is a plain text file is going to be text/plain.
01:27Now after you have entered all of that information you can now setup an icon for your file type.
01:33Now if you click on the folder to the right of each listing it will open up a window where you can select an icon.
01:39Now this works exactly like the icons for the application.
01:42You request 4 different sizes.
01:43If you look in the File icon's folder in the Chapter 14 Exercise Files folder you will see
01:48that I have some icons that we can already use.
01:50Now I happen to know that this one is the 128 so we can select
01:53that for the 48 we will select the file that designates 48.
01:5732 will be the same and finally for 16.
02:01So now we have created our custom file type and now it will be attached to our AIR application.
02:07Now there is another thing that we need to actually set inside of our application so we will go back
02:13to the Actions layer and we will go to Window and then Actions and there is a command within NativeApplication.
02:20We are going to NativeApplication.setAsDefaultApplication and then we are going to want
02:32to tell it what extension we want to be the default application for.
02:36Now here is a word of warning on this.
02:37This doesn't work for just any file type you have to have included this file type inside
02:42of your application descriptor file in the AIR Installer Settings dialog box for it to actually work.
02:47For instance right here if I wanted to enter in PDF that wouldn't work because I hadn't already registered
02:52that inside of the application descriptor file but here I can say "AIRAPI" and we can close it
03:00and now the first time I launched my application it will actually set this application
03:03as the default for that file type.
03:05Now in this situation there technically isn't an AIRAPI file.
03:08It is really just a text file that we are calling an AIRAPI file so I am going
03:12to tactually go into Notepad and create a file.
03:15So we will open Notepad, I will just say this is an AIRAPI file and then we will save it we go to File
03:26and then Save and then we go here onto to the desktop.
03:32We want to be sure that we select all files and then we will save it as sample.airapi and then we will hit Save.
03:40So now we have saved our first AIR API file.
03:45Now we can actually export our application, we will first actually run it to be sure
03:49that we don't have any coding errors to see if it launches properly.
03:54We can now go to Commands, Create AIR File. It will tell us the AIR file has been created.
04:00We can go into the Chapter 14 folder, take TextReader02 and double click it to begin the installation process.
04:06We will say yes we want to install and we will leave all the other settings the same
04:10and there let's actually launch our TextReader02 file.
04:15Now if we go back to the desktop we can already see that our sample AIR API file has been registered with our icon
04:24so that's one level of customization that you already have available to you but in addition now
04:28if we double click this file because our application is registered as a default handler
04:32for that file it will automatically open it up and you can automatically read the data that's within the file
04:38so setting your application to be the default handler for this file enables you
04:41to just double click the file and then open it.
04:43So this is another powerful feature within AIR that gives you the ability to have your own file types that can be used
04:48with your application and again this doesn't mean you have to go out and create some new way of storing data
04:53but you can use something like a customize XML file to store preferences for your application or to store data
04:58for your application so that the user can simply double click the file and install it.
Collapse this transcript
Launching an application at startup
00:00Another way that you can invoke your application is by having your application configured to start automatically when
00:05the operating system starts up.
00:07It's actually very easy to set this within your file.
00:10So we are going to go to File
00:11and then Open
00:13and then we are going to open Text Reader03 in the Chapter 14 folder of the exercise files.
00:19We are going to go to the Actions layer
00:21and then we will go to Window
00:23and then Actions.
00:24The way that we actually tell the application to start automatically at log in is to set a property on the instance of
00:30NativeApplication.
00:31So if we want an application to start at log in we can say
00:35NativeApplication.nativeApplication
00:39.startAt
00:42Login = true. Simply by setting this value and then having your application run, it will then be configured to start when the
00:50operating system launches.
00:52However, if you actually set the value to true and don't run your application then it won't be registered. It actually
00:57has to run and see that value set.
00:59In addition, if your application is currently configured to run at log in and you want to actually turn that off, you can actually
01:05set startAtLogin = false.
01:09And this can be very handy for applications that users always want to have on their desktop.
01:13For instance, maybe some type of an instant messaging application or some type of an application that allows them to
01:18keep track of what's going on with their friends or other people around them,
01:21and so this can be a very powerful tool.
01:24However, you certainly never want to set this value without giving the user some type of customization to turn it on or off.
01:30And this is yet another way that you can invoke your application.
Collapse this transcript
15. Updating AIR Applications
Understanding the updater
00:00If you have created your first amazing AIR application and now you have sent it all to your friends and then all
00:05of a sudden you realize there is a big coding problem inside of your application, you are going to want to find a way
00:09to officially get an update out to each of those users.
00:12If you are working in a big company and maybe somebody discovers a security flaw in your application
00:16and maybe the problem becomes even more urgent.
00:19Included with AIR is the Updater capability, with this you can actually, basically anywhere that you would
00:25like configure your application to check for updates
00:27and then update itself whenever it finds that there is a new update available.
00:31The great thing about this is that it frees the developer
00:33up to include this functionality in any way that they would like.
00:36Now I have got a sample application right here that will allow us to test the Updater functionality.
00:41This way you can see what part of the process you the developer can actually script and what part
00:46of the process is automatically controlled by AIR.
00:49We currently have Version 1 of this application, I am going to highlight Version 2 and say that we want to update.
00:54First, it is going to download the file and save it here on the local computer then if everything works properly,
01:00you will then tell the application to begin the update process by telling it that you are currently
01:04on Version 1 and want to go to Version 2.
01:06So you can see that at the point after I click the Update button, the application started downloading the file,
01:11at that point AIR took over and actually handled the rest of the update process.
01:15After AIR was done updating the file, the application launched again
01:19and we can see that it has been updated to Version 2.
01:21So we are going to begin integrating this functionality into one of our applications.
01:25So what I have done is I have created a folder under XAMPP, under htdocs and under a new directory, update,
01:34where I have an updated AIR file as well as an XML file.
01:37So I am going to go ahead and open up the XML file.
01:40And just so you know, both of these files are also available in the Chapter 15 folder of the exercise files.
01:46Inside of here is a very simple XML file, it defines two settings for an update, the version and the location
01:54and those are the two items that you will have to have when you go to update your application.
01:57So we will go ahead and close the XML file.
02:00The first thing we are going to want to do is inside of one of our AIR applications is we wanted to be able to go
02:05and check this XML file to see if there is a newer version of the application
02:08than the version that they currently have installed.
02:10So we are going to go ahead now and go to Flash and begin developing this in our application.
02:15Now once we are in Flash, we are going to go to File and then Open and then we are going to open Text Reader01
02:23in the Chapter 15 folder of the exercise files.
02:25We are going to go to the Actions layer and then we are going to go to Window and then Actions.
02:32Now we are going to first create a new function called checkForUpdate.
02:43Now it's not going to take any parameters and we can set the return type equal to void.
02:46And what we are going to do inside of this method is we are just kind of tell the application to go
02:51and look at that XML file and bring the data back.
02:53So we are going to create a new first URLRequest and we are going to point it to the XML file, which in this case,
03:05because I have installed it with XAMPP, it's going to be under localhost/update/update.xml.
03:13Now we are going to create a new instance of the URLLoader, so we will say var loader of type URLLoader.
03:21It is going to be equal to a new URLLoader.
03:25Then we will add an event listener to listen for when the file has been completely downloaded,
03:30we will say loader.addEventListener and will listen for the Event.COMPLETE event.
03:38And now we are going to respond with the onXMLLoadComplete method.
03:53So now for the last step in this method, we are actually going to tell the loader to begin loading the XML file.
04:00So now we can copy this onXMLLoadComplete name for the next method.
04:04And now we are going to actually complete the method.
04:10So we paste in onXMLLoadComplete, now we will receive an event of type event,
04:16but it won't return anything so we can set that equal to void.
04:20Now inside of this method, the first thing we are going to do is we are going
04:22to extract the URLLoader from the event.target.
04:25So we will say var loader of type URLLoader is going to be equal to event.target as URLLoader.
04:35Now once we have that, we are going to go ahead and extract the XML data from the loader, so will say var xmlData
04:44of type XML is going to be equal to. And then we wanted to create a new XML object from the text data
04:49that was downloaded, so we will say XML and then we will pass in loader.data.
04:54Now we are going to want to extract those 2 pieces of data that were contained in the XML file.
05:01So we will first say var updateVersion and that's going to be a String. It's going to be equal to we will say xmlData
05:13and then it actually was inside of a tag called Update, and we are going to want the first tag and then we are going
05:20to go and find the attribute that was, Version.
05:25So by using that code, we can obtain the application version of the update, and then we will create one more variable,
05:30UpdateFile, and that can be found by looking at xmlData.update
05:41and then also finding the first value and then looking for location.
05:47Now we are going to actually place a trace statement at the end and it will say "Check to see if it is accurate."
05:54So this way we actually can know that when we need to go into our debugger,
05:59I am going to put a breakpoint right there at line 35 and we are going to go ahead
06:03and call this checkForUpdate method as soon as the application launches.
06:07So now we can save it.
06:11We will check over our code and make sure that everything looks good and then we will go to Debug, Debug Movie.
06:16First it tells us we have an incorrect number of arguments, we look at line 28 and indeed we forgot
06:23to pass the URLRequest into the Loader.load method.
06:26So we will add that and now we can hit Save and go to Debug, Debug Movie.
06:35We can see now that it stopped at our breakpoint,
06:38we can see that it's already grabbed the XML data, we can see the entire XML data here.
06:42Well we can see that our value for update version has been set to 2.0, which was the same value that was contained
06:48in the XML file and the UpdateFile variable has been set to localhost/update/update.air which also is correct.
06:56So now that we have got this data, we can now interact with the update functionality included with the Adobe AIR.
Collapse this transcript
Retrieving an update file
00:00In continuing to work with the update functionality within AIR we are going to learn how to actually take a file
00:05that exists somewhere else we are going to download it and we are going
00:08to save it as our file on our local file system.
00:10Now this is important because with AIR with the updater you can't just say go update my application at this URL
00:16that wouldn't be a good idea for a lot of different reasons.
00:19But what you actually have to do is you have to take that file from the URL and save it on your local computer
00:23and then you can actually pass that into the updater.update function along with the new version of the application.
00:29So to accomplish this we are going to need to look at a few other properties within AIR and we are also going to need
00:33to utilize some of the file system methods that we learned previously.
00:36So let's go to File and then Open we will now open TextReader02 in the Chapter 15 folder of the exercise files
00:47and now we are going to actually go to the Actions layer and we will go to Window and then Actions
00:55and we can now actually begin the process of downloading the update file.
00:59Now we are going to change a few things around within the code that we just wrote to check for the update.
01:04First we are going to actually make the location of the update file an actual property
01:09that will be available throughout the whole application.
01:11So we will create a new section in our code here for Properties.
01:19And we will say var updateURL is String, we won't set its value yet.
01:25We will also make the updateVersion a property and it also would be a String.
01:33We can go down to our onXMLLoadComplete method and we will change the value for these two
01:39to just be updateVersion, we don't need that, and then updateURL.
01:47So those values will now be set after we would run the checkForUpdate method
01:53and then the onXMLLoadComplete method response.
01:57Now at this point we are going to go ahead and assume that we are going to be downloading the update.
02:01We will actually do some calculating in the next video to determine if we need to download the update and then what
02:05to do with it after we actually finish that.
02:07But we are going to go ahead and have a function called startUpdate that will actually begin downloading the file.
02:14So now the first thing that we are going to need to do is we are going to create a new URLRequest object
02:23with the URL inside of it so we will say var req is a URLRequest= new URLRequest and then it is willing
02:33to pass in the URL which is just updateURL.
02:36Now after we have actually created that we are going to need to create a new instance of the URLStream class.
02:44Now at this point we are going to also create two new properties that will help us in the update process.
02:48So just as we created updateVersion and updateURL we can scroll back
02:52up to the top then we can actually add var stream which should be of type URLStream.
03:01We will also create var fileData which should be of type ByteArray and now we can go down
03:10and continue working with our startUpdate method.
03:13So first we will say stream is equal to a new URLStream.
03:17And then next after that we will say fileData is going to be equal to a new ByteArray.
03:25Now we are going to need to add an event listener so that we know
03:30when this URLStream has actually finished downloading the file so we will say stream.addEventListener we will listen
03:40for the Event.COMPLETE event with the onDownloadComplete method.
03:45Now after we have added the event listener for the stream we actually can begin the process of downloading the file
03:55so we will say stream.load and then we will actually pass in the URLRequest req.
04:01Now when you create our onDownloadComplete method so we will go down to create one more new method
04:07and say function onDownloadComplete within this method or receive an event that will be of type Event
04:15and we can just set the return type equal to void.
04:20Now we are actually going to need to take the data from the URLStream and pass it into our Byte Array,
04:25so first we will say stream.readBytes and then we will want to tell it first where we wanted
04:35to read it into and so we will say file data.
04:37Next we wanted to tell where we wanted to start reading the bytes from and we will just say 0
04:43and then they will ask us how much do you wanted to read and we will say that we wanted
04:47to read all of it by saying stream.bytesAvailable.
04:49Next we are going to want to actually create a new file reference on the file system so we will say var updateFile
04:58of type File is equal to File.applicationStorageDirectory.resolvePath
05:09and it will actually pass in the name update.air.
05:15So once it actually creates this file object it will create a file
05:19in the Application Storage Directory named update.air.
05:22Now, we will need to create a new FileStream object as we have done in the past
05:25to actually pass these bytes into the file.
05:27So, we will say var fs of type FileStream, this is going to be equal to a new FileStream.
05:34Now, we will need to create an event listener we will say fs.addEventListner.
05:40We want to listen specifically for the Event.CLOSE event and this will tell us
05:45when the FileStream has actually completed writing the bytes into the file
05:48and then we will actually call the performUpdate method.
05:51Now, we need to actually open a connection to the file, so we will say fs.openAsync and then we will want
06:00to actually pass in the reference to the file, which will be updateFile,
06:05and then it will tell it what mode it will be FileMode.WRITE because we actually be writing data to the file.
06:16Finally, we will use the fs.writeBytes to actually write data into the file.
06:22We will actually tell it to put the fileData and we will start at 0 and we will actually go to fs.bytesAvailable.
06:30Now, finally once it's actually done right in that data, we can just call fs.close and because we are using async here,
06:41we can actually wait until it's done before we actually perform any additional options.
06:45So, now let's actually create the next method which will be performUpdate, we are not going to implement this method
06:50in this video, but we are going to actually see that we can actually download the file.
06:54So, we will actually say performUpdate, it will receive an event of type Event,
07:00we will set the return type equal to void.
07:05So, now we will go ahead and put a breakpoint at line 64 here and I will actually put
07:09in a Trace statement here, so we know. 'Testing download.'
07:13And now just so that we can actually see how things work instead of actually storing this file
07:22on the Application Storage Directory, we will temporarily store it on the desktop directory.
07:27So, now we can save our application and we actually can go to Debug and Debug Movie.
07:33Actually, before we debug our movie we need to do one more thing, at the end of the onXMLLoadComplete method,
07:40we are going to go ahead and call the startUpdate method.
07:44This way these are actually chained together, so as soon as we download the information about the XML file,
07:48it will actually start downloading the file.
07:49So, now let's go to debug and Debug Movie.
07:52It will first tell us that we actually have an undefined property and it seems
07:57as though I have just actually entered in, here we go, actually entered in the wrong name for the property.
08:02We can now save it and now we can go to Debug and Debug Movie and now once we debug our movie,
08:12we will see that there is one small little problem.
08:14We actually have one small problem we will need to fix in our onDownloadComplete method.
08:17So, let's go ahead and end our debug session. We close the Compiler Errors window and the problem is,
08:22is that here we have actually used the fileStream.bytesAvailable, but that's not what we want to do
08:27because we are not going to want to use the fileStream.bytesAvailable property,
08:30instead we are going to want to take the binary data that we are actually writing in and we are going to want to use
08:35that as determining how many bytes we want to read in.
08:38So, we will actually say, fileData.bytesAvailable.
08:47Now, if we debug our application, we will now see that it stops at our breakpoint at performing update
08:59and if we end our debug session and actually go to the desktop,
09:02we can see that indeed our AIR file has been downloaded.
09:04We can right click to see the properties and see that we have actually downloaded roughly 53.5K and actually saved it
09:11to the desktop using the URLStream, the FileStream and the ByteArray classes.
Collapse this transcript
Performing an update
00:00So in this lesson, we are actually going to work specifically
00:03with the Updater.update method to actually perform the AIR update.
00:07We are also going to learn how to look and find the application version
00:10of the current application that we are running.
00:11We are going to use all that together to determine when we need to download an update
00:15and then we will actually finish the update by performing it and actually having AIR install our new version.
00:20So, let's go ahead and open up the file we will be working with, which is going to be Text Reader03
00:26in the Chapter 15 folder of the exercise files.
00:29Now, well be sure that the Actions layer is selected and we will go to Window and then Actions.
00:36We will scroll down to where we actually had the PerformUpdate method, because we just had a trace statement
00:45in here, so we could test and see that the application had properly downloaded.
00:49However, in this place, we are actually going to perform the application update, so to do this we are going
00:54to create a new instance of a new class, we haven't yet dealt within AIR
00:57and that's going to be the actual updater class.
00:59So we will say var updater:Updater = new Updater.
01:08Now, at this point all we actually have to do is called the Updater.update method and then we will need to pass
01:18in two things, first is going to be the update file.
01:21Now, we happen to know that our file, we actually already defined here as updateFile. Now,
01:27to make this easier so that we can access this from this method as well,
01:31we are actually going to convert updateFile into a property.
01:34We will delete the var keyword before and we will scroll up and we will say var updateFile:File.
01:43We actually set the value in the onDownloadComplete method and now we actually use that here, we will say updateFile.
01:57And then the only thing we have left to do is to actually pass in the update version.
02:08So, now we actually have performed the update from beginning to end just with the code we have here.
02:14However, there is a problem, we are not going to want
02:16to download the update file every single time we launch our application.
02:20There is going to be times when we have the most current version.
02:23So what we need to do now is we need to actually develop a method that will tell us if we even need to update,
02:29it will actually look at the XML file and it will compare the version from the XML file to the version
02:34that actually is available on our local system.
02:37So, let's actually scroll up to the onXMLLoadComplete method.
02:43Directly, below here we are going to create a new method called checkStatus that will check the status
02:48of our application and see if we need to download a new one.
02:51This will be a method that does not receive any events and it won't return anything,
02:56so we will set the return type equal to void.
02:58The first thing we will need to do is determine the current version of our application, this actually is not available
03:04as a property of the NativeApplication class as you might thing.
03:07However, inside of the NativeApplication class there is your application descriptor file
03:12that is actually brought in as XML data.
03:14So, we actually can access that by saying var, we will create a variable called AppXML it will be of type XML
03:21and we will set that equal to NativeApplication.nativeApplication.applicationDescriptor.
03:31And as I stated earlier, that's your actual ApplicationDescriptor file in XML form that was created
03:39with your application that was the file that we edited with the AIR Application
03:43and Installer Settings inside of Flash CS3.
03:45Now, we are going to actually need to look into this XML file.
03:49However, this XML file uses something called namespaces, so to ensure that we can actually view the right tags,
03:55we are just going to need to be sure that we are looking at the default namespace.
03:58So, we can do that by saying var air, we are going to call this a Namespace,
04:03it's going to be equal to appXML.namespaceDeclarations and then we are just going to call the method and it's going
04:13to return an array and we are just going to say that we want the first of the namespace declarations.
04:18Now, if you are not familiar with XML namespaces, don't worry about it, right here we are basically just saying,
04:23we just want to use whatever is default for this document
04:26and now we can easily determine what our application version is by saying appXML, which is the name of our XML object
04:34that we got earlier and then saying .air, which says what namespace we are going to use
04:39and then we actually can just use two colons and then say version
04:42and this will actually return the version of our application.
04:45Now, just to test this, we will actually set this equal to another variable, we will say var version,
04:51which will be a String, will be equal to that and then we will actually add a trace statement below
04:56and we will say "Check if it's accurate," just to remind us what we are actually debugging for.
05:04So now we can actually put a breakpoint here and now on the XMLLoadComplete instead of calling startUpdate,
05:11we are just going to call checkStatus, then we can actually save our application.
05:19And now that we have this breakpoint set, we will go and actually check and see what our application version is.
05:24Currently, it's version 1.0, so we will click OK.
05:32Now, we actually can test by going at Debug and Debug Movie.
05:41And here we can see that indeed version was set as 1.0,
05:44so we are being able to properly read in our application version.
05:48So, now we are going to want to put one extra item on the Stage of our application.
05:51We are going to put a button, we are going to go to the Components window and we are going to unlock Layer 2 here
05:58and then we are going to drag a button onto the Stage, but first we need to be sure that we have Layer 2 selected.
06:03Then we will just drag the button onto the Stage and then we will actually give this an instance name of updateButton
06:11and then we will actually go under Parameters, we will change the label to say Update
06:18and we will set the enable property once we get into the ActionScript to false, because we don't want this
06:23to be an option that's normally there, we want this to be a button that's only enabled when we actually need to update.
06:28So, we will now relock Layer 2, we will go to the Actions layer, we will go to the Window and then go to Actions.
06:36So, up where we declare our properties, we are also going to say updateButton.Enabled is going to be equal to false.
06:45Now, we are going to back down to our checkStatus method and we are going to say if version does not equal update version
07:01in other words, if the version that's on the update side does not equal our current version then we are going
07:06to actually enable the Update button.
07:14In addition, we are going to use the Update button to actually trigger the startUpdate Method.
07:19So it will now receive an event, MouseEvent and then we just need to actually go and add in our event handler up above.
07:27We will say updateButton.addEventListener and we will actually listen for the MouseEvent.CLICK event
07:39and then we will actually call the method below, which is StartUpdate
07:47and that will actually start the download process.
07:57And now we can click Save.
07:58So now let's actually test the application and we will see what happens.
08:03We will go to Control, Test Movie.
08:06We can see now that the button was not enabled and now it is.
08:17If I went to the actual XML file, under XAMPP and then under htdocs and then went under Update
08:26and I actually change the value from 2.0 to 1.0 and then save the XML file
08:33and then I went back and tested the movie again.
08:36You can see that now it would be disabled and it would stay disabled, because it's determined
08:42that we actually have the most current version of the application.
08:45Now, the last thing that we are going to do before we actually update our application is we are actually going
08:52to package a version of our application as version 2.0 and put it on the server, because one of the things
08:56that you have to understand is AIR actually has some limits on how the update functionality can be enabled.
09:01It wants to be sure that both of the applications have the same Application ID. Let's go to Commands, AIR Application
09:07and Installer Settings and let's make this version 2.0.
09:12Now, even though most of the times you will see numbers for that value, the application actually reads them as strings,
09:17so for instance Version 3 doesn't necessarily mean that it's newer than version 2, you can choose a naming scheme
09:23for your application versions that will be whatever you would like and then just be sure
09:26that you are consistent in the way that you implement it.
09:28So now we have created our AIR file, which can be found under the exercise files.
09:32And now that the file is being packaged, we will actually take the file and we will copy it
09:48into the same directory with our XML file.
09:52We will actually delete the old update.air file and we will rename this one Update.
09:58Now we can close that window and we will go back in, we will now change our current application version to 1.0
10:09and we will say OK and that will create another packaged version of our AIR application and it will say
10:18that the AIR file has been created and now we will actually install our application.
10:23We will say Install.
10:28Now we will actually go back to our XML file, we will change the version back to 2.0, which is the version of the file
10:38that we actually uploaded to this directory
10:41and then we re-launch our application, we will actually go to the desktop.
10:44We will re-launch Text Reader03.
10:47We will now see that the Update button is enabled.
10:50If we press the button we will actually begin the update process and AIR will actually carry us
10:55through the rest of the installation and there we go.
10:59Now we have the most up-to-date version, version 2.0.
11:01You should be very careful, anytime you distribute an application to include some form of update
11:06with the application, if you choose not to, you could run into the possibility that many of the users
11:10of that application are going to have out-to-date versions, they might have security flaws or they might just not have
11:15that kind of functionality that you want in your application and because of that, once you actually put it
11:20out without an updater, there is no way to bring it back, it's already out there.
11:23So, if you take some time and implement the Update functionality in your application then you can ensure
11:28that the users are going to have the best experience that you can offer through your application.
Collapse this transcript
16. Using Advanced Techniques
Closing an application gracefully
00:00There will be times when you create applications
00:02that you will want to keep windows for the entire applications from closing until you have had a chance to actually do some cleaning up.
00:08In these situations you can listen to events that are dispatched by both NativeWindow and NativeApplication to perform
00:14some last minute cleanup
00:15to save things like preferences or to save the application state before the application actually closes.
00:20So we are going to illustrate this with the Contact Manager, so let's go ahead and open the file.
00:24We are going to go to File and then Open
00:26and then we are going to open ContactManager01 in the Chapter 16 folder of the exercise files.
00:32We are going to go ahead and test the movie,
00:36and you will see here that we have our window that's popped up.
00:39Now what we are going to look at specifically is we are going to click the Add User button
00:42and that will bring the Add User window to the front.
00:45Now,
00:46as we have discussed before we can enter in a username and a password that will be added to the encrypted local store,
00:51such as David.
00:52And then 12345 if we wanted to,
00:55and then we can press
00:57Add User and it would actually save the user.
00:59However, in this case, what if somebody actually entered in the username and password and then chose to close the window.
01:04You can handle that in a lot of different ways you can prompt the user for an alert.
01:07But there is a way to illustrate this functionality, if there is actually a value still present in the username and password when
01:13the user goes to click the field,
01:14it will actually store that value inside of the encrypted local store.
01:18So let's go ahead and close the application.
01:20We are going to go to the Add User movie clip,
01:23and we are going to open up Actions.
01:26So it will highlight the Actions layer and then go to Window
01:28and then Actions.
01:30Now there are a couple of important things to know about the way the windows work.
01:33First,
01:34when a window is closing, it always dispatches a closing event, so other objects within the application can actually
01:40listen for that event.
01:41You can also call the method preventDefault to prevent the window from actually closing to give you an opportunity to
01:46perform some actions.
01:48Now generally most of the cleanup should always be done by the window itself.
01:52So if the window listened for its own close event then it can perform actions before it actually closes.
01:57And one additional note on this.
01:58When you're working, when you're doing this type of clean up operations right before a window or application is getting ready to close,
02:04you can only use synchronous methods.
02:07So if you're doing anything with the file system or anything with the database you're going to have to use synchronous programming
02:12because there's no way for sure here that we can know
02:14that our asynchronous methods would actually dispatch their events before the application actually closed. So let's go
02:19ahead and listen for the closing event here within this window.
02:22We will say stage.NativeWindow,
02:25which is the way that we get an access to the NativeWindow inside of a movie clip,
02:29then we will say addEventListener,
02:31it will listen specifically for the Event.CLOSING event.
02:35And then,
02:36we will actually call the onWindowClosing method.
02:40Now don't get just confused with the actual Close event.
02:43The Close event is dispatched when the window is already closed.
02:46So if you are listening for that event in hopes of doing some cleanup, you are probably going to be out of luck
02:50but the closing event is dispatched before the Close event.
02:54So now we are going to create a method, onWindowClosing,
03:03and it'll receive an event
03:05of type event.
03:08And it's not going to return anything so we can leave the return type as void.
03:12Now here inside of this method.
03:13As I stated we were going to want to actually execute the onAddUser method
03:17and you can see I have already actually made the default value for this event equal to null
03:22so that it can be called either as an event handler or just as a regular method.
03:26So in this case we are going to check and see if username
03:30.text
03:31.length
03:32and of course this will return "true" if the length here is greater than 0,
03:35and if password
03:39.text
03:40.length,
03:42which also would do the same.
03:44So basically we want to see, did the user enter something into both of those?
03:48If they did, then we are going to go ahead and call the onAddUser method.
03:54By doing this we can actually do some last minute cleanup before the window closes.
03:58So even if they click the Close button we can still be sure that those items get put into the local store.
04:03In addition, windows are not the only things that dispatch events.
04:07The NativeApplication actually dispatches an event as well.
04:10So if we were to go back over to our root movie,
04:14and go to Window and then Actions,
04:17we then can go to our event handler section and we can actually add an Event Listener to the NativeApplication. We can say
04:23NativeApplication.
04:25nativeApplication.
04:27addEventListener
04:30and we are going to listen here in this case for the Event.EXITING.
04:34This works in a very similar way to what it does for the window and that the exiting is actually dispatched before the actual exit is.
04:41So in this case we can listen for the onApplicationExit method,
04:45and perform any clean up that needed to be performed. In this specific instance,
04:49we don't have anything that needs to be performed at this time. We can consider possibly syncing the data from the server
04:55and actually putting in the database before the application closed
04:57but there would be a couple of problems with that.
04:59First of all we can only use synchronous methods
05:02and we would actually have to do about a 1000 queries. Now this can create a problem for the user if they're having to wait for the
05:07application to close during that time, they would be much more likely here to actually find a manual way of closing your application
05:12before it's actually completed, and so that can be a problem as well.
05:15You generally want to keep your items that you do in cleanup before a window or an application closes
05:20as short as possible so as to not degrade the experience of the end user.
Collapse this transcript
Supporting multiple monitors
00:00There are going to come times as you develop AIR applications, where you are going to want to know more
00:04about the monitors that the user is using to view your application.
00:07You might want to know this so that you can know where to best position your window on the screen.
00:11You might want to know this, so that you know which screen is the main screen and you might also want
00:14to know some other information, such as the actual bounds of the monitors themselves.
00:19So we can find out a lot of these things by using the Screen class inside of AIR.
00:23So if we go to File and then Open, we are going to open the Screen Analyzer01 file
00:29in the Chapter 16 folder of the exercise files.
00:32We are now going to go to the Actions layer and first we will actually take a look at the Stage.
00:37We just have basically a skin of an application with one big text area in the middle and then a button
00:41with an instance name Analyze button, but it's actually going to be used as the trigger for analyzing the monitors.
00:49So now if we go back under Actions and go to Window and then Actions,
00:54we actually begin now to analyze the monitor structure of the current computer.
00:58Now again if you run this application, you will probably get different results from me.
01:02We probably have different screen sizes or you might have multiple monitors,
01:05but what this will do is this will allow you to get the information you need as a developer to know enough
01:09about the user screens to where again you can fully take advantage of positioning for your application.
01:13So the first thing that we are going to do is we are going to utilize a property of the Screen class called Screens
01:20that contains an array of each of the different screen references.
01:23So we actually can look through that, but first we are actually going to add an iterator to say i, it's a uint,
01:30will be equal to 1 and then we will say for each var screen of type Screen in Screen.screens.
01:43Now we actually can use this to get some information about each of the screens.
01:47Each of the instances of a Screen class contains information on the bounds
01:51which includes the x and y as well as the width and height.
01:54That also contains other pieces of information such as the color depth.
01:57So let's try to get as much information as we can about each monitor.
02:03We will start off by declaring what monitor it is.
02:05We will say monitor and then will add in the iterator that we created earlier, then outputText.text += and then we want
02:15to find out the width and we can pass in screen.bounds.width.
02:23We actually can copy that line and do the same thing again for the height, screen.bounds.height.
02:33Finally, we are going to just copy down some of the information about the color depth
02:38so we actually can copy this line one more time and we will say color depth and then we want
02:45to actually have a reference to screen.colorDepth.
02:48Now the last thing that we will do is to add a little bit of space at the end of each of these.
02:52We will just add a new line indicator and then we can paste that to the end of each.
03:01And we will actually add a couple of new line indicators at the end as well
03:04so we can separate the information about our multiple monitor.
03:09Now let's see what we found out about our screens, so we can go ahead to save our application
03:14and we can go to Control and then Test Movie.
03:17Oops and it's going to tell us we actually have an undefined property here of output text.
03:21If we go back to the Stage, we highlight the text of output area so we will just change this to output text
03:31and then we will go to Control and Test Movie.
03:37Now here we can actually press the Analyze button and we will get back information about the monitor.
03:42Now I currently only have one monitor setup, but if you have multiple monitors you will see information come
03:46through about each of these.
03:48So we can see here that this is monitor 1 with a width of 10x24 and a height of 768 and a color depth of 32,
03:54but these aren't the only properties that you can use with your AIR application.
03:58In addition, there is also the screen.mainscreen which is a reference to the operating system designated main screen.
04:05So you can be sure if you have positioned your application on the main screen that is actually
04:09in the prime place for the user to see it.
04:11In addition you also can measure the entire bounds of all of the monitors together to get an idea of how
04:16to position elements that might need to flow horizontally or vertically depending on the user's monitor alignment.
Collapse this transcript
17. Distributing AIR Applications
Installing a local web server
00:01When working with the samples for distributing your AIR application it is going to be beneficial
00:05to install a development web server on your local computer.
00:08Some of the samples won't actually run properly if you are just running them directly from your hard drive.
00:12Now if you are using Windows, one of the best solutions is to use XAMPP.
00:17And you actually can find that at apachefriends.org/en/xampp.html.
00:25If you are on Mac probably the best option available is MAMP and that can be found at mamp.info/en/mamp.html.
00:35We will go ahead and go back to XAMPP for the moment; we will scroll down and find XAMPP for Windows.
00:44We will then click on the XAMPP1.6.6a and it will bring us to an option
00:51where we can select from different types of files.
00:53In this case, we just want the easiest installer, so we will go ahead and just select the Installer method.
00:58It will take you to another page where it will begin the download process and depending
01:02on which browser you are using it might prompt you to confirm that you want to download the file.
01:06We are now actually going to go ahead and run the application.
01:09Now it will confirm that we want to run the file and we will go ahead and click Run and if you see any warnings related
01:15to UAC on Vista you can just go ahead and click OK.
01:19Now we will have the option to walk through the setup,
01:21we can pretty much accept the default settings for almost everything.
01:24The one thing that you are going to want to really pay attention to is that XAMPP
01:28by default installs everything at the root of the C: drive.
01:31That's fine but we just need to remember where that location is because we will be using it later.
01:35Next, we will have it install a desktop icon, also included in the Start menu
01:40and we also want to run Apache and MySQL as the service.
01:46Once the installation has been completed, you can click Finish.
01:53As it installs Apache and MySQL as services you will see a few other windows pop up.
01:58This is nothing to be alarmed about.
02:00It will finally tell you that the server's installation has been finished;
02:03it also says that you can use the XAMPP control panel to manage services.
02:06We will click OK, and we will say that we want to start the Control panel now.
02:12So here is the Control panel and we have it available in the system tray when we need it.
02:17Now that we have installed the local development web server, we will begin to look at different methods
02:21for distributing our AIR applications the way we have built, configured and packaged inside of Flash CS3.
Collapse this transcript
Using a download link
00:00Now that you have completed your AIR application and you have got your .air file and you are ready to distribute it
00:05to the world, one of your first choices might be to take that .air file
00:10and then place it somewhere, like on a web server.
00:12You might have some web hosting space or you might even have a server yourself that you can place it on
00:16and then you figure that you can just take the link and then hand it out to everybody
00:20and then they can receive your application that way.
00:22Well that's not always the best idea and I am going to demonstrate why.
00:26First, be sure that you actually have XAMPP installed because we are going to be using some samples from it.
00:30Now I am going to open the htdocs directory for XAMPP that can be found under C:XAMPP and then htdocs.
00:40This is the root for the web server.
00:42Now I have already put in here a download.html file and you can see here that it just has one single tag
00:49that allows the user to download the browser application and it references the browser.air file.
00:55In addition, you can see that I have copied the browser.air file into this directory.
01:01Now we can actually visit this directory by just going to localhost/download.html.
01:06Now if we click on this link, what is going to happen is that right now, Windows believes that this is a zip file,
01:13so if the user clicks open, it is basically going to take your .air file and unpackage everything.
01:21You are going to see your compile sweep and you are going
01:23to see any other assets that you included with your application.
01:26And certainly there is no way to install it from this point.
01:29The problem lies with the fact that the web server does not have the proper MIME type for AIR files.
01:36In other words, it doesn't know what to do with that AIR files.
01:39It doesn't know how to send it to the end user.
01:41So we are going to need to go in and update the configuration for Apache.
01:46Now just to note; if you have your own server it might be easy enough to go and do this.
01:51However, if you are on a shared host you might have to contact your technical support
01:54and see if they can go in and do this for you.
01:56So I am going to close this window, and I am going to go ahead and close this window,
02:02and we are going to go to another directory within XAMPP.
02:05We are going to go to XAMPPapacheconf.
02:10Then we are going to locate the httpd.conf file and we can just right click and go to edit.
02:15Now in this file; you are going to want to search for default type and directly under is where you are going
02:24to place the MIME type declaration for AIR.
02:26But you are probably wondering what is the MIME type declaration for AIR.
02:30What is a MIME type declaration at all?
02:31That's basically just phrase that you put into your server configuration file
02:37that tells it how to handle certain things.
02:39So I am actually going to go to myblog for a moment because I have actually posted an article
02:43that explains how to do this for multiple web servers.
02:46The first option here is Apache and since that's what we are using we actually can just copy
02:51and paste this directly under our configuration file.
02:53So if we go we can hit the plain text option here
02:57and then we can just highlight this entire line and then we can copy it.
03:01Now we can go ahead and minimize this browser window and now directly
03:05in the httpd.conf file we are just going to add this declaration.
03:10And basically what it says is, it is going to add the type and then there is the specific MIME type for Adobe AIR files
03:16and then it is going to tell it to handle any .air file with that MIME type.
03:21Now we can save the configuration file but we are not done yet.
03:25We actually have to restart Apache for these changes to take effect.
03:28So I am going to go ahead and close this window and I am going to open up the XAMPP control panel.
03:36We can see that Apache is currently running and so we are going to stop it.
03:40Now that it has said that the Apache service has stopped, we are now going to hit Start,
03:45and now it says that Apache is not running
03:47so we can minimize the control panel and we will open up a new web browser.
03:52In this case, we can go to local host and go back to download.html.
03:56Now the first time you clicked this link it still might give you the wrong MIME type, but in most cases it should update
04:02to where now the Adobe AIR Installer can actually handle this file.
04:05Oops and they still gave the old one, just refresh the page, and click it again, and now we can see that it recognizes it
04:13as a .air file and now we can click Open.
04:17And we now can see that it actually begins going through the AIR installation process.
04:21So you need to be very careful when distributing your AIR files, that if you are placing them somewhere on a server
04:26where they can just be easily downloaded, you need to be sure
04:29that the server has been updated with the MIME type for Adobe.AIR files.
Collapse this transcript
Using the Seamless Install Badge
00:00There is another method for distributing your AIR applications
00:03that can make the entire process quite a bit easier for your users.
00:07Let's think about what is required to install an AIR application.
00:10First, the user has to be sure that they have AIR installed, so if they don't, they are probably going to have
00:15to go and download it from the Adobe site.
00:18Next, they are going to need to go somewhere and download your ".air" file and then they are going to need
00:22to download it to their computer and then install it.
00:25Now for most users if you just want them to install a single application,
00:29they might not be willing to go through all of these steps.
00:32But Adobe has actually developed some functionality that makes it quite a bit easier
00:35to distribute your AIR applications by using the Seamless Install Badge.
00:40Now recently, I wrote an article for the Adobe Developer Network that actually outlines the process
00:44for using the Seamless Install Badge, but also using it with another one of the Adobe Technologies
00:49and that's the Adobe Express Install for the Flash Player.
00:53Now the purpose of this is to actually use the Seamless Install Badge you have
00:57to at least have Flash Version 9.0.115.
01:02The Express Install can update most older versions of the Flash player up to at least that version
01:08and then it can proceed with the Seamless Install Badge.
01:11And what makes the Seamless Install Badge so useful is, it actually can walk the user
01:15through installing AIR without them ever leaving your site.
01:19So you don't have to tell the user, stop downloading my file, go and unload Adobe AIR and then come back,
01:24all of that is taken care of with the Seamless Install Badge.
01:27So the address for this particular article is adobe.com/devnet/air/articlesair_badge_install.html.
01:41On the first page of the article, you will see the sample files.
01:43We are going to be using the sample files.
01:46I have already downloaded the files and actually extracted them to the desktop,
01:50and so here is the directory badge install samples.
01:53So we now can go ahead and close this window.
01:55We are going to go ahead and close all the tabs.
01:58Next, we are going to actually open up our htdocs directory.
02:02Again, this is under C:XAMPP and then htdocs.
02:06We are now going to create a directory inside and we will just call it Badge.
02:12Now we are going to open up the sample files that came with the article,
02:18we are going to go to the Express Install example and we are going to copy all
02:23of these items directly into the Badge directory.
02:28Next, we are going to copy our browser.air file or whichever AIR file that you have packaged and we are going
02:35to place it in the directory with these items.
02:39We can go ahead and close the Badge Install samples window.
02:42The other files were there to either support the use of the badge, or to support the use of the Express Install.
02:49In this case, we actually can right click and just edit index.html.
02:53Now the main section need to worry about when using the Flash Install Badge, is this section right here
02:59between these two script tags, where it defines a lot of settings for this specific application.
03:04The first thing they were going to want to change is we are going to want to change the location
03:08of our AIR file, ours is at localhost/badge/browser.air.
03:19In addition, you also can set an application image to be used with the Seamless Install Badge
03:26and you will see what I mean with that in a second.
03:28We can go ahead and save this file and now we actually can open up a browser window, we can go to localhost/badge.
03:42When this loads up, you will see that we now have a button on the Stage.
03:45This is actually a Flash file, and you can see that there is an Install Now option for this application.
03:50We can now click on it, and it will tell us
03:53that it's actually downloading the AIR file and beginning the installation process.
03:57Now here is the great thing though.
03:58If you didn't have AIR installed already, the process would look almost identical except it will also install Adobe AIR
04:06as it installed your application.
04:08The other great thing is that with this you don't have to worry about what version of the Flash player users have.
04:14As long as they have something later than Flash player version 5, they can go to this page;
04:18they might be required to update their version of the Flash Player, but they can do so from this window
04:24and once their version of the Flash Player has been updated, they will see the Install Badge, they can click Install Now.
04:30Then, again if they don't have AIR that can also automatically be installed.
04:33So by using the Seamless Install Badge with the Express Installation,
04:38what it allows you to do is basically deliver your entire application including Adobe AIR
04:42and including updating the Flash player without ever having to leave your site.
04:46And this is a powerful feature and the best way to distribute AIR applications.
04:50So in this case, we could go ahead and click Open, it would walk us through the process of installing our application.
04:56Now as I said, there is a bit of customization that can go into the Install Badge,
05:00if we go back to the index.html file, you can see that we can change the application image
05:05and then within the documentation included with the sample files from the article, you can see that there are a lot
05:10of other settings that can be adjusted as well.
05:12So by using the Seamless Install Badge, we are able to do deliver a seamless experience for the user
05:18as they download and install your AIR application.
Collapse this transcript
Conclusion
Goodbye
00:00I hope you really enjoyed this series.
00:02I really enjoyed getting to share some of the cool things about AIR with you and hopefully you enjoyed some of the cool
00:06applications that we got to build.
00:08Now you've got the tools to go out and build the next generation of rich internet applications
00:12using the visual tools of Flash with some of the great capabilities of AIR.
00:16Go to it.
Collapse this transcript


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