Archive for April, 2007

Example of the Flex Component Kit for Flash CS3

,,,

I’ve now had a chance to use the Flex Component Kit for Flash CS3. It worked as advertised for me. Check out Glenn’s presentation on the Adobe Labs page. If you are interested in this example, you will need to follow the instructions given on that page to upgrade Flex 2 and get the Kit for Flash CS3. Both are pretty easy to install.

I’m going to use the ball-and-star Flash SWF from the previous examples. This really shows how far things have come. When you compare this to the first article using ActionScript 2 SWFs with Flex 2, you’ll see what I mean.

Download this example

Here’s how I went about the process of using the Kit. I started with the same FLA I used in the last article.

Create a New Flash CS3 Document

It’s important to create a new Flash CS3 document. If you want to use symbols from another Flash 8 (or earlier) document, copy them to the new document’s Library. That’s what I did with the example and called it star_and_ball.fla. I copied over the Star and Planet symbols.

You can only use symbols with the Flex Component Kit. Since my previous example had all of the tweens and ActionScript code on the root timeline, I needed to create a new symbol for them in the new document. I created a new, plain, MovieClip symbol which I called StarAndBall (yes, it should have been StarAndPlanet). I placed the Star and Planet symbols into the new StarAndBall symbol in separate layers and copied the guide layer as well and the tween.

Note: Symbols should have (0,0) as their registration point. I made sure that my Star and Planet symbols were positioned so that as the Planet orbits the Star it all stays within these boundries. However, you can also add a special boundingBox to your symbol and Flex will use that for your component’s size. You can read about that in the documentation.

Creating the Flex Component

Once the symbol was working I selected it in the Library. Then I picked the new command, "Make Flex Component" from the Commands menu. Several things happened:

  1. Since my movie wasn’t set to 24fps, I was asked if I wanted to change it to 24fps. I responded Yes (see documentation for explanation).
  2. Then the output window showed that UIMovieClip was added to my Library and that my symbol, StarAndBall, was ready for export.

That’s really all there was to it. If you looked at the symbol’s properties before doing this you would have seen that it didn’t have a linkage name. Now, you’ll see that it has an ActionScript class (more on that later), that its base class is UIMovieClip, and that it is being exported.

Publish

You must publish your movie. This not only creates the SWF, but it also creates a SWC. Since my file is named star_and_ball.fla, publishing created star_and_ball.swf and star_and_ball.swc. When using the Flex Kit, ignore the SWF. Maybe a future version will even let you avoid creating the SWF, but for now just ignore it.

Using the Flash Component in Flex

Being able to pick any MovieClip symbol in your Flash libary and selecting a command to turn it into a Flex component was easy. Now the fun part. I created a new Flex project and opened its Project Properties dialog. I then went to the Build Path and selected the Library tab. Then I picked "Add SWC" and browsed to the star_and_ball.swc and brought it in.

Flex now believes that star_and_ball.swc contains a true Flex component named StarAndBall. To use I started typing:

<Star

Flex Builder’s code assistant brought up the StarAndBall class, so I selected it and <local:StarAndBall was inserted. I closed the tag and ran my application. The Flex application ran and the planet was orbiting the star.

At this point you probably think this may be no better than just using SWFLoader. That would be less steps, but did you see how Flex Builder found the Flash symbol as a class? That’s due to UIMovieClip in the SWC, making the symbol a true Flex component.

Going For Objects

In the past examples you could control the Flash SWF (stopping the ball from orbiting, scaling and rotating the star). In the first example it was all controlled by LocalConnection. In the second example (just a few days ago, really), you can directly invoke functions on the root timelime.

Using the Flex Kit also allows you to invoke methods, not on the root timeline, but on the symbol itself, just like any Flex component.

Going backt to the Flash CS3 document, star_and_ball.fla, I opend the properties for the StarAndBall symbol. You can see that there is a class named: StarAndBall. If I click on the pencil (edit) button, I’m told that the class does not exist but one will be generated for me in the SWC. Very nice. But you can make your own, too.

I created a class, StarAndBall.as and used the root timeline functions as class methods:

package {
     
import flash.display.MovieClip;
     
import mx.flash.UIMovieClip;

     
public class StarAndBall extends UIMovieClip
     
{
          
public function StarAndBall():void
          
{
          
}

         
public function rotateStar( angle:Number ) : void {
              
star_mc.rotation = angle;
          
}

          
public function zoomStar( factor:Number ) : void {
               
star_mc.scaleX = factor;
               
star_mc.scaleY = factor;
          
}

          
public function stopPlanet() : void
          
{
               
stop();
          
}

          
public function resumePlanet() : void
          
{
               
play();
          
}
     
}
}

Hmm, very similar to Flex component code. Of course, this is ActionScript 3, so you have packages and public functions and import statements. Now when the FLA is published, my class gets put into the SWC.

Back to Flex

In the Flex application I gave the component a name: <local:StarAndBall id="star" />. I added a button to pause the orbit of the ball/planet and made the click event handler invoke the stopPlanet() method of the StarAndBall class:

star.stopPlanet();

Flex Builder was happy to code-assist me with this one, too. When I typed the period, Flex Builder showed me all of the possible properties and methods, stopPlaying() being one of them!

Now that interacting with the Flash symbol as a bonafide Flex component works, I added the Pause/Play button and Slider controls for rotation and scaling. The event handlers for those controls directly invoke the methods on the Flash component. For example, the rotation HSlider does this:

star.rotateStar(event.target.value)

I hope this gives you some idea of the possibilies with Flash CS3 and Flex. Read the information on the Flex Connectivity Kit for Flash CS3 page; there are more things you can do with this tighter integration between Flex and Flash.


Using Flash CS3 with Flex 2

On the heels of my last article, Adobe has just released the Flex Component Kit for Flash CS3 on Adobe Labs. This ultra-cool kit lets you use Flash MovieClip symbols seamlessly in Flex.

This is really an impressive piece of work. All of the effort by the Flash and Flex teams comes together here. You’ll see why changing to ActionScript 3 was so important and how fluid the workflow has become. If you’ve been waiting to use Flex 2 or can’t decide if Flash CS3 is right for you, now’s the time! If you have any Flash content in Flex, or if you’ve been considering adding Flash content to your Flex applications, this is what you have been waiting for!

For example, once you export your Flash CS3 MovieClip as a SWC, you use it just like a custom component in Flex (there’s no SWFLoader necessary). This means you have access to its public methods and symbols as with any Flex component. You can also handle events dispatched by the Flash CS3 MovieClip.

How do you do all of this? Rush right over to the Flex Component Kit for Flash CS3 page and read the instructions. You will need to be using Flex 2.0.1 and update that with the Flex 2.0.1 patch for CS3 Compatability (also linked from the Labs’ page).

Have fun. Be creative. Show the world what only Flash technology and your imagination can do.

(did I mention that I think is a really great idea?)

Using ActionScript 3 SWFs with Flex 2

Awhile ago I wrote an article, Using ActionScript 2 SWFs with Flex 2. In that article I showed how you can communicate between a SWF written with ActionScript 2 and a Flex 2 SWF, written in ActionScript 3. The communication is done with LocalConnection as if the two SWFs were in separate Flash Players. That is effectively true since each SWF is put into its own virtual machine within the Flash Player.

With the release of Flash© CS3 you no longer have to use LocalConnection. Flash CS3 can create ActionScript 3 SWFs which are loaded into the same Flash Player virtual machine as a Flex 2 SWF. If you compare the two examples you’ll see this new method is clean and very easy to implement.

Download the Example
Get Flash CS3

Let’s start with the Flash SWF. I used the same Flash movie as I did in the earlier article, but this time I’ve updated it for ActionScript 3. If you open the FLA file and examine the ActionScript code, you will not see LocalConnection anywhere. Instead, you’ll see this:

function rotateStar( angle:Number ) : void {
  star_mc.rotation = angle;
}

function zoomStar( factor:Number ) : void {
  star_mc.scaleX = factor;
  star_mc.scaleY = factor;
}

function stopPlanet() : void
{
  stop();
}

function resumePlanet() : void
{
  play();
}

function getStar() : MovieClip
{
  return star_mc;
}

The functions, on the root timeline of the Flash Movie, can be directly called from Flex. In Flex, the SWF is loaded into a SWFLoader control:

<mx:SWFLoader width="300" height="300"
    
id=”flashStar”
    
source=”star_flash.swf”
    
complete=”starLoaded()” />

To rotate the star by 45 degrees, the Flex application calls the MovieClip’s rotateStar root timeline function:

var c:MovieClip = flashStar.content as MovieClip;
c.rotateStar( 45 );

The SWFLoader’s content property is the SWF’s root timeline. You cast the content property to MovieClip and then just call the functions defined.

Compare the code between the two examples. If you use Flash SWFs in your Flex applications, download Flash CS3 right away and simplfy your code.

On Creating Flex Applications

I get a number of questions from people with large Flex applications that have run into a problem. For example, someone might have a TabNavigator and sometimes one of the tabs doesn’t show up or a tab remains even if the child component has been removed.

Isolating the problem can be difficult because the Flex application is large and requires data from a server or some other resource that makes it nearly impossible to send to us in Flex Product Support.

If you are involved in a large-scale development project (or think you will be), then STOP. Don’t go any further. I’ve got some advice.

Patterns

There are a number of books and papers about software development and they have fancy names like the waterfall method, or simply unit testing. These are good, sound, tested techniques that might at first appear to be so much academic fluff, but there is a reason people went to the trouble of creating these design and development patterns.

I’m not going to write another book on the subject, but rather distill them into something I hope makes sense and is easy enough for you to implement. This is how I work on a problem.

The Steps (or the Zen of Development)

The first step is research. That is, figuring out how something is going to work before incorporating it into the application. For example, suppose I think I’ll want to use a Move effect. I’ll write a separate application to explore how the Move effect works. I’ll try out its options and may be I’ll discover that it doesn’t work as I thought it did. Or may be I’ll discover that what I really want is a Move + Zoom effect and then I’ll figure out how to use Sequence or Parallel effects. The point is, I look at the application and think about the parts that I’m unsure of. I may not know if a DataGrid with 30 columns will perform well or even been easy for the end-user to use. It is this exploration of the possibilities that can give you a better feel for how Flex works and really build up your skill set.

The second step is organization. I try to think of the parts of an application as coming from 3rd party vendors. If I need a DataGrid with special features I think about it as if I could buy it from someone. This is also known as the black box approach. In other words, I don’t want any other part of the application to be able to muck with the insides of my special DataGrid. Nor do I want my special DataGrid to know anything about the rest of the application. Thinking about it this way isolates each major part and leads to the next step.

Hint: This is where custom events come into play. A custom event helps you identify what action is happening that relates to the new component classes. A custom event can be as simple as a new event type (eg, "inventoryUpdate") or it can contain additional information (eg, the part number and name of the item being updated). Each component or group of components should have their own custom event(s).

The third step is interfaces. This is how parts mesh or fit together. It involves how one black box component interacts with another one. Obviously there are parts of a component that have to be publically exposed. Think about the Flex componets. The DataGrid does not know a thing about your application. All you can do is interact with its public functions, properties, events, and styles. If you discover that the DataGrid does not do something you want, you can create your own class, extending DataGrid and add those features. But you should create your class with the same intention – expose just those public functions and properties that get the job done.

Hint: Using actual ActionScript interfaces can really help keep parts of the application isolated. An interface provides the contract between a component and its users, but it also allows the component developer to change how the component works (or to fix bugs) without adversely affecting the rest of the application.

The last step is testing. That is, testing each of these units. Write stand-alone applications to try your components out separately and in logical combinations as they might be used in your larger application. You may discover flaws, shortcomings, or eliminate unnecessary features at this stage. If you’ve done the research step, then you’ll already have most of the testing code in place.

Hint: If in the testing phase you run into a problem you cannot solve, you have a self-contained example that you can send to someone for help.

Benefit

The benefit to this approach is that you have a much more reliable application. Plus you may have created reusable components for a future application.

Further, should you need the services of the Flex Support Team, you’ll have ready-made test cases that you can send to us so we can quickly help resolve the problem.


Apollo Music Player Redux

After I received a comment on the previous Apollo Music Player article I decided to implement the missing feature of selecting the music library directory.

The new version, available for download here or on the previous article, has an option button on the Library panel where you can select the directory containing the music files. If you are interested in seeing how to use the Apollo File class and supporting UI components such as FileSystemList, take a look at this new source code.

Library Options Button

Library Options Dialog

Also, I should add to the to-do list "Playlist" as there is no support for them in my version. It is pretty amazing how complex something as simple as a program to play an MP3 file can get.

Download AIR installer. This requires the Apollo Alpha1 runtime. The file may download as a .zip file (for some reason I don’t understand). Rename it .air before launching it. Just double-click it once you have the Apollo runtime installed.

Download Source. The source is missing the Visualization source code by Ben Stucki. If you want to use it, please download the latest copy from the Adobe Exchange. This new source code has been restructured a little and I’ve added comments to the code.

Apollo Music Player

,

If you haven’t checked out Adobe Apollo on Adobe Labs yet, what are you waiting for? Apollo is a platform-independent runtime system. Apollo applications can mix Flash, HTML, and PDF content all in one application.

If you download the Apollo alpha trial you’ll find some great examples. I decided to try my own hand at an Apollo application and created a music player. There is a music application on the Apollo Showcase site, but there’s nothing like writing your app to get a feel for how things work.

You can rip your CDs into a special directory ({documents}/My Music) and the music player will display them in a Tree control. Select an album from the control and the track listing will be displayed in the main window. You can play, pause, and skip to any point in a song. You’ll also be treated to a visualization by Ben Stucki

Downloads

13 Apr 2007. These downloads are the same as the ones in the Apollo Music Player Redux article.

Download Music Player Installer AIR file (you will need to install the Apollo Runtime System first). The uploaded file has an extension of .air but the browser may try to download this file as a .zip. Right click this link and pick Save As and give the file a .air extension. Or download an save the file with a .air extension. This way you can double-click it and the Apollo Runtime will install the application properly.

Download Music Player Source (a zip file with a Flex 2.0.1 Project). The source does not include the visualization component; please download that from Adobe Exchange or remove it from the application.

Music Directory

The music directory ({documents}/My Music, where {documents} is your local documents directory; on Windows that would be My Documents) should be structued like this:

My Music/
        artist/                (eg, Jason Mraz)
             album/          (eg,     Waiting for my Rocket to Come)
                 track         (eg,            You and I Both.mp3)

This is the typical structure created by Windows Media Player when it rips a CD to disk.

Things to Note

I built and tested this application in Flex Builder. Apollo applications are created in a familiar environment with tools you already know.

Existing Flash and Flex content integrate easily. I pulled the visualization component from the Adobe Exchange and used it right away. Any Flex components you have already created can be used as-is.

The Shuffle and Repeat buttons use small Flash 8 SWFs when toggled on. The Repeat button, for example, shows a spinning arrow.

To do

There are still a few things to do:

  • Allow the music directory to be anywhere. Right now I coded it for My Documents/My Music.
  • Display album art in the tree control. Most of the time one or more image files are deposited with the album contents so it could be displayed in the tree.
  • Since HTML content can be easily displayed in an Apollo application, an "Album Details" button could display information about the artist or even display the artist’s web site within the Apollo windows.

The Stack Components

Not too long ago I read a question from someone who wanted to know how to make the Accordion control display more than one child at time. The response said to use a VBox.

This question and the response intrigued me, so I set out to create a control which would allow any number of its children to be open simultaneously. After some tinkering I came up with the Stack components: VStack and HStack, show in the following figures.

VStack with 3 children open
VStack with middle child open, rest closed

 

HStack with 3 children open
HStack with middle child closed, rest open

The VStack component looks very much like Accordion, except zero, one, or any number of its children can be visible at once. HStack is the horizontal equivalent.

These might not be the most useful components, but there are some interesting things you can use in your own components. You can download the source (a zip file Flex Builder 2 project) here: Stack Component Source.

How It’s Made

I created a base component called StackBase which extends UIComponent. StackBase has a single child: a Box container; VStack extends StackBase and makes the child a VBox and HStack extends StackBase and makes the child an HBox.

My goal was to capitalize on the layout management already built into the Box classes and to use "off-the-shelf" parts when possible, making the component easier write, understand, and maintain.

The DefaultProperty

I wanted the Stack components to behave just like any other Flex navigator component, such as Accordion. Meaning, I wanted to be able to use it like this:

<adobe:VStack …>
      <mx:Canvas …>
            <!– canvas children here –>
      </mx:Canvas>
      <mx:Canvas label="Page 2">
            <!– canvas children here –>
      </mx:Canvas>
      <!– etc. –>
</adobe:VStack>

I used the [DefaultProperty] metadata tag to tell the Flex compiler which property should be used if none is specified. Now it might not look obvious, but those Canvas containers within the VStack definition do belong to a property – contents – of the StackBase class. Open StackBase.as and you’ll see what I mean:

[DefaultProperty("contents")]
public class StackBase extends UIComponent …

and further down you’ll see the contents property defined:

[ArrayElementType("mx.core.Container")]
public function set contents( value:Array ) : void …

The contents property is an Array and for the Stack components, it is an Array of mx.core.Container classes (or any class that extends Container, such as Canvas). Just try and put something other than a Container in stack and you’ll get the same error as if you were using a ViewStack or Accordion.

Creating the Content

The StackBase createChildren() method creates the Box. The contents – children of the Box – cannot be created at this time in the component life cycle because the contents property may not be set. A better place is in commitProperties().

In case you didn’t know, commitProperties() is called once all of the properties have been set and the component children created (or in response to invalidateProperties()). The children may not yet be visualized, but they are available to have their own properties set. This means the contents Array is set with the components to go into the Box and the Box is ready to accept children.

The process of creating the content actually involves creating a couple of additional components. The content given in the MXML file is not made directly the children of the Box. Instead, a Canvas is created and it is given the content children and a control to open and close the child. This is a StackHeaderButton control which is part of this package.

When the content has been created you have:

Box
    Canvas
         StackHeaderButton
         container-specified
    Canvas
         StackHeaderButton
         container-specified
    etc.

Sizing

The trick to this component is sizing the content properly. Suppose for example you have a VStack with 3 children. If all of them are visible, how much room do they take up? Suppose only one of them is visible?

The solution is that all of the open children evenly divide the space available, minus the space taken by the StackHeaderButtons. Using the example, when all three are visible they use approximately 1/3 each of the space. If one is closed, the remaining two occuply 1/2 of the the space.  You are welcome to take this component and modify it to do something differently.

Interactivity

The StackHeaderButtons not only visually separate the content but they also open and close the content. When you click on a header, the child slides either open or closed and the remaining children have their sizes adjusted. This should appear fairly smooth because I used a Resize effect to do this.

My algorithm goes something like this:

First count the number of children in the content which are closed ("collapsed" in the code). Then take the space occupied of the Stack control and divide it evenly among the open children, subtracting the space taken for the StackHeaderButtons, of course.

As this is being done, a Resize effect is created for each child. Afterall, when one child closes the open ones increase their size.

All of the Resize effects are placed into a Parallel effect so that all of the adjustments are done at once. When the calculations have completed the Parallel effect is played and the contents adjust to their new sizes.

VStack vs. HStack

I had originally planned this to be a vertical control, but after I saw how it all came together I decided to add in the HStack control. I changed StackBase to use some protected functions for determining the size and position of its child content and the HStack component overrides these functions and returns width instead of height or x instead of y.

Mostly the controls are the same and StackBase takes care of the majority of the work.

Skins

The StackHeaderButton uses a skin class for its appearance. A skin is a class whose sole job is to provide the visualization for a component. I started off using a simple Button for the header, but decided it was easier to rotate a Label than the label of a Button. You can change the appearance of the headers just by writting your own skin classes.

Summary

Even if you don’t find these controls useful themselves, use them as a guide to building your own components. I have to admit that using Box, Canvas, and Resize made the job easier, but if you want to write the whole thing from scratch, go for it. Just pay attention to the Flex framework component life cycle.

Some things of note in this component are:

[DefaultProperty] and [ArrayElementType] meta tags. These tags make it easier for people to use the component.

Resize and Parallel effects. You can make a whole lot happen all at once and make the control appealing to use.

Skins. Think about how your component is visualized and then write those separately as skins. This will make customizing its appearance easier and it separates the function of the component from its presentation.

Embedded Fonts. For the HStack to look correct, the labels on the StackHeaderButtons are rotated 90 degrees. They would be invisible if you didn’t use an embedded font for them. To make things speedy, the Flash Player uses system fonts for most of the text. But system fonts do not have vector paths (outlines) that describe the letters, so they cannot be rotated. By embedding a font you can rotate, skew, and scale text controls easily.