ActionScript.org Flash, Flex and ActionScript Resources - http://www.actionscript.org/resources
Creating widgets fast and easily with SPAS 3.0
http://www.actionscript.org/resources/articles/850/1/Creating-widgets-fast-and-easily-with-SPAS-30/Page1.html
Pascal ECHEMANN
I'm an ActionScript developer in the French Riviera.
I've created the Swing Package for ActionScript 3.0 (SPAS 3.0) which helps Flash developers to easily create RIAs with the Flash Platform and both Flash and Flex:
http://www.flashapi.org/ 
By Pascal ECHEMANN
Published on December 12, 2008
 

Difficulty: Easy
Time Taken: 20 minutes
Description: In this tutorial we will learn how to make a simple Celsius to Fahrenheit degree converter with less than 30 lines of code. Then, we'll see how to integrate it into a Flash application directly from the Flash CS3 main timeline.


Introduction

The process to create impressive widgets with Flex and to integrate them into Flash is too much complicated. For these reasons, one of the aims of SPAS 3.0 is to really simplify the coding process, without restricting its possibilities.

In this tutorial we will learn how to make a simple Celsius to Fahrenheit degree converter with less than 30 lines of code. Then, we'll see how to integrate it into a Flash application directly from the Flash CS3 main timeline.

Note: this example uses SPAS 3.0 alpha 2 release. In this release, the default L&F is the "spas" L&F, contrary to the previous release which uses the "basic" L&F as default Look and Feel.

We assume that you are familiar with external files programming and that you already have downloaded SPAS 3.0.
If not:


Part 1

First, let's create the class template. Open your favorite class editor (personally I use Flashdevelop) and create a new ActionScript file called CelsiusConverter.as.

The best way to create autonomous widgets with SPAS 3.0 is to extend the Popup class (org.flashapi.swing.Popup). Thus, the widget will be independent of the environment in which you will place it (principle of weak coupling).

So, open the CelsiusConverter file and create a class called CelsiusConverter that extends the Popup class, as shown below:

[as]package {
import org.flashapi.swing.*;
public class CelsiusConverter extends Popup {
public function CelsiusConverter() {
super();
}
}
} [/as]

The super statement calls the Popup constructor which has 3 parameters: title, width and height. The title specifies the text displayed on the face of the popup's title bar. We set its value to "Convert Celsius to Fahrenheit", which is not so bad, and we set the width to 250 pixels. (It is enough to display the widget's content). Moreover, in OOP we often prefer to initialize objects into an initializing method instead of the constructor method itself.

[as]public function CelsiusConverter() {
super("Convert Celsius to Fahrenheit", 250);
initialize();
} [/as]

Once the construcor function is defined, we can concentrate on the initialize() method to create the widget.


Part 2

The default layout for SPAS 3.0 containers is an horizontal flow layout. If you combine the default layout with the autoHeight property set to true, the UIContainer object automatically adapts its height if there is no more enough width for displaying the next object in the display list. By the way, we set the padding, horizontalGap and verticalGap properties to 10 pixels.

[as]private function initialize():void {
autoHeight = true;
padding = horizontalGap = verticalGap = 10;
} [/as]

Now, what about adding controls? The first control we need is the text input where the user can type the temperature to convert. We declare this object as a private variable to allow it access into the scope of the CelsiusConverter object. Then we create a new instance of the TextInput class with 0 (zero) as default parameter:

[as]private var _input:TextInput;
private function initialize():void {
autoHeight = true;
padding = horizontalGap = verticalGap = 10;
_input = new TextInput("0");
} [/as]

The user mustn't type characters other than numeric values, and the number's size cannot exceed 5 characters. So we use the maxChars and restrict properties of the TextInput class to do that. Add the following lines of code below the TextInput instance declaration:

[as]_input.maxChars = 5;
_input.restrict = "0-9"; [/as]

The next control is a simple label object where the result of the conversion will be displayed. This control must be accessible from the internal scope, like the preceding one. Once we have declared the private variable for this control, we create the corresponding Label instance as detailed below.

[as]private var _result:Label;
private var _input:TextInput;
private function initialize():void {
autoHeight = true;
padding = horizontalGap = verticalGap = 10;
_input = new TextInput("0");
_input.maxChars = 5;
_input.restrict = "0-9";
_result = new Label("fahrenheit");
}[/as]

Part 3

We don’t need anymore to create controls which are internally accessible. We will just create a Button control to convert the temperature, and the label which indicates that the temperature unit of the input field is celsius.

[as]var _btn = new Button("Convert", _input.width);
var celsiusLabel:Label = new Label("celsius"); [/as]

All controls are built now. To add them at one time into the Popup container we use the addGraphicElements method. The following line of code illustrates this process:

[as]addGraphicElements(_input, celsiusLabel, _btn, _result); [/as]

Well, the widget is not so bad, but it is not interactive yet. We must implement a function to convert the temperature. Let's call it convertTemp. The algorithm of the convertTemp function is quite simple. When the user clicks the "convert" button, the program reads the input field value as a Number, and writes the converted value into the result label field.

To add mouse actions, we use the UIMouseEvent class:

[as]import org.flashapi.swing.event.*; [/as]

The event model of SPAS 3.0 is exactly the same as the AS3 event model. But it is better to use the SPAS 3.0 integrated tools to manipulate events, than to use an other system. SPAS 3.0 has its own event sub-system to prevent leak of memory due to event management. That's why we use the eventCollector property of the Popup class to register the button event:

[as]eventCollector.addEvent(_btn, UIMouseEvent.CLICK, convertTemp); [/as]

When the user clicks the button, it will call the convertTemp function which is based on the algorithm described above:

[as]private function convertTemp(event:UIMouseEvent):void {
var temp:Number = Number(_input.label);
_result.label = String(temp * 1.8 + 32) + " fahrenheit";
}[/as]


Conclusion

Well, we should have a 28 lines of code class. If not, here is the complete CelsiusConverter class:

[as]package {
import org.flashapi.swing.*;
import org.flashapi.swing.event.*;
public class CelsiusConverter extends Popup {
public function CelsiusConverter() {
super("Convert Celsius to Fahrenheit", 250);
initialize();
}
private var _result:Label;
private var _input:TextInput;
private function initialize():void {
autoHeight = true;
padding = horizontalGap = verticalGap = 10;
_input = new TextInput("0");
_input.maxChars = 5;
_input.restrict = "0-9";
_result = new Label("fahrenheit");
var _btn = new Button("Convert", _input.width);
var celsiusLabel:Label = new Label("celsius");
addGraphicElements(_input, celsiusLabel, _btn, _result);
eventCollector.addEvent(_btn, UIMouseEvent.CLICK, convertTemp);
}
private function convertTemp(event:UIMouseEvent):void {
var temp:Number = Number(_input.label);
_result.label = String(temp * 1.8 + 32) + " fahrenheit";
}
}
} [/as]

Let's see how to use our widget directly from the Flash CS3 main timeline.
When you use SPAS 3.0 from Flash IDE instead of the Application class (org.flashapi.swing.Application) you must declare the Stage instance. (This is a consequence of the impossibility to access to a global reference of the Stage instance in Actionscript 3.0.) Said like that, this could seem complex. But it's not! Indeed, you just have to put the following lines on the first frame of the main timeline:

[as]import org.flashapi.swing.*;
UIManager.initialize(this); [/as]

Once you have done that, you can easily create and display the CelsiusConverter object, and even use SPAS 3.0 built-in effects such as shadow or reflection:

[as]import org.flashapi.swing.*;
UIManager.initialize(this);

var cc:CelsiusConverter = new CelsiusConverter();
cc.shadow = cc.reflection = true;
cc.display();[/as]

Ok! It's finished; just compile the FLA to see the result!

I hope you've enjoyed this tutorial. You can find more resources and tutorials on the SPAS 3.0 Web site at: http://www.flashapi.org/


Addenda (12/20/2008)
For ones of you who want to get the same visual result as the example in this tutorial with the alpha 1.0 release, here is a version of the CelsiusConverter class that uses the "SPAS" look and Feel:

[as]package {
import org.flashapi.swing.*;
import org.flashapi.swing.event.*;
import org.flashapi.swing.plaf.spas.*;
public class CelsiusConverter extends Popup {
public function CelsiusConverter() {
super("Convert Celsius to Fahrenheit", 250);
initialize();
}
private var _result:Label;
private var _input:TextInput;
private function initialize():void {
setLaf(SpasWindowUI);
autoHeight = true;
padding = horizontalGap = verticalGap = 10;
_input = new TextInput("0");
_input.maxChars = 5;
_input.restrict = "0-9";
_result = new Label("fahrenheit");
var _btn = new Button("Convert", _input.width);
_btn.setLaf(SpasButtonUI);
var celsiusLabel:Label = new Label("celsius");
addGraphicElements(_input, celsiusLabel, _btn, _result);
eventCollector.addEvent(_btn, UIMouseEvent.CLICK, convertTemp);
}
private function convertTemp(event:UIMouseEvent):void {
var temp:Number = Number(_input.label);
_result.label = String(temp * 1.8 + 32) + " fahrenheit";
}
}
}[/as]