In my earlier article on components, I didn't use libraries. But library components are the best way to share code between projects, so the examples in this article will utilize reusable library components.
I've found the coverage on the creation of libraries in books and documentation to be spotty and scattered, so it's important to describe it thoroughly before we get into collections.
If you're a Java programmer, aspects of the library-creation process will be familiar. Each component lives in a namespace, and we want namespaces to be unique (to prevent collisions), so Flex follows the Java practice of beginning the namespace with the reversed URL of the individual or company creating the library. So in my case, my namespace will begin with com.mindviewinc.
You can have multiple components within one namespace, so it makes sense to group them according to functionality. In this article I create three different types of components which I classify as display, format, and functional, so their full namespaces will be com.mindviewinc.display, com.mindviewinc.format, and com.mindviewinc.functional.
Also like Java, the library directory structure must correspond to the namespace, so library components within the com.mindviewinc.display namespace must be placed in the directory com/mindviewinc/display. Mercifully, however, Java's classpath has not been inflicted upon ActionScript programmers; on the contrary, Flex Builder tends to be helpful when you are including libraries. Also, a Flex project typically compiles to a single SWF so installation is a matter of copying the SWF (usually onto your web site).
The final similarity to Java is in the library's component files: each file can have only one public element (class or function). That way, each file only exposes that one element. Note that I didn't find this out through reading; Flex Builder told me when I tried to put more than one public element in a single file.
In Flex Builder, select File | New | Flex Library Project. It doesn't matter what you name your library (that is, you're not constrained by any of the aforementioned rules). I just called mine "Mindview." Right-click (or your machine's equivalent) on the "Mindview" folder, create a directory called "com," and beneath that create "mindviewinc," and beneath that create "display," "format," and "functional." The full directory structure for the library (including the bin directory added by Flex Builder, and things we will add later) looks like this:
Mindview
+ bin
+ com
+ mindviewinc
+ display
+ format
+ functional
+ test
+ includes
Let's create a first library component; although it's simple it turns out to be useful in this article. It is a small modification to the TextArea and it simplifies the display of information.
To create it, right-click on the display folder and select New | ActionScript Class. Call the class TextDisplay. Note that you're not given the option of naming the file; the file name is the same as the class name. You can also tell it what base class to inherit from. Flex Builder knows what package name to use because of the folder you're placing it in.
Here's what the component looks like after the rest of the code has been filled in:
package com.mindviewinc.display {
import mx.controls.TextArea
public class TextDisplay extends TextArea {
public function TextDisplay() {
super()
percentHeight = 100
percentWidth = 100
}
public function show(s:* = "", delim:String = "\n"):void {
text += String(s) + delim
}
}
}
Like Python, Ruby and Groovy, semicolons at the end of lines are optional. The compiler treats the end of a line as the end of a statement unless it's inside a parenthesized expression. The only time you are required to use a semicolon is when you have more than one statement on a single line, or an empty expression.
If you've seen JavaScript or ActionScript code before, you'll note that typical code often makes heavy use of the this keyword. It turns out this use is redundant; like Java and C++, this is only necessary in special cases and the compiler will automatically scope to this. As I am a minimalist when it comes to code syntax, I will tend to leave off both redundant semicolons and redundant usages of this.
The constructor sets the component to full width and height, and the method simplifies the act of displaying text. Note that ActionScript supports default function arguments, which I find very convenient.
Note that show() has an asterisk for the argument type; this means "any type." You actually get any type if you don't specify a type, but then the compiler gives you a warning. The asterisk for the type tells the compiler that you intend this to be of any type. This way, show() can accept anything, then cast it to a String for printing.
For testing, create a little Flex application that uses the component. Select File | New | Flex Project, give it a name and press the "next" button. Press "next" again and press the "Library path" button and then "Add Project." The "Mindview" library should appear as an option; select that. Press "Finish." Now if you start typing "<Text", Flex Builder should provide "TextDisplay" as a completion option, and when you select that it puts in the necessary namespace field:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application name="TestTextDisplay" xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:display="com.mindviewinc.display.*" >
<display:TextDisplay id="t"/>
<mx:creationComplete>
t.show("hello", ", ")
t.show("world")
</mx:creationComplete>
</mx:Application>
I'm taking slight liberties with the name property of the Application to note the name of this MXML file. However, name is generally used for child components so this shouldn't cause any problems.
The creationComplete block is just like a Script block, except that it also defines an event handler -- in this case, the creationComplete event which is fired when the application is finished initializing. Using a creationComplete block is a convenient way to experiment with ActionScript code inside Flex Builder. Note also that the CDATA tags are only necessary when the script block contains special characters.
Although the new component doesn't do much, it helps a little, and often that's all the value you need. In this article it simplifies the code enough to be worth it.
Note that you aren't limited to adding libraries only when creating the project. At any time you can right-click on the project in Flex Builder and add new libraries.