Friday, 18 March 2011

Firefox HTML 5 demonstration

When in Firefox, Chrome or any other HTML5/CSS3 capable browser, take a look at this nice Planetarium demo at http://mozillademos.org/demos/planetarium/demo.html

Tuesday, 15 March 2011

Flex 4 / AIR: copyToAsync does not fire the ProgressEvent

Problem:

While working on an desktop AIR application, I came across the problem that the copyToAsync method of the flash.filesystem.File class does not fire a ProgressEvent.

I would love to use the Async method, because this does not hold up the rest of the application, but I wanted to display some progress indication in e.g. a ProgressBar.

Solution:

Open 2 streams, one to read from and one to write to. Read and write chunks of bytes and calculate the progress according to the bytesAvailable attribute of the read stream.

Sample code:

// This is an object which has a public attribute which contains the source of the file to copy and 
// a public function with a File parameter to copy it to


public var fileObject:File;


public function copyTo(destination:File):void {
     inStream = new FileStream();
     outStream = new FileStream();


     inStream.addEventListener(ProgressEvent.PROGRESS, onProgress );
     inStream.addEventListener(Event.COMPLETE, onReady );


     inStream.openAsync(fileObject, FileMode.READ);
     outStream.openAsync(destination, FileMode.WRITE);
}


private function onProgress(e:ProgressEvent):void {
     // calculate the percentage
     pct = Math.round(e.bytesLoaded/e.bytesTotal*100);


     // if you want to update the progress bar:
     bar.setProgress(pct, 100);


     // if the ProgressEvent is fired, we have data available in the inStream, so we can start writing data
     var bytes:ByteArray = new ByteArray();
     inStream.readBytes(bytes, 0, inStream.bytesAvailable);
     outStream.writeBytes(bytes, 0, bytes.length);
}


private function onReady(e:Event):void {
     // the whole stream is read, so close the files
     inStream.close();
     outStream.close();


     // dispatch a COMPLETE event to let listeners to this object know the copy is done
     fileObject.dispatchEvent(new Event(Event.COMPLETE));
}

And somewhere in the application, associated with the copying process, there's a progress bar like this:

<mx:progressbar id="bar" mode="manual" width="100%"/>

I'm sorry this code's not entirely complete, but I had to use fragments of my existing code to illustrate this principle. Feel free to experiment with it.