Chapter 4. Using Source Mode

IN THIS CHAPTER

What Design Mode Does

Anatomy of a Flex Application

Adding Components in Source Mode

Code Completion

MXML in Depth

S, FX, and MX: Namespaces Explained

Summary

“The whole is greater than the sum of its parts.”

Aristotle

When we created the HelloWorld application, Flash Builder automatically generated several lines of MXML code. In this chapter, we use Source mode to examine our HelloWorld application and glean some additional insight into the structure of a Flex project. We also use Source mode to add a few more components and get a feel for Flash Builder’s code completion mechanism and MXML syntax.

What Design Mode Does

As previously stated, when you drag components into your Flex 4 project, Flash Builder creates corresponding MXML code in whatever MXML file you’re currently editing. Conversely, if you alter the MXML code in Source mode, Design mode will rebuild and reflect the changes. Let’s take a look at the MXML for our HelloWorld application.

If you closed Flash Builder since creating HelloWorld in Chapter 3, reopen it and switch to Source mode. It’s easy to switch from Design mode to Source mode; just click the “Source” button above your WYSIWYG editor (Figure 4-1).

Switching to Source mode
Figure 4-1. Switching to Source mode

Note

Whether you’re using Windows or Mac OS, you can quickly switch between Design mode and Source mode using the keyboard shortcut Ctrl-tilde (~).

Anatomy of a Flex Application

Your source code for this example should look something like that in Example 4-1.

Note

Code created by Design mode has a tendency to be ugly. On another note, due to limitations of print/page dimensions, it’s impossible to identically replicate the code you’re seeing in print. As a result, expect our book examples to differ from yours somewhat.

Example 4-1. The MXML code autogenerated by Design mode
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
            xmlns:s="library://ns.adobe.com/flex/spark"
            xmlns:mx="library://ns.adobe.com/flex/mx" width="100%"
              height="100%">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects)
            here -->
    </fx:Declarations>
    <s:Label x="50" y="50" text="My First Flex 4 Application"
    id="titleLabel"
    fontFamily="Arial" fontWeight="bold"/>
    <s:HGroup x="50" y="70" width="80%">
        <s:Button label="Say Something" id="speakButton"/>
        <s:TextInput id="speakTI" width="100%"/>
    </s:HGroup>
</s:Application>

Code created by Design mode is usually jumbled and messy. As a result, our source code could use some housecleaning. Before we break apart the code and discuss it, let’s clean up the code here in Source mode. Using extra line breaks and tab indents, make your Source code look more like Example 4-2.

Note

Notice that we deleted the Declarations block? This block will always appear in a new project, so if you won’t need it—and we won’t need it for a while—you can delete it to create cleaner code. Of course, it won’t hurt to leave it. It’s your decision.

Example 4-2. Our clean MXML code after reformatting it in Source mode
<?xml version="1.0" encoding="utf-8"?>
<s:Application
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    width="100%" height="100%">

    <s:Label id="titleLabel" x="50" y="50"
        fontFamily="Arial" fontWeight="bold"
        text="My First Flex 4 Application"/>

    <s:HGroup x="50" y="70" width="80%">
        <s:Button id="speakButton" label="Say Something"/>
        <s:TextInput id="speakTI" width="100%"/>
    </s:HGroup>

</s:Application>

Now that we can comfortably read the code, let’s consider what’s happening. The first line is a mere XML declaration that usually begin XML files. It has no functional purpose in the code, but Flash Builder will always add it to new application files. The “real Flex” begins with the Spark Application tag.

Every Flex application contains a root tag. Flex applications geared for web deployment will use an Application tag, but Adobe AIR applications designed for the desktop will use a WindowedApplication tag. Our HelloWorld application is designed for the Web; therefore, the entire project exists between <s:Application> and </s:Application>, the opening and closing tags of the Flex Application container.

Notice that the opening tag includes an ensemble of attributes, specifically several namespace assignments (i.e., xmlns:), as well as the width and height properties we established back in Design mode. The opening tag for every component exists between left (<) and right (>) angle brackets.

The Declarations section (which you may have deleted per the note) is identified by the <fx:Declarations> and </fx:Declarations> tags, and it’s reserved for nonvisual elements. We briefly discussed nonvisual elements in Chapter 3. Even though this application doesn’t have any nonvisual elements, Flash Builder creates the Declarations section anyway.

The <s:Label/>, <s:HGroup/>, <s:Button/>, and <s:TextInput/> tags represent components we added in Design mode. The Label and the HGroup container are nested within the main application, but the Button and the TextInput are nested within the HGroup.

The Label, Button, and TextInput controls are closed differently than the Application and HGroup containers. Closing XML tags using /> is an optional syntax, but it’s frequently used for controls. Alternatively, you could open and close the Button using the code shown in Example 4-3.

Example 4-3. A Button created with optional syntax
<s:Button id="speakButton" label="Say Something"></s:Button>

However, using the full syntax on controls has a tendency to make your code less readable. Fortunately, Flash Builder will encourage the abbreviated syntax by using it for controls created in Design mode.

As you inspect the remaining MXML code, you should recognize other properties we set back in Design mode. While you’re here, feel free to change some of the basic properties (x, y, width, height, text), and then leap back into Design mode (Ctrl-tilde) to see the changes take effect.

Adding Components in Source Mode

Of course, we can also add components to our project while in Source mode, so let’s add another button to perform a “clearing” function.

Just below the TextInput but still within the HGroup tag, add a Button component by typing <s:Button id="clearButton" label="Clear"/>. In context, it should look like Example 4-4.

Example 4-4. Adding a Button in Source mode
<s:HGroup x="50" y="70" width="80%">
    <s:Button id="speakButton" label="Say Something"/>
    <s:TextInput id="speakTI" width="100%"/>
    <s:Button id="clearButton" label="Clear"/>
</s:HGroup>

If you switch back to Design mode, you’ll notice the TextInput control sandwiched between the “Say Something” and “Clear” buttons. The HGroup container is forcing the three controls to consume the 80% width allotted to it.

For the sake of playing around, convert both HGroup tags to VGroup tags (literally replace the “H” in each tag with a “V”), and then jump back to Design mode to see how this change affected the layout of your application (Figure 4-2). You can keep the layout in this arrangement if you want, but our example will continue using the HGroup.

HelloWorld using HGroup and VGroup, respectively
HelloWorld using HGroup and VGroup, respectively
Figure 4-2. HelloWorld using HGroup and VGroup, respectively

Code Completion

When you created the button in Source mode, did you notice a pop up after you started entering the code for the control? Perhaps it looked like Figure 4-3.

Flash Builder’s code completion utility
Figure 4-3. Flash Builder’s code completion utility

Code completion is your best friend when you’re new to a programming language. Not only does code completion help you avoid typos and spelling errors, it can also be a useful reference. Consider this: in Design mode’s Properties pane, you can toggle Category or Alphabetical view to see properties available to a component. Similarly, Source mode’s code completion allows you to browse a control’s properties and methods, but it also allows you to browse components, classes, data types, objects, etc. If you’re trying to brainstorm a solution to a programming task, sometimes it’s helpful to trigger code completion just to peruse the menu. You never know; it just may trigger some inspiration.

Code hinting will attempt to offer you the best reasonable match to the text you’ve entered into the code editor, and it will begin making suggestions alphabetically as soon as you create the left angle bracket (<).

Note

Code completion is a rose with many names: code hinting, content assist, autocomplete, and autocompletion, to name a few. Developers with a lot of experience using Microsoft’s Visual Studio might even call it IntelliSense. This is important because you’ll encounter these various terms in the blogosphere.

If you’re looking for a specific component, type as much of the component declaration as you find convenient (e.g., “<s:tex”); then, once you get the content assist utility, either left-click on the component you want or hit Tab to change focus to the code completion pop up. Once the code hinting utility has focus, use your arrow keys to scroll through the menu. Even better, if you typed enough text for code completion to zero in on the correct component, simply press Tab and then Enter to select it and plug it into your code. That declares your class.

After you’ve declared a class, use code completion to configure its properties and methods. So, if you just declared a new instance of the TextInput using code completion, you’ll have <s:TextInput, with your insert cursor against the last character. But once you hit your space bar, you’ll get a host of properties and methods to choose from.

Note

As you become more familiar with Flex components, you may type fast enough that the code hinting doesn’t appear. If this happens, or if you did something to lose the utility, use a keyboard shortcut to get it back. In Windows, it’s Ctrl-spacebar, and in Mac OS it’s Command-Shift-spacebar.

MXML in Depth

Metaphorically, think of MXML as the skeleton within the body of your source code. Just as skeletons provide structural definition to our human bodies, MXML code gives your project a visible structure.

You’ll quickly adapt to MXML syntax because it’s so intuitive, but a few details should be covered now to guide your thinking.

The XML in MXML

XML stands for Extensible Markup Language. Extensible refers to the capacity to create your own tag relationships. Markup means your tags can include text as well as extra information about that text, also via tags. Remember, tags are identified by their <opening> and </closing> syntax.

XML is not a programming language. Rather, XML is a structured arrangement of text and data. There are no keywords, component classes, class properties, or methods. It’s simply textual information presented according to specific syntax rules that identify a hierarchy or relationship between the elements. So how do XML and MXML compare?

MXML borrows its syntax rules from XML. However, to the Flex compiler, MXML identifies ready-made ActionScript classes that can be instanced using XML syntax. In this way, MXML is essentially a class vocabulary that provides a more convenient approach to declaring ActionScript UI components.

It’s All About Structure

As we just discussed, XML is simply structured text. It distinguishes data structures within tags defined by angle brackets (< and >). There isn’t an XML vocabulary of reserved words; in fact, the author of XML is free to create her own structural hierarchy. So, XML is purely syntax and structure.

You’re reading a book right now, so you recognize that a book is divided into chapters and sections. If you wanted to represent a book in XML, you could create tags like <book/>, <chapter/>, and <section/>, and deploy the book like Example 4-5.

Example 4-5. Empty XML demonstrating structural hierarchy
<book>
    <chapter>
        <section/>
    </chapter>
</book>

As implied by this example XML, “book”—the root node—contains “chapter” nodes, which contain “section” nodes.

A Few Ground Rules

XML parsers, including Flash Builder, web browsers, etc., are unforgiving when it comes to XML syntax. While you can invent whatever tags and data structure you desire, you can’t invent your own syntax rules. So let’s discuss the basics of XML syntax.

All that is opened must be closed

An important fact about XML is that each tag must be complete. If a tag is opened, it must eventually be closed later in the XML. As you’ve seen, an XML tag is opened with a left bracket (<), some text representing the tag’s name, and then a right bracket (>). To maintain our previous example, <book> is an opening tag. Finishing the tag requires closing it using a forward slash (/) in the proper position within the closing tag, </book>.

You can ensure all tags are closed in a couple of ways. The first is by creating the end tag immediately after you create a beginning tag. So, after creating the open container tag <book>, go ahead and create the closing tag </book>. Alternatively, if a tag will not have any nested tags—as is often the case with simple Flex controls such as the Button, CheckBox, and others—you can use shorthand syntax by adding a forward slash immediately before the right angle bracket of the opening tag, like this: <section/>. So, <section></section> is equivalent to <section/>.

Case matters

XML is case-sensitive. That is to say, uppercase letters and lowercase letters distinguish different elements. So, <book> and <Book> aren’t the same in XML. That means <s:Text> and <s:text> are different as well.

Declarations are optional, but polite

The first line of an XML document may optionally contain a line declaring it as XML and listing what encoding it uses. The declaration looks like the line in Example 4-6.

Example 4-6. An XML declaration
<?xml version="1.0" encoding="utf-8"?>

Note

Encoding in this context refers to your potential to use various characters and symbols in your XML markup. There are different encoding standards available to you, but utf-8 is the way to go. For more information, see the w3schools discussion of this topic at http://www.w3schools.com/XML/xml_encoding.asp.

All MXML files created through Flash Builder automatically contain this XML declaration, so you don’t need to worry about creating it.

Because MXML is XML, MXML inherits all the XML rules.

Warning

Make sure you don’t have any spaces, empty lines, or other whitespace before the XML declaration in a Flex application. Otherwise, Flex will warn you that whitespace is not allowed before an XML Processing Instruction and your application won’t compile!

The Anatomy of a Tag

An XML tag can contain information in two ways, either by content or by attributes. Content is simply the text that exists between the node’s opening and closing tags. Attributes are value assignments inside the opening tag. Consider the XML in Example 4-7.

Example 4-7. XML with attribute information
<book title="Learning Flex 4"
    author1="Alaric Cole" author2="Elijah Robison">

    <chapter title="Using Design Mode"/>
    <chapter title="Using Source Mode"/>
</book>

In this example, <book> is the root node, but title, author1, and author2 are attributes of that book. This code also has two nested tags representing chapters, and each has a title attribute.

Compare the previous code to Example 4-8, which contains the same information using a different structure.

Example 4-8. XML with content information between the tags
<book>
    <title>Learning Flex 4</title>
    <author1>Alaric Cole</author1>
    <author2>Elijah Robison</author2>
    <chapter3>
        <title>Using Design Mode</title>
    </chapter3>
    <chapter4>
        <title>Using Source Mode</title>
    </chapter4>
</book>

The second example is essentially the same as the first, but the second is more verbose. The first example uses attributes, and the second uses nested tags. So, attributes can be useful as a compact way to represent information, and more compact means more readable. Compare this code to the same example in MXML.

You’re probably used to seeing something like this:

<s:Label text="Learning Flex 4"/>

But did you guess you could do the following?

<s:Label>
    <s:text>Learning Flex</s:text>
</s:Label>

Those two code snippets create the same product, but one uses an attribute to add the text property, and the other uses a nested tag. We recommend using attributes in your MXML for the reasons stated earlier: compactness and readability.

There will be times, however, when you’ll need to use nested tags instead of attributes. This is because nested tags allow more complex content than a single line of text or a number. In other words, nested tags are preferable for adding data that can’t be represented as simple attributes. Consider the case of the text property. If the text were a whole paragraph, it would look strange as an inline property.

Similarly, nested tags are essential when assigning complex data properties. For example, you might use an ArrayCollection to supply data to a control, and some controls can display a long list of items. Example 4-9 shows a relevant example.

Example 4-9. An MXML ComboBox with a nested ArrayCollection
<s:ComboBox selectedIndex="0">
    <s:ArrayCollection>
        <fx:Object>Alabama, AL</fx:Object>
        <fx:Object>Alaska, AK</fx:Object>
        <fx:Object>Arizona, AZ</fx:Object>
        <fx:Object>Arkansas, AR</fx:Object>
    </s:ArrayCollection>
</s:ComboBox>

The same is true for complex components that may require an array of other component objects, such as the columns property of a DataGrid, which takes an array of DataGridColumn components, each with its own properties. You can see an example of this by dragging a DataGrid control to your application in Design mode, which gives you the MXML in Example 4-10.

Example 4-10. An MXML DataGrid with nested DataGridColumn components
<mx:DataGrid>
    <mx:columns>
        <mx:DataGridColumn headerText="Column 1" dataField="col1"/>
        <mx:DataGridColumn headerText="Column 2" dataField="col2"/>
        <mx:DataGridColumn headerText="Column 3" dataField="col3"/>
    </mx:columns>
</mx:DataGrid>

Clearly the columns property of the DataGrid can’t be written as an attribute, because it expects a complex list of DataGridColumn objects, which in turn require their own property assignments.

S, FX, and MX: Namespaces Explained

Flex 4 provides three packages of components, and each is identified by a unique namespace. The three Flex 4 namespaces are Spark (s:), Halo (mx:), and the Language (fx:) namespace.

Each MXML component tag should contain a namespace designation, like the Button tag in Example 4-11, which declares the Button component from the Spark collection.

Example 4-11. An MXML Button in the Spark (s:) namespace
<s:Button/>

The Halo collection has its own Button, as in Example 4-12.

Example 4-12. An MXML Button in the Halo (mx:) namespace
<mx:Button/>

The same syntax is used to declare components from the Language (fx:) namespace, as shown in Example 4-13.

Example 4-13. An Array declaration in the Language (fx:) namespace
<fx:Declarations>
    <fx:Array id="statesArray">
        <fx:Object>Alabama, AL</fx:Object>
        <fx:Object>Alaska, AK</fx:Object>
        <fx:Object>Arizona, AZ</fx:Object>
        <fx:Object>Arkansas, AR</fx:Object>
    </fx:Array>
</fx:Declarations>

Namespace Basics

What’s a namespace? Take a look at the word itself: name + space. Basically, a namespace is a package designation for a prebuilt set of components. You can illustrate this concept in Source mode by typing <s:Bu, and noticing that you have two Button options to choose between, as shown in Figure 4-4.

Button controls in the Spark (s:) and Halo (mx:) namespaces—the choice is yours
Figure 4-4. Button controls in the Spark (s:) and Halo (mx:) namespaces—the choice is yours

The Button class has been around for a while and continues to be important. Therefore, it exists among the new Spark components as well as the older Halo components. We recommend you use the updated Spark component, but because both packages are available within Flex 4, it’s your choice. Similarly, you could create an extension of the Spark Button that includes a few specialized properties and save it in your own package/folder. To use the extended button in your project, you’d have to assign your custom package a namespace declaration. Custom namespaces are pretty common, even among small applications.

Most simply, namespaces point to component locations within a package structure. They may identify components in precompiled libraries (SWC files), or they may represent a classpath in your project’s src folder.

If we revisit the concept of extending a Button, you could still name it “Button” because your unique namespace would distinguish it from its Spark/Halo counterparts, and the source code for your class would exist in a unique directory. You might then refer to your button in MXML as something like <tweaks:Button/> to differentiate it from <s:Button/> or <mx:Button/>.

Namespaces and Third-Party Libraries

If you work with a third-party library, code completion will add the library’s namespace definition for you as you add components from the third-party library. For example, if you download the Google Maps API (it’s a SWC) and add it to your libs folder, typing <map is enough for code hinting to lead you to <maps:Map/>, and in turn, Flash Builder will create the Google Maps namespace, as shown in Example 4-14.

Example 4-14. A third-party library with a unique namespace identifier
<s:Application
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:maps="com.google.maps.*"

But what if you don’t like that default namespace? Why not change maps to some other identifier? Well, you can.

Note

If you spend much time dabbling in third-party libraries, you’ll frequently encounter the convention com.domain.subpath.* among package structures. The technique is called reverse domain package naming, and developers endorse it for two reasons. First, and most significantly, this strategy helps to keep component packages in unique classpaths, serving the purpose of avoiding class name conflicts. Second, well, there’s a clear marketing advantage.

Note the line xmlns:maps="com.google.maps.*". This is easy to customize. For instance, instead of maps, you could use gmap, as demonstrated in Example 4-15.

Example 4-15. Changing a library’s namespace
<s:Application
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:gmap="com.google.maps.*"

This simple change lets you use <gmap:Map/> instead of <maps:Map/> in your MXML component declarations.

Summary

In this chapter we explored the basics of Source mode. You learned how to clean up autogenerated code. You also learned how to add components and assign properties with the help of code completion. We discussed basic XML syntax rules, how to read XML structure, and how these relate to MXML. Finally, we discussed namespaces, giving you an improved perception of component package structure.

In the next chapter, we discuss the basics of scripting and object-oriented programming, and along the way, we’ll finish that HelloWorld application.

Get Learning Flex 4 now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.