Apollo Native File Dialogs

Currently the Apollo Alpha doesn’t support native file dialog boxes (it will before the final official release.) Despite that, there is a way to get this functionality now by using existing Flash Player APIs.

I will first show how to display a file ‘Save’ dialog box which allows the user to specify the name of the file they would like to write to the disk. This will allow them to type in the name of a file that may not exist. The user can also select a file that already exists and the dialog will prompt the user that they are about to replace that file on the system.

To accomplish this in Apollo, you use the ‘download’ method on the flash.net.FileReference class. Because the flash.filesystem.File class extends FileReference, you can employ this technique by using that class as well. The trick to getting the File reference without actually downloading the file is to cancel the URLRequest before it executes. See the code below for an example:
[as]
private var file:File;

private function saveFile():void
{
// Here we create a new File class and wait for the
// ‘open’ event. The URLRequest can use a URI pointing
// to any resource, we will be canceling it in the event
// handler. It must be a valid URI though. We also specify
// the default name for the file that the user will be able
// to override in the dialog.
file = new File();
file.addEventListener( Event.OPEN, handle_saveFileSelect );
file.download( new URLRequest(“http://foo”), “hello.txt” );
}

private function handle_saveFileSelect( event:Event ):void
{
// First cancel the download operation. We aren’t going
// to download a file but we now have a reference to the
// file the user specified anyways!
file.cancel();

// Time to write out some text to the file.
var fileStream:FileStream = new FileStream();
fileStream.open( file, FileMode.WRITE );
fileStream.writeUTF( “Hello World!” );
fileStream.close();
}
[/as]

Another File dialog that you may want to use is a file chooser dialog. This dialog will only allow the user to select only existing files. We can actually use this API as documented we don’t have to cancel any URLRequests like in the previous example.This can be accomplished by using the flash.filesystem.File ‘browse’ method. Lets take a look at the code:

[as]
private var file:File;

private function readFile():void
{
file = new File();

// Lets listen for the ‘select’ event. This event tells us that
// the user selected a file. We can also listen for a ‘cancel’
// event that will tell us the user didn’t select a file and
// closed the dialog.
file.addEventListener( Event.SELECT, handle_readFileSelect );

// Open the dialog box and wait for the ‘select’ event.
file.browse();
}

private function handle_readFileSelect( event:Event ):void
{
// Get a reference to the file and trace out the
// text representation of the file.
file = File( event.target );

var fileStream:FileStream = new FileStream();
fileStream.open( file, FileMode.READ );
trace( fileStream.readUTF() );
fileStream.close();
}
[/as]

To get a reference to more than one FileReference objects, you use the flash.net.FileReferenceList class. I will not show an example of that here, but it follows the same pattern as above. Be sure to check out the FileReferenceList docs.

There are some limitations to these techniques and issues that you should be aware of:

  • There is no directory chooser dialog. You can only select or create file references.
  • You cannot specify an initial directory for the dialog. It will default to the directory of the last file that was selected.
  • Each Apollo application can only have a single file dialog box open at any given time. This means that each window of an Application is limited to the one dialog for its parent application.

I have attached a simple Flex Builder Project file that contains all of the code above.

6 thoughts on “Apollo Native File Dialogs

  1. James, the sample project doesn’t add any significant functionality. The only thing it does differently is add text fields so that the string you write to the disk can be customized, and when you read from the disk the text will appear in the second TextArea component.

  2. Another limitation of this is that the dialog titles will say “upload” and “download”, which may be confusing to users who are just loading or saving a file on their local hard drive. Again though, these are just temporary measures until native dialogs are fully supported.

  3. Hi Daniel,
    If I use your code as written, I get an IOError after closing the save() popup (i.e. your first example).

    However, if I change the following line:
    file.addEventListener( Event.OPEN, handle_saveFileSelect );
    to this:
    file.addEventListener( Event.SELECT, handle_saveFileSelect );

    the problem goes away.

    Hope that’s helpful,
    Ian

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s