Getting UI to work in ActionScript 3/Flex

If you're just getting started with ActionScript 3 programming, you may be confused how to access all those cool User Interface widgets that you can access from the Flex MXML stuff.

Step 1: Create your main class by extending Canvas

What you need to do here is to extend the MX Canvas to use the UI stuff, not Sprite. One of the drawbacks of this however is that you will not be able to use things like TextField anymore but hey there are better things you can use now.
import mx.containers.Canvas;
import mx.controls.Button;
import flash.events.MouseEvent;

public class App extends Canvas {

	private var button:Button;
	
	public function App() {
		button = new Button();
		button.label = "I'm a Button!";
		button.addEventListener(MouseEvent.CLICK, click);
		addChild(button);
	}
	
	private function click(evt:MouseEvent):void {
		removeChild(button);
	}
}
The Canvas class is infact derived from UIComponent from FlexSprite from Sprite so you can do everything Sprite does but you also have the functionality of Flex with UI on your side as well. You may notice in your code that width = 0 and height = 0 for the App class. To get the actual width of the Canvas, use parent.width and parent.height instead.

Let's look at a more complicated example
private var button1:Button;
private var button2:Button;
private var panel:Panel;
private var buttonLayout:LayoutContainer;
private var testlabel:Label;

public function App() {
	button1 = new Button();
	button1.label = "Continue";
	button1.addEventListener(MouseEvent.CLICK, continueClick);
	button2 = new Button();
	button2.label = "Exit";
	button2.addEventListener(MouseEvent.CLICK, exitClick);
	
	buttonLayout = new LayoutContainer(); // so we can layout the buttons how we want
	buttonLayout.layout = "horizontal";
	buttonLayout.addChild(button1);
	buttonLayout.addChild(button2);
	
	testlabel= new Label();
	testlabel.text= "What do you want to do?";
	testlabel.styleName= "SpecialLabelStyle";  // override default Label styling here
	
	panel= new Panel();
	panel.addChild(testlabel);
	panel.addChild(buttonLayout);
	
	addChild(panel);
}

private function continueClick(evt:MouseEvent):void {		
	var alert:Alert = new Alert();
	alert.text = "Continue Pressed";
	addChild(alert);
}

private function exitClick(evt:MouseEvent):void {		
	var alert:Alert = new Alert();
	alert.text = "Exit Pressed";
	addChild(alert);
}	
Yes embedding objects into each other is as easy as making a container object and adding the objects to the container. You can control how the alignment works with the stylesheet and also with a LayoutContainer object. The styleName property says that we want to override the normal style used for the widget which we will see in a bit.

Step 2: Create a CSS file to style your UI widgets

There are infact ways to style your UI widgets in code directly (widget.setStyle("property", value);) but it is frowned upon because it takes a lot of resources to do; using stylesheets is a much better and cleaner way to go.
Button
{
	fillColors: #000000, #707070;
	color: #ffffff;
	textRollOverColor: #0000ff; 
	themeColor: #00007f;
}

.SpecialLabelStyle
{
	color: #ff0000;
}
Here we tell the UI the default style to use for every Button object it renders. We are also overriding the behavior of one specific instance of a Label object with this special CSS block. The coolest part is that the CSS file will actually be compiled into your SWF file and optimized so you won't need to include it in your distribution. You may have noticed that the style properties are not the same as HTML styles; Flex defines the complete set of valid styles for each UI widget in the AS3/Flex documentation (look in mx.controls and mx.containers).

Step 3: Set up your MXML correctly

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" styleName="plain" xmlns:MyApp="*">
	<mx:Style source="style.css"/>
	<MyApp:App/>
</mx:Application>
Here we are saying that we want to associate our stylesheet with this SWF project and then instatiating our App class which is the main Canvas to render to. The downside to using Flex's powerful UI capabilities is that it will add significant size to your SWF file although you do get added bonuses by using AS3 instead of MXML: the ability to draw custom graphics (via each widges' and the main Canvas's graphics member variable) ontop of rendering the UI widgets.


Addendum: You may be confused as to why you can't add a Sprite to the Canvas as you normally do with addChild(sprite). If you are using any Flex derived UI object like Canvas to draw to, you need to use rawChildren.addChild(sprite) instead.

6 Comments
Ram
Nice demonstration of how to instantiate controls using ActionScript. Thanks!
Will
In FlashDevelop, make sure to right click on your Main.mxml file and set it to 'Always Compile' for this to work.  Otherwise you will not see anything on the screen.
Amar Shukla
Nice and simple example to make newbies understand about how to work with coding to make GUI.
;'"
Your Name
;"'
Your Name
;'"Warning: fopen(../spam.txt) [function.fopen]: failed to open stream: Permission denied in /var/www/willperone/wrapper.inc.php on line 132