You can stop waiting, its been released.

I'm a bit late in releasing this news, but our "Flex 3 Training from the source book" was released last week, and is now available from our publisher, as well as the major online bookstores such as Amazon, and Barnes and Noble. Speaking of Amazon, we are currently the #843 best selling of all their books, #15 in the Computers and Internet / Software category, and #8 in Computers and Internet / Programming. Thanks to all of you who have bought our book, and pushed the sales ranks so high.

Anyhow, I know folks have been asking me for months when this book would finally be released, and the answer is, last week.

Enjoy.

CFUnited Europe, AJAXWorld, and more conference stuff...

Next week I'm off to London to speak at CFUnited Europe, and the following week, I'll be speaking at AJAX World East.  In both places, I'll be speaking about the joy that is Flex 3 in all its forms.  The CFUnited talk is more focused on how Flex can improve the lives of CF Developers, while the AJAX World one is more focused on how Flex can help RIA developers increase their real world Retursn On Investment from RIA's.  On another note, CFUnited has just released the session schedule for their Washington DC Conference in June, and rumor is that the session schedule for WebManiacs should be available shortly.

My Speaking Engagements for the first half of 2008

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

Hey, what am I doing on blogs.digitalprimates.net?

I've been a bit slow in getting this announcement out, as I see several other bloggers have already posted on this, but the rumors are true.  Tapper, Nimer and Associates. Inc. has teamed up with Digital Primates Inc.    Some of you may recall, it was just over a year ago that I teamed up with Mike Nimer to form Tapper, Nimer and Associates.  It's quite an odd experience for me to go from a solo propietorship to a team of 15 or so developers in about 16 months.   With all the great minds from both our companies working together, we will be able to help more customer on bigger and better projects.  

Many of you probably know Mike Labriola for his work on custom Flex Components, he has extended the Flex framework in ways that the developers at Adobe never even imagined.  He is also frequently speaking at conferences and User groups.  Both Nimer and I ran across him at dozens of speaking events across the country, and as we talked, we found there were far more similarities between us then differences. 

One of our first meetings at a conference ended up with him as a co-author on the Flex 2 book.  A year and a half of meeting at conferences later, and we were helping each other out on projects so frequently that it made sense to explore further integrating our companies.  When the opportunity for Nimer and I to join forces with him and his company, it was much too enticing to pass up.

We are looking forward to doing great work together, continuing to build cutting-edge applications for our clients, continuing to teach the world to build better RIAs, and continuing to serve the community. 

Flex 3 Training From the Source - NOW AVAILABLE on rough cuts

I just heard from our editor's that about a 1/3 of the content for our upcoming "Flex 3 Training from the Source" book is now available in Rough Cuts form on Safari from Peach Pit.  Obviously, as the Flex 3 product hasnt been released yet, the chapter there may change as the product evolves, but we have been working diligently to get the updates in your hands as quickly as possible.  So, for those who are dying to get started with Flex 3, you can start reading the pre-release chapters now.

CFUnited Europe

I've been asked to speak at the first ever CFUnited Europe this year.  CFUnited, which has been running each year in the Washington DC area (earlier under the name CFUN) for the past 9 years, is branching out, and hosting the conference in Europe as well. The conference will be on March 12th and 13th in London.  Hope to see you there!  I hope to be presenting on Flex 3 for ColdFusion developers.

Reflecting an image in Flex

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,[c]);
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:
 
 

H.264 Support in FlashPlayer

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.

 

 

Changing Flex Style Sheets at runtime

Sorry its been so long since the last blog entry, between the two kids, writing 3 books, and many clients, its been hard to find time to write new entries here.  Today, I wanted to give a quick example of the Flex 2.0.1 feature of loading CSS style sheets at runtime.

In most Flex applications, I had been creating a seperate CSS style sheet, and compiling it into the application through the use of the <mx:Script source="..." />.  One of the pains of this, is that applying changes to the styles requires re-compiling the application, and as you probably now, the styles are one of the most frequently changed aspects of any application.

To help solve this problem, Adobe implemented the ability to load Style Sheets at run time in the Flex 2.0.1 release.  To do this, you first need to compile the CSS into a swf.  You can do this in FlexBuilder by right clicking on the css file and choosing "Compile CSS to SWF" option, or using the comand line compiler (mxmlc).  Once the css is compiled into a swf, it can be loaded with the StyleManager.loadStyleDeclarations(...) method.  Consider this simple example:

TestLoadStyles.mxml 

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
 <mx:Style>
  .text1{
   color:#0000ff;
  }
  .text2{
   color:#ffff00;
  }
 </mx:Style>
 <mx:Script>
  <![CDATA[
   private function changeCSS():void{
    StyleManager.loadStyleDeclarations("myCSS.swf");
    
   }
   private function undoStyle():void{
    StyleManager.unloadStyleDeclarations("myCSS.swf");
   }
  ]]>
 </mx:Script>
 <mx:Button label="change css" click="changeCSS()"/>
 <mx:Button label="revert css" click="undoStyle()"/>
 <mx:Label text="hi there"/>
 <mx:Label text="hi there" styleName="text1"/>
 <mx:Label text="hi there" styleName="text2"/>
</mx:Application>
 

myCSS.css

Application{
 color:#ff0000;
 font-size:40;
}
.text1{
 color:#00ff00;

Compile the css into a swf, and make sure it is in the same directory as the TestLoadStyles.swf. As you run the application, you can see the changes as the style sheet is loaded or unloaded.  One thing to notice, is that even when the styles are loaded, and styles initially defined, which are not overridden in the loaded style sheet still remain, therefore, the styles of .text2 (yellow text), remain yellow, even after the new style sheet is loaded, since the .text2 style does not appear in the load style sheet, while the style .text1 which is defined as red text in the initial application, is changed to green, as the same style name is defined in both, so when the new style sheet is loaded, the .text1 label changes its color from green to red, and when its unloaded, it reverts to green.

This offers great opportunities not only for greater separation of styles from the application, but also for the concepts of writing an application once and rebranding the same deployed application.

Parsing ITunes Library.xml with ActionScript 3.0

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.

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.9.001.