Today, I am going to show you how to create your own ActionScript Flex Components.
Creating Flex components is very easy, but you must know some things about the Flex Component Framework.
Bitmap Caching
The graphical performance of the Flash Player gets improved thanks to the bitmap caching feature. It enables the Flash Player to render the visual elements just when needed. If a visual element doesn’t change during the execution of the application, a bitmap representation of that element will be shown in every frame instead of rendering it once and again. Only the visual elements marked as “dirty” will be redrawn.
More information on Bitmap Caching here.
Graphic Primitives
When developing custom Flex Components, we will make intense use of graphic primitives. In a future post, I will talk about creating skinnable components, and it will allow us not to draw programatically, but using assets.
We will build a very simple blackboard component. We will achieve this:
We are going to create two actionscript components:
- BlackboardShape: it respresents every independent shape a user draws. It is made of different points connected with lines.
- Blackboard: the canvas where the users draws. It does all the event catching work.
First of all, we will focus on the BlackboardShape, wich is a very simple Flex component.
This is the source code for that component:
package comp
{
import comp.common.BlackboardPoint;
import flash.filters.BevelFilter;
import mx.core.UIComponent;
public class BlackboardShape extends UIComponent
{
private var pointArray : Array;
private var color : Number;
public function BlackboardShape()
{
super();
pointArray = new Array ();
color = Math.random() * 0xFFFFFF; // This sets the color. We choose a random color.
this.filters = [new BevelFilter ()]; // This adds a bevel filter to the shape wich will
// add that "ketchup" look
}
// Add a new point to the shape
public function addPoint (x : Number, y : Number) : void {
pointArray.push (new BlackboardPoint (x, y, false));
// There is a new Point, so the shape must be redrawn. We call invalidateDisplayList, so
// the framework will call updateDisplayList at the right time
// in order to draw the next frame
invalidateDisplayList();
}
// This method updates the visualization of the component.
// You should NEVER call this method directly.
// If you have to update the visualization of your component, call invalidateDisplayList ()
// instead and the Flex Component Framework will call updateDisplayList for you at right time.
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
var previousPoint : BlackboardPoint = new BlackboardPoint (0, 0, true);
var point : BlackboardPoint;
this.graphics.lineStyle(15, color);
// We process every point in the shape.
// We use graphic primitives to draw lines between the points
for each (point in pointArray) {
if (!point.processed) {
if (previousPoint) {
this.graphics.moveTo(previousPoint.x, previousPoint.y);
}
this.graphics.lineTo(point.x, point.y);
point.processed = true;
}
previousPoint = point;
}
}
}
}
There is a public method addPoint that will be used by the Blackboard component when capturing mouse events. If you read that code you will see there are no graphic instructions: we only add a record to our Point Array. The pointArray property stores the points that define the shape. At the end of the method, we call invalidateDisplayList to notify that this component is dirty and it has to be redrawn.
At the right time, the framework will attempt to refresh every “dirty” component by calling the updateDisplayList Method. We will add all the graphical logic here. In this example, we just iterate the points and draw lines between them. Note that a lot of optimizations could be added to this code but its easier to understand keeping it simple.
Now we will create a test Flex Application for this component to see it running:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="center" verticalAlign="middle" xmlns:comp="comp.*"> <comp:BlackboardShape id="shape" width="200" height="200"/> <mx:Button label="Draw!" click="shape.addPoint(Math.random() * 200, Math.random()*200)"/> </mx:Application>
It should work like this:
In my next post, I will show you the Blackboard component.
September 12th, 2008 at 6:31 pm
[...] Source [...]
October 16th, 2008 at 12:26 pm
[...] the blackboard component will hold some instances of the BlackboardShape component we built in the previous part of this tutorial. You can see the whole example working here. Press right button -> View Source [...]