fp9: Category

Category: fp9

Flex 360 tickets selling fast

Posted At: December 17, 2009 12:12 PM | Posted By: Jeff Tapper
Related Categories: actionscript3, flash, flashplayer, flex, flex3, flex4, FlexUnit4, fp10, fp9, Speaking Conferences

Down to the last 5 (Cheap) tickets left for 360|Flex. Register now, save $100 and get the same awesome content for a little less coin. Act fast, these last tickets won’t last. When they’re gone, the regular price of $599 kicks in. Come on out and hear me give advice how not to hurt yourself with code, in my “Ouch, it hurts when i do that” talk.

Comments (0)

Fun with custom preloaders in Flex

Posted At: October 2, 2009 11:10 AM | Posted By: Jeff Tapper
Related Categories: actionscript3, as3, flash9, flex, flex3, fp10, fp9

As you probably know, its pretty easy to use a custom preloader in flex to replace the built in preloader shown as a flex application loads. There are a few tricks to remember with a custom preloader though, remember that the preloader is built to be displayed until the flex framework is done downloading. As such, the preloader won’t display until all the classes needed by the preloader are done downloading. For this reason, its really important to remember that your custom preloader class doesn’t make use of the flex framework, because if it does, the users will see nothing until enough of the framework has been loaded to display the preloader, and the preloader will only be displayed while the remainder of the framework is downloaded. Fortunately, the DownloadProgressBar class makes little use of the flex framework, as it extends Sprite, instead of UIComponent, and only utilizes a few event classes from flex, which don’t require any additional framework classes. A quick google search can show you dozens of examples on subclassing DownloadProgressBar to create a preloader which matches your application. A larger challenge is faced when you have additional needs from a preloader. Frequently, we are tasked with writing a preloader which is shown during the initial download, as well as remaining displayed until some startup procedures are complete within the application. Some might try to approach by referencing Application.application within the preloader, to listen for a custom event indicating that the startup procedures are complete. Of course, this is not an ideal solution, as referencing the Application class will link in the mx.core.Applicaiton class, which in turn links in around 170k worth of the Flex framework. A better approach is to create a new class, which is not linked to the flex framework, which can act as an event bus between the main application and the preloader. If this class is built as a singleton, you can be assured that both the main application and the preloader are accessing the same instance, allowing for a simple and convenient mechanism for the preloader to listen to the main application, without needing any reference to the application or the flex framework.
package net.digitalprimates.preload { public class PreloadEventBus extends EventDispatcher { public var isReady:Boolean = false; private static var _instance:PreloadEventBus; public static const READY:String = "READY"; public static function getInstance():PreloadEventBus { if (!_instance) { _instance = new PreloadEventBus(new SingletonEnforcer()); } return _instance; } public function PreloadEventBus(singletonEnforcer:SingletonEnforcer) { if (!singletonEnforcer) { throw new Error("PreloadEventBus is a singleton class, use getInstance() instead"); } } } } class SingletonEnforcer {}
With this class, when the main application is done with its startup procedure, it’s a simple process to get a reference to the PreloadEventBus, set isReady to true, and dispatch an event.
protected function applicationCustomStartupDone(event:Event) { var bus:PreloadEventBus = PreloadEventBus.getInstance(); bus.isReady = true; bus.dispatchEvent( new Event ( PreloadEventBus.READY ); }
In the custom preloader, you can override the set preload method, and instead of listening for the complete event as the base class does, listen for the INIT_COMPLETE event, which indicates that the application has loaded, and had its initialize event dispatched. In the event handler for this method, you will get a reference to the PreloadEventBus, check if the application has already set the isReady flag to true, and if not, listen for the READY event.
private function bus:PreloadEventBus = PreloadEventBus.getInstance(); override public function set preloader( value:Sprite ):void { preloader.addEventListener( FlexEvent.INIT_COMPLETE , initComplete); }
An important thing to note is the lack of call to super.preloader in this overridden setter. If the base classes setter is allowed to run, the preloader will act as initially intended, such that it disappears when the application is done downloading. As the purpose of this preloader is to allow for the application to determine when to hide the preloader and start the app, its important we override this functionality. You may find that you need to listen for other events here, such as ProgressEvent.PROGRESS, FlexEvent.INIT_PROGRESS or Event.COMPLETE. This example shows the bare minimum you would need to make use of the preloader
private function initComplete( event:Event ):void { if (bus.isReady) { completePreloader(event) } else { bus.addEventListener(PreloadEventBus.READY, completePreloader); } }
While its not expected that the application will be done with its initialization procedures before the INIT_COMPLETE, but, based on how the application is built, it is possible. To avoid this race condition, the isReady property of the PreloadEventBus is used, so that the preloader only listens for the READY event if the application is not already done with its startup. Last but not least is the completePreloader method, which is called when the preloader has determined that the application is ready. With the logic in initComplete, this same method will be used, regardless whether the state of the application was determined by the isReady property, or by listening for the PreloadEventBus.READY event.
private function completePreloader(event:Event):void { dispatchEvent( new Event( Event.COMPLETE ) ); }
Event.COMPLETE is used, as this is the event for which the system manager listens, to know that the preloader is done with its job. By preventing its normal mechanism of dispatching, and only dispatching it when the application determines it is ready, you have a nice clean approach to allow the the preloader to display as long as it needs to.

Comments (3)

My Speaking Engagements for the first half of 2008

Posted At: January 22, 2008 12:01 PM | Posted By: Jeff Tapper
Related Categories: actionscript3, adobe, apollo, as3, cfmx7, cfunited, ColdFusion, enterprise, flash, flash9, flashplayer, flex, flex3, FMS, fp9, Speaking Conferences

1/18 – Flex Camp Chicago

1/24 – Flex Camp Omaha

2/24-2/27 – Flex 360 Atlanta

3/12-3/13 – CFUnited Europe

5/1-5/4 – CF.Objective()

5/19-5/23 – WebManiacs

6/25-6/28 – CFUnited

Comments (0)

Reflecting an image in Flex

Posted At: September 21, 2007 7:09 PM | Posted By: Jeff Tapper
Related Categories: actionscript3, as3, flash, flash9, flashplayer, flex, flex2, flex3, fp9, runtime

Increasingly, clients have been asking for a "reflection" effect, showing a vertically flipped image of a component next to the actual component.  After reinventing the wheel on this several times, I came up with this simple reusable component:

package com.tappernimer.components{
import mx.containers.Canvas;
import mx.core.UIComponent;
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.display.IBitmapDrawable;
public class VerticalReflection extends Canvas{
private var _component:UIComponent;
public var trans:Number=.5;
public var filterArray:Array=new Array();
public var skewY:Number=0;
public var skewX:Number=0;
public function get component():UIComponent{
return _component;
}
public function set component(c:UIComponent):void{
this._component = c;
// hack to work around issue with component being 
// a dynamically loaded image its possible for the 
// image to be fully loaded, but its height or width 
// not yet set this call later, keeps retrying until 
// the values are set.
if(c.width ==0 || c.height==0){
callLater(resetComponent,);
return;
}
doReflection();
}
private function resetComponent(c:UIComponent):void{
this.component = c;
}
private function doReflection():void {
// create bitmap object
var bmpData:BitmapData = new BitmapData(
	component.width,component.height);
// create matrix
var invertMatrix:Matrix = new Matrix(1,skewY,skewX);
// set matrix to invert vertically, but normal horizontally
invertMatrix.scale(1, -1);
// move matrix, so top is at bottom, and vice versa
invertMatrix.translate(0, component.height);
// draw component flipped
bmpData.draw(component as IBitmapDrawable,invertMatrix);
// create a new holder for the image
var ref:UIComponent = new UIComponent();
// match new holders size to the original
ref.setActualSize(component.width,component.height);
// fill the new component with the image
ref.graphics.beginBitmapFill(bmpData);
ref.graphics.drawRect(0, 0, 
	component.width, component.height);
ref.graphics.endFill();
// set the transparency
ref.alpha = trans;
// apply any filters
ref.filters = filterArray;
// add image to stage
addChild(ref);
} 
}
}

This component can then be passed any other component to reflect, accepting filters (filterArray), alpha value (trans), and arguments to allow you to skew the reflection.  In fact, using it can be as simple as this:

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx=http://www.adobe.com/2006/mxml 
xmlns:c="com.tappernimer.components.*" 
layout="absolute">
<mx:Image id="image" source="images/tn_logo_full.jpg"/>
<c:VerticalReflection id="ref" 
component="{image}" 
x="{image.x}" y="{image.height}" 
filterArray="{new Array(new BlurFilter())}"/>
</mx:Application>
Here is the code running:
 
 

Comments (0)

H.264 Support in FlashPlayer

Posted At: August 22, 2007 11:08 AM | Posted By: Jeff Tapper
Related Categories: actionscript3, adobe, apollo, as3, enterprise, flash, flashplayer, flex2, flex3, fp9, h264, mpeg4

I missed it yesterday, when it was announced, but Adobe has now announced support for H.264 (also know as MPEG4) in an upcoming version of the flash player.  H.264 is the same standard which is used by BluRay and HD-DVD — the ability to have this type of video in our web applications is absolutly huge.  Remember, not that long ago, Adobe announced plans for the Adobe Media Player (AMP), as a desktop application which was built with AIR and Flash — now, AMP will be able to use H.264 as well as FLV for its video content.

 

 

Comments (0)

FlexManiacs 2007 – Getting Started with Apollo

Posted At: June 27, 2007 12:06 PM | Posted By: Jeff Tapper
Related Categories: actionscript3, adobe, apollo, as3, flash9, flashplayer, flex2, flex3, fp9, ria

As promised, here are the starting files from my "FlexManiacs 2007 – Getting Started with Apollo" session.  Thanks for attending my session, I hope you enjoyed it and the FlexManiacs Conference.

Overall, i thought this conference was a great success.  Many attendees of all levels.  Great networking, Great debates, and an all around good time.

Comments (8)

Parsing ITunes Library.xml with ActionScript 3.0

Posted At: June 27, 2007 12:06 PM | Posted By: Jeff Tapper
Related Categories: actionscript3, apollo, as3, flash9, flex2, flex3, fp9, itunes, libraryxml, ria

I recently built a hands-on presentation for the FlexManiacs conference, and thought it would be fun to have the class build a little apollo based mp3 player, which reads in the mp3 files from an iTunes libary.xml file, which they can then play, pause or stop.  Well, we did just that, but oddly enough, the hardest part in building that application turned out to be parsing the xml.  In the time I've been working with AS3 and Flex2, I've always found that working with well formed XML is incredibly easy.  Therein lies the problem, the xml that apple uses in this file is hideous, and seems to have been designed by someone without the least bit of understanding of structuring xml.

Here, you can see a sample library.xml file from itunes.  The first odd thing you might notice is that there are a total of only 5 different node names used throughout the file:  plist (the root node), key, string, integer and date.  Rather than using intelligently named nodes (ie. PlayList, Song, etc), a dict node is used to indicate any arbitrary grouping of other nodes.  Within a dict, you will find other dict nodes, or key nodes followed by either a node describing a datatype (string, integer or date).

The real challange in parsing this, is that there is no grouping of keynames to their values, except for the order in which they appear.  For example, for a song named "Every Worthy Cause" performed by Ben Wakeman, rather than an xml structure like this:

<song name="Every Worthy Cause" artist="Ben Wakeman" />  

or

<song><name>Every Worthy Cause</name><artist>Ben Wakeman</artist></song>

ITunes has it structured like this:

<dict><key>Name</key><string>Every Worthy Cause</string><key>Artist</key><string>Ben Wakeman</string></dict>

 This poses a number of challenges, primarily, because the only thing which associates the Name node with the value Every worthy cause is the order the nodes appear.  This makes the use of E4X for parsing the nodes nearly impossible.   Here, you can see the solution I came up with for parsing this xml.

package parsers{
 import mx.collections.ArrayCollection;
 import valueObjects.PlayListEntry;
 import flash.utils.Dictionary;
 import utils.TimeFormatter;
 
 
 public class LibraryParser{
  private static var lib:XML;
  public static function parseLibrary(xml:XML):ArrayCollection{
   var ac:ArrayCollection = new ArrayCollection();
   lib = xml;
   for each(var d:XML in xml.dict.dict.dict){
    ac.addItem(parseSong(d));
   }
   return ac;
  }
  private static function parseSong(song:XML):PlayListEntry{
   var ple:PlayListEntry = new PlayListEntry();
   var tune:Dictionary= new Dictionary();
           
   var key:String;
   for each (var tuneProperty:XML in song.children()){
             
       if (tuneProperty.name() == "key"){
           key = tuneProperty.text();
       } else {
           tune[key] = String(tuneProperty.text());
       }
   }
   ple.album = tune.Album;
   ple.artist = tune.Artist;
   ple.bitRate = tune["Bit Rate"];
   ple.genre=tune.Genre;
   ple.location=tune.Location;
   ple.name = tune.Name;
   ple.sampleRate = tune["Sample Rate"];
   ple.songLength = tune["Total Time"];
   ple.year=tune.Year;
   ple.lengthString = TimeFormatter.formatTime(ple.songLength);
   return ple;
  }
 }
}

What this does, is to find each dict node which indicates a song, and then loop over each of its children in order.  If it finds a node called Key, it creates a new entry in a Dictionary object (like a HashMap).  Once the dictionary is fully assembled, the elements from the dictionary are parsed into a strongly typed class called PlayListEntry, which simply specify all the attributes of a song.  The PlayListEntry class looks like this:

package valueObjects{
 public class PlayListEntry {
  public var name:String;
  public var artist:String;
  public var album:String;
  public var genre:String;
  public var songLength:int;
  public var year:int;
  public var location:String;
  public var bitRate:int;
  public var sampleRate:int;
  public var lengthString:String;
 }
}

A version of these files for use with Apollo (in which you pass in a FileStream object, rather than xml), can be found here.

If anyone has a more elegant solution to parsing this library.xml file into something usable in AS3, I'd love to hear it.

Comments (6)

A Great big pile of public beta’s from Adobe

Posted At: June 11, 2007 10:06 PM | Posted By: Jeff Tapper
Related Categories: actionscript3, ajax, apollo, as3, flash, flash9, flashplayer, flex3, fp9, free, scorpio

Today, Adobe has released 3 new public beta's on Adobe Labs:   The Adobe Integrated Runtime (formerly known as Apollo) beta, the Flex 3 Beta, and the Flash Player Updater were all publicly released on Labs today.  I've been recovering from a failed hard drive all day (remind me to post a blog about the wonders of SpinRite 6.0 when i get a minute), but I'll post more about all 3 of these, as well as the ColdFusion 8 (Scorpio) beta released 2 weeks ago, when i get a few minutes.

Comments (0)

Flash Player 8.5 has been renamed flash player 9

Posted At: April 22, 2006 4:04 PM | Posted By: Jeff Tapper
Related Categories: as3, flashplayer, fp9

In a wise marketing move, Adobe has renamed the flash player 8.5 public beta as the flash player 9 beta.
According to the Flash Player FAQ on Adobe labs, they will be publicly releasing the first beta of FP9 with Beta 3 of Flex 2.  They also acknowledge that the next version of the Flash Authoring tool (code named Blaze) will target the same Flash Player 9.

Considering the new Flash Player has a entirely reworked runtime (or virtual machine, if you prefer), it would seem that the next player is taking as large a step as any release since Flash Player 5, so the full version number, as opposed to a .5 version makes complete sense.

Any of you detecting for FP8 in your applications should ensure your code is looking for a major version >= 8, not simply == 8.

Comments (0)