Macromedia Flex is a presentation server that developers are using to build a new generation of Rich Internet Applications (RIAs). Rich Internet Applications combine the usability of desktop applications with the administrative advantages of the web.
Flex is a presentation server installed on top of a J2EE application server or servlet container, a rich library of user interface components, an XML-based markup language used to declaratively lay out these components, and an object-oriented programming language which handles user interactions with the application. The result is a Rich Internet Application rendered using Flash Player and developed using industry standards and a development paradigm familiar to developers.
This article focuses on the key aspects of the Flex language.
To run the code in this article, you may want to try installing Flex. Flex runs on top of a J2EE Application Server such as Macromedia JRun, IBM Websphere, BEA WebLogic, or Apache Tomcat. In the future, Flex will also run on top of Microsoft .NET server.
The Flex language capitalizes on the strengths of two popular development paradigms: markup languages and object-oriented programming languages.
Markup languages have proven successful and relatively easy at laying out application user interfaces. MXML, the XML-based markup language introduced with Flex, builds on this success. You use MXML, much like HTML, to declaratively lay out the user interface of your application. As an XML-based markup language, MXML has a more structured and less ambiguous syntax than HTML. MXML also includes a much richer set of tags than HTML. For example, DataGrid, Tree, TabNavigator, Accordion, and Menu are all part of the standard set of tags. You can also extend the MXML tags and create your own components. But the most significant difference is that MXML-defined user interfaces are rendered by Flash Player, providing the users with a much more engaging experience than traditional HTML-based, page-centric web applications.
In addition to laying out visual components, you can also use MXML to define other important aspects of your applications: For example, you can declaratively define your application as a client for a web service, or define animations that provide the user with visual cues about the state transitions in your application.
Markup languages are inadequate, however, to provide the programmatic logic to respond to the user interactions with your application. In Flex, you do this by coding event handlers using the ActionScript programming language. ActionScript is based on the ECMA-262 standard, and is a strongly typed object-oriented language that will feel immediately familiar to those of you coding in languages like Java or C#.
In summary, when you write a Flex application, you use a combination of MXML to declaratively set up the user interface and ActionScript to provide the logic to respond to user interactions.
Depending on your preferences as a developer, you can either hand code MXML using your favorite IDE (such as Eclipse or Intellij), or use the WYSIWYG development environment that is available for Flex (code-named Brady). If you choose to hand code MXML, you can use the XML schema provided with Flex to take advantage of code hinting and code completion features of your IDE.
The following example shows the source code for a simple Flex application, named HelloWorld.mxml. The application has two TextInput components. When you click Copy, the content of the source TextInput appears in the destination TextInput field. This example shows how you combine MXML and ActionScript to produce the application: You define the user interface declaratively using MXML and write the copy logic in ActionScript in the click event handler for the Button component.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:TextInput id="source" width="100"/>
<mx:Button label="Copy" click="destination.text=source.text"/>
<mx:TextInput id="destination" width="100"/>
</mx:Application>
Figure 1. Text moves from the source to the destination TextInput in this simple HelloWorld application
To develop and deploy this application, you would typically use the following steps:
The first time a user requests HelloWorld.mxml, the server compiles the MXML code into Flash bytecode (a SWF file). The server then sends the generated SWF file to the client where it executes in Flash Player. Subsequent requests to the same MXML document bypass the compilation process
If you are familiar with JavaServer Pages, this model is extremely similar. MXML files are compiled into Flash bytecode just like JSPs are compiled into Java bytecode (servlets). The major difference is that with Flex, the generated bytecode executes on the client, whereas the Java bytecode (the servlet) generated from a JSP executes on the server. With Flex services, you can seamlessly integrate your rich client application with your existing business and data access logic.
Flex features an extensive set of user interface components. In addition to traditional data input controls (TextInput, TextArea, CheckBox, RadioButton, ComboBox, and so forth), MXML includes advanced components to manipulate structured data (Tree component) and large data sets (DataGrid component). Flex also provides you with navigation components to clearly organize information and processes (TabNavigator, ViewStack, Accordion, and so forth).
To help you assemble the user interface, Flex containers define layout management policies that specify how components are positioned relative to each other. The Flex component library provides a wide variety of containers implementing different layout policies. For example, components in an HBox are aligned horizontally, components in a VBox are aligned vertically, and components in a Grid are arranged in rows and columns, much like in an HTML table. The Canvas container doesn't define any layout management policy; within it, you can use absolute positioning by providing an x and y coordinate.
The following example shows a traditional three-pane e-mail interface built with Flex. An HBox horizontally aligns the Tree and a VBox, which vertically aligns the DataGrid and the TextArea.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:HBox>
<mx:Tree/>
<mx:VBox>
<mx:DataGrid/>
<mx:TextArea/>
</mx:VBox>
</mx:HBox>
</mx:Application>
Figure 2. An e-mail application built with Flex
The Flex language is event driven. MXML exposes events as tag attributes
where you can write ActionScript event handlers. For example, the Button
component has a click attribute, the ComboBox, List, and
Tree components have a change attribute, and so forth.
For simple interactions, you can write an ActionScript statement directly in the tag attribute for the event. For example, in the HelloWorld application, the ActionScript statement that copies the content of the source TextInput to the destination TextInput is in the button's click event handler.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:TextInput id="source" width="100"/>
<mx:Button label="Copy" click="destination.text=source.text"/>
<mx:TextInput id="destination" width="100"/>
</mx:Application>When the logic is more complex, you can define a separate ActionScript function and call that function from the component event handler. For example, you could rewrite the HelloWorld application as follows:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:Script>
function copy() {
destination.text=source.text
}
</mx:Script>
<mx:TextInput id="source" width="100"/>
<mx:Button label="Copy" click="copy()"/>
<mx:TextInput id="destination" width="100"/>
</mx:Application>
When you create an MXML document, you actually create a class. ActionScript
functions you define in the <mx:Script> tag are
methods of that class. You can define ActionScript functions inside
the MXML document or in a separate file. Depending on your organization,
the last option can promote a better separation of tasks in your
development team.
With Flex, you can create your own components from scratch or extend existing components in the Flex component library. You create components much like you create applications: You combine MXML to declaratively lay out the user interface of your component with ActionScript to provide the user interface logic.
The following example shows a simple credit card chooser component created by extending the VBox class:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:RadioButton groupName="card" id="americanExpress"
label="American Express" selected="true"/>
<mx:RadioButton groupName="card" id="masterCard" label="MasterCard"/>
<mx:RadioButton groupName="card" id="visa" label="Visa"/>
</mx:VBox>The component has the name of its source file. For example, if you name the source file CreditCardChooser.mxml, the component name is CreditCardChooser, and a tag with the same name is automatically available. The following example shows a Flex application using the CreditCardChooser component:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" xmlns="*"> <mx:Label text="Select a credit card:"/> <CreditCardChooser/> </mx:Application>
Figure 3. The CreditCardChooser application
Designers can also build sophisticated visual components as SWC files in the Macromedia Flash development environment.
Alternatively, you can define components entirely in ActionScript. You typically use this approach to create faceless components in your application. You can use faceless components for business objects (for example, an object that encapsulates the client-side logic for a shopping cart), or for helper classes in your application.
Macromedia developed Flex to operate in a service-oriented architecture (SOA). In this model, an application completes its task by interoperating with decentralized services available from different sources. For example, if you build an online travel application, you might need to interact with different services: a global reservation system, a destination information service, a weather service, and so forth. These services will likely be available from different sources through different mechanisms. Flex allows you to aggregate information at the client side and offers three different data service components to accommodate the specific data access requirements of the service provider: the WebService component, the HTTPService component (typically used for XML over HTTP data access), and the RemoteObject component. MXML allows you to declaratively set up connections to services using the corresponding WebService, HTTPService, and RemoteObject tags.
In many languages, displaying back-end data in user interface controls can be code intensive and error prone. Collecting data entered by the user in user interface controls and passing the information to remote services is often an even more tedious task.
Flex features a codeless bidirectional data-binding mechanism: you can bind user interface controls to data resulting from a service invocation and, conversely, you can bind service parameters to values entered in user interface controls.
The following example shows a simple stock quote application. You use the WebService tag to declaratively set up a connection to the sample stock quote web service provided by XMethods. This example demonstrates the two-way binding capability of Flex:
getQuote method is bound to the symbol TextInput.quote Label is bound to the result of the getQuote method invocation.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:WebService id="wsStock"
wsdl="http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl">
<mx:operation name="getQuote">
<mx:request>
<symbol>{symbol.text}</symbol>
</mx:request>
</mx:operation>
</mx:WebService>
<mx:Label text="Enter a symbol:"/>
<mx:HBox>
<mx:TextInput id="symbol"/>
<mx:Button label="Get Quote" click='wsStock.getQuote.send()'/>
</mx:HBox>
<mx:Label id="quote" fontWeight="bold" text="{wsStock.getQuote.result}"/>
</mx:Application>
Figure 4. The stock quote application
In fact, the Flex data binding mechanism transcends the traditional retrieve/display scenario: You can bind any property of any object to the value of any other property of any other object in a Flex application.
Flex adopted the cascading style sheet (CSS) standard to help ensure the consistency of your user interface and to facilitate the maintenance of your applications. Much like in HTML, you can inline a style sheet in your code, point to an external style sheet, or define a style as an attribute of a specific element. Style sheets also allow you to define fonts for your applications. The required font definition is embedded in the bytecode of your application to ensure that the font is rendered correctly even if it is not available on a user's machine.
The following code shows an external style sheet saved as main.css.
@font-face {
src: url("LucidaSansRegular.ttf");
font-family: mainFont;
}
.error {
color: #FF0000;
font-size: 12;
}
.title {
font-family: mainFontBold;
font-size: 18;
}
TextArea {
backgroundColor: #EEF5EE;
}The following application declares the external style sheet using the <mx:style> tag, and applies different styles to specific controls.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:Style source="main.css"/>
<mx:Label styleName="error" text="This is an error"/>
<mx:Label styleName="title" text="This is a title"/>
<mx:TextArea width="200" height="100" wordWrap="true" text="This is a TextArea"/>
</mx:Application>
Figure 5. Application using an external stylesheet
Rich Internet Applications are often compared to client/server applications because they provide the same level of user experience. An often underestimated difference, however, is the nature of their respective user constituency. The user of a client/server application is generally a trained employee who eventually gets used to the user interface, even if it is poorly designed. The user of a Rich Internet Application is typically an occasional or one-time user. In this context, a user interface that is not self-explanatory and not intuitive leads to lost opportunities.
Using effects properly can help you provide users with cues about the current context of the application and its state transitions. With MXML, you can declaratively set up animations.
The following example uses prebuilt effects from the Flex library of behaviors. The example applies the WipeRight effect when the square component appears and applies the WipeLeft effect when it disappears.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:Canvas id="square" width="100" height="100" backgroundColor="#666699"
showEffect="WipeRight" hideEffect="WipeLeft"/>
<mx:HBox>
<mx:Button label="Display" click="square.visible=true"/>
<mx:Button label="Hide" click="square.visible=false"/>
</mx:HBox>
</mx:Application>
The Flex language consists of a rich library of user interface components, MXML (an XML-based markup language), and ActionScript (an ECMA 262-based, strongly-typed and object-oriented programming language). You use MXML to declaratively set up the user interface and other aspects of your application and ActionScript to provide the logic which handles user interactions with the application. Flex enables developers to build large-scale applications that leverage the Flash platform. Developers can build these applications using industry standards (such as XML, CSS, and SVG), and development paradigms and patterns they are accustomed to. The Flex partitioned approach and the Macromedia common component model also allow developers and designers to work together to produce applications that combine a breakthrough user experience with a solid and maintainable architecture.