Working with XML in Flex 3 and Java-part2

Exclusive offer: get 50% off this eBook here
Flex 3 with Java

Flex 3 with Java — Save 50%

Develop rich internet applications quickly and easily using Adobe Flex 3, ActionScript 3.0 and integrate with a Java backend using BlazeDS 3.2

$23.99    $12.00
by Satish Kore | June 2009 | Java Open Source

In the first part of this article series by Satish Kore, we started with the basics of XML and move ahead to understand E4X completely. In this article, we will learn about loading external XML documents and also implement the concepts through an example— Building a book explorer.

 

Loading external XML documents

You can use the URLLoader class to load external data from a URL. The URLLoader class downloads data from a URL as text or binary data. In this section, we will see how to use the URLLoader class for loading external XML data into your application. You can create a URLLoader class instance and call the load() method by passing URLRequest as a parameter and register for its complete event to handle loaded data. The following code snippet shows how exactly this works:

private var xmlUrl:String = "http://www.foo.com/rssdata.xml";
private var request:URLRequest = new URLRequest(xmlUrl);
private var loader:URLLoader = new URLLoader(;
private var rssData:XML;
loader.addEventListener(Event.COMPLETE, completeHandler);
loader.load(request);
private function completeHandler(event:Event):void {
rssData = XML(loader.data);
trace(rssData);
}

Let's see one quick complete sample of loading RSS data from the Internet:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="loadData();">
<mx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
private var xmlUrl:String = "http://sessions.adobe.com/360FlexSJ2008/feed.xml";
private var request:URLRequest = new URLRequest(xmlUrl);
private var loader:URLLoader = new URLLoader(request);
[Bindable]
private var rssData:XML;
private function loadData():void {
loader.addEventListener(Event.COMPLETE, completeHandler);
loader.load(request);
}
private function completeHandler(event:Event):void {
rssData = new XML(loader.data);
}
]]>
</mx:Script>
<mx:Panel title="RSS Feed Reader" width="100%" height="100%">
<mx:DataGrid id="dgGrid" dataProvider="{rssData.channel.item}"
height="100%" width="100%">
<mx:columns>
<mx:DataGridColumn headerText="Title" dataField="title"/>
<mx:DataGridColumn headerText="Link" dataField="link"/>
<mx:DataGridColumn headerText="pubDate"
dataField="pubDate"/>
<mx:DataGridColumn headerText="Description"
dataField="description"/>
</mx:columns>
</mx:DataGrid>
<mx:TextArea width="100%" height="80"
text="{dgGrid.selectedItem.description}"/>
</mx:Panel>
</mx:Application>

In the code above, we are loading RSS feed from an external URL and displaying it in DataGrid by using data binding.

Output:

Working with XML in Flex 3 and Java-part2

An example: Building a book explorer

In this section, we will build something more complicated and interesting by using many features, including custom components, events, data binding, E4X, loading external XML data, and so on. We will build a sample books explorer, which will load a books catalog from an external XML file and allow the users to explore and view details of books. We will also build a simple shopping cart component, which will list books that a user would add to cart by clicking on the Add to cart button.

Create a new Flex project using Flex Builder. Once the project is created, create an assetsimages folder under its src folder. This folder will be used to store images used in this application. Now start creating the following source files into its source folder.

Let's start by creating a simple book catalog XML file as follows:

bookscatalog.xml:
<books>
<book ISBN="184719530X">
<title>Building Websites with Joomla! 1.5</title>
<author>
<lastName>Hagen</lastName>
<firstName>Graf</firstName>
</author>
<image>../assets/images/184719530X.png</image>
<pageCount>363</pageCount>
<price>Rs.1,247.40</price>
<description>The best-selling Joomla! tutorial guide updated for the latest 1.5 release </description>
</book>
<book ISBN="1847196160">
<title>Drupal 6 JavaScript and jQuery</title>
<author>
<lastName>Matt</lastName>
<firstName>Butcher</firstName>
</author>
<image>../assets/images/1847196160.png</image>
<pageCount>250</pageCount>
<price>Rs.1,108.80</price>
<description>Putting jQuery, AJAX, and JavaScript effects into your Drupal 6 modules and themes</description>
</book>
<book ISBN="184719494X">
<title>Expert Python Programming</title>
<author>
<lastName>Tarek</lastName>
<firstName>Ziadé</firstName>
</author>
<image>../assets/images/184719494X.png</image>
<pageCount>350</pageCount>
<price>Rs.1,247.4</price>
<description>Best practices for designing, coding, and distributing your Python software</description>
</book>
<book ISBN="1847194885">
<title>Joomla! Web Security</title>
<author>
<lastName>Tom</lastName>
<firstName>Canavan</firstName>
</author>
<image>../assets/images/1847194885.png</image>
<pageCount>248</pageCount>
<price>Rs.1,108.80</price>
<description>Secure your Joomla! website from common security threats with this easy-to-use guide</description>
</book>
</books>

The above XML file contains details of individual books in an XML form. You can also deploy this file on your web server and specify its URL into URLRequest while loading it.

Next, we will create a custom event which we will be dispatching from our custom component. Make sure you create an events package under your src folder in Flex Builder called events, and place this file in it.

AddToCartEvent.as:
package events
{
import flash.events.Event;
public class AddToCartEvent extends Event
{
public static const ADD_TO_CART:String = "addToCart";
public var book:Object;
public function AddToCartEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

This is a simple custom event created by inheriting the flash.events.Event class. This class defines the ADD_TO_CART string constant, which will be used as the name of the event in the addEventListener() method. You will see this in the BooksExplorer.mxml code. We have also defined an object to hold the reference of the book which the user can add into the shopping cart. In short, this object will hold the XML node of a selected book.

Next, we will create the MXML custom component called BookDetailItemRenderer.mxml. Make sure that you create a package under your src folder in Flex Builder called components, and place this file in it and copy the following code in it:

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
cornerRadius="8" paddingBottom="2" paddingLeft="2"
paddingRight="2" paddingTop="2">
<mx:Metadata>
[Event(name="addToCart", type="flash.events.Event")]
</mx:Metadata>
<mx:Script>
<![CDATA[
import events.AddToCartEvent;
import mx.controls.Alert;
[Bindable]
[Embed(source="../assets/images/cart.gif")]
public var cartImage:Class;
private function addToCardEventDispatcher():void {
var addToCartEvent:AddToCartEvent = new AddToCartEvent
("addToCart", true, true);
addtoCartEvent.book = data;
dispatchEvent(addtoCartEvent);
}
]]>
</mx:Script>
<mx:HBox width="100%" verticalAlign="middle" paddingBottom="2"
paddingLeft="2" paddingRight="2" paddingTop="2" height="100%"
borderStyle="solid" borderThickness="2" borderColor="#6E6B6B"
cornerRadius="4">
<mx:Image id="bookImage" source="{data.image}" height="109"
width="78" maintainAspectRatio="false"/>
<mx:VBox height="100%" width="100%" verticalGap="2"
paddingBottom="0" paddingLeft="0" paddingRight="0"
paddingTop="0" verticalAlign="middle">
<mx:Label id="bookTitle" text="{data.title}"
fontSize="12" fontWeight="bold"/>
<mx:Label id="bookAuthor" text="By: {data.author.
lastName},{data.author.firstName}" fontWeight="bold"/>
<mx:Label id="coverPrice" text="Price: {data.price}"
fontWeight="bold"/>
<mx:Label id="pageCount" text="Pages: {data.pageCount}"
fontWeight="bold"/>
<mx:HBox width="100%" backgroundColor="#3A478D"
horizontalAlign="right" paddingBottom="0" paddingLeft="0"
paddingRight="5" paddingTop="0" height="22"
verticalAlign="middle">
<mx:Label text="Add to cart " color="#FFFFFF"
fontWeight="bold"/>
<mx:Button icon="{cartImage}" height="20" width="20"
click="addToCardEventDispatcher();"/>
</mx:HBox>
</mx:VBox>
</mx:HBox>
</mx:HBox>
Flex 3 with Java Develop rich internet applications quickly and easily using Adobe Flex 3, ActionScript 3.0 and integrate with a Java backend using BlazeDS 3.2
Published: June 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

 

The above custom component will be used as an itemRenderer to display books' details from an XML file. In this example, we have created a custom MXML-based component. This custom component dispatches a custom event called AddToCartEvent when a user clicks on the add to cart button. Notice that when we are dispatching an event, we are setting its bubbles argument (second argument in the AddToCartEvent constructor, which is inherited from the flash.events.Event class) to true. This is very important in order to bubble this event up to its parent where we will write an event listener for it. You will see how to write an event listener on the parent to handle the event dispatched by its children in the BooksExplorer.mxml code. At the end, this custom component will be used as ItemRenderer of the TileList component to display books. So we are using the data property of the itemRenderer instance to access XML nodes and properties using the E4X technique. The data property is implicitly available in item renderers that can be used to access content locally.

Next, we will create the main application and layout the book explorer user interface, and then we will write business logic for loading XML data and display it in the custom component, and so on.

BooksExplorer.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()"
xmlns:components="components.*" layout="horizontal">
<mx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
import mx.formatters.CurrencyFormatter;
import mx.collections.ArrayCollection;
import mx.effects.Blur;
import events.AddToCartEvent;
import components.BookDetailItemRenderer;
import mx.controls.Alert;
private var loader:URLLoader;
private var request:URLRequest;
[Bindable]
private var xmlData:XML;
[Bindable]
private var selectedBook:XML;
[Bindable]
private var shoppingCart:ArrayCollection;
private function init():void {
tileList.addEventListener(AddToCartEvent.ADD_TO_CART,
addToCartHandler);
shoppingCart = new ArrayCollection();
request = new URLRequest("./bookscatalog.xml");
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, completeHandler);
try {
loader.load(request);
} catch (error:SecurityError) {
trace("A SecurityError has occurred.");
} catch(error:Error) {
trace("An Unknown Error has occurred. ["+error.
message+"]");
}
}
private function completeHandler(event:Event):void {
xmlData = new XML(loader.data);
}
private function addToCartHandler(event:AddToCartEvent):void {
shoppingCart.addItem(XML(event.book));
}
private function itemSelected(event:Event):void {
selectedBook = XML(tileList.selectedItem);
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%" verticalAlign="bottom">
<mx:HBox width="100%" height="70%">
<mx:Panel title="Products Explorer" width="70%" height="100%"
layout="horizontal">
<mx:TileList id="tileList" variableRowHeight="false"
itemRenderer="components.BookDetailItemRenderer"
dataProvider="{xmlData.book}"
change="itemSelected(event)" columnCount="2"
height="100%" width="100%"/>
</mx:Panel>
<mx:Panel width="30%" height="100%" title="Details">
<mx:Form width="100%" height="100%">
<mx:FormItem label="Book Name:">
<mx:Label id="bookName" text="{selectedBook.title}"/>
</mx:FormItem>
<mx:FormItem label="ISBN:">
<mx:Label id="isbnNumber"
text="{selectedBook.@ISBN}"/>
</mx:FormItem>
<mx:FormItem label="Author:">
<mx:Label id="authorName">
<mx:text>{selectedBook.author.firstName}
{selectedBook.author.lastName}</mx:text>
</mx:Label>
</mx:FormItem>
<mx:FormItem label="Pages:">
<mx:Label id="pageNumber"
text="{selectedBook.pageCount}"/>
</mx:FormItem>
<mx:FormItem label="Price:">
<mx:Label id="bookPrice"
text="{selectedBook.price}"/>
</mx:FormItem>
<mx:FormItem label="Description:">
<mx:Text id="bookDesc"
text="{selectedBook.description}" width="200"/>
</mx:FormItem>
<mx:FormItem label="Cover Page:">
<mx:Image width="138"
height="146" source="{selectedBook.image}"/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
</mx:HBox>
<mx:HBox width="100%" height="30%">
<mx:Panel width="100%" height="100%" title="Shopping Cart">
<mx:DataGrid id="dgGrid" dataProvider="{shoppingCart}"
height="100%" width="100%" editable="true">
<mx:columns>
<mx:DataGridColumn headerText="Book Name"
dataField="title" editable="false"/>
<mx:DataGridColumn headerText="Price"
dataField="price" editable="false"/>
<mx:DataGridColumn headerText="Qty."
dataField="quantity" editable="true"/>
</mx:columns>
</mx:DataGrid>
<mx:ControlBar>
<mx:Button label="Checkout"
click="Alert.show(‚Not yet implemented.');"/>
<mx:Button label="Remove"
click="Alert.show(‚Not yet implemented.');"/>
</mx:ControlBar>
</mx:Panel>
</mx:HBox>
</mx:VBox>
</mx:Application>

In the code above, we have used the HBox, VBox, and Panel containers to lay out the main user interface. We have also added a TileList component to display books using a custom component, that is, BookDetailItemRenderer.mxml as its itemRenderer. Next, we have added another Panel container to display the selected book's details using a Form container. We have used data binding to bind the selected book's details with individual labels in the Form container, for example, text="{selectedBook.title}". selectedBook is an XML object which will be populated with the selected book's details when you select an item in the TileList component using its change event.

The TileList control displays a number of items laid out in tiles. It displays a scroll bar to access all items in the list. You can use its direction property to control the direction in which this control lays out its children. To know more about the TileList control, see Flex 3 language reference at http://livedocs.adobe.com/flex/3/langref/mx/controls/TileList.html.

Next, we have created another Panel container to create the shopping cart user interface and added a DataGrid component to display cart details. The DataGrid component is using data binding to display information from the shoppingCart ArrayCollection object, which will contain individual selected book nodes. We will populate the shopppingCart array in the addToCartHandler() method, which is the event handler for the addToCart custom event.

In the ActionScript code block, we have defined a method called init() to initialize the application's resources and variables. This method is called in the application tag's creationComplete event. In this method, we have registered an event handler for the addToCart event which will be dispatched by the BookDetailItemRenderer.mxml custom component.

Notice that BookDetailItemRenderer.mxml is acting as an itemRenderer of a TileList component, so there is no straight way to add an event listener to it. Therefore, to handle events from the itemRenderer component in its parent, you need to dispatch an event from custom component by setting its bubble argument to true. When an event is dispatched with the bubble argument set to true, Flex searches for event listeners in the bottom to top order—that is, from event target to root display object. When it finds an appropriate event listener anywhere in its display hierarchy, it delivers an event to it. This is a simple way to communicate with your application from itemRenderers.

Next, we are loading XML file using URLLoader and setting its result to the xmlData XML object, which is used as the dataProvider of the TileList component. xmlData.book refers to individual node(s) from the XML file.

Now we are ready with our application. Once we compile and execute this application, you would see the following screen:

You can play with this application. You can try selecting different items from the TileList control and see how it changes display in the Details panel, and see what happens when you click on the Add to cart button.

Summary

In this article, we learned how to load external XML files and use XML as a data provider. We also created a sample books explorer application using various concepts, such as custom component, event creation, data binding, and E4X.

This article series mainly covered the E4X approach to process XML data with a comprehensive example application using these techniques to process XML data.

If you have read this article you may be interested to view :

Flex 3 with Java Develop rich internet applications quickly and easily using Adobe Flex 3, ActionScript 3.0 and integrate with a Java backend using BlazeDS 3.2
Published: June 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

About the Author :


Satish Kore

Satish Kore hails from Bangalore, the IT capital of India. He has more than 8 years experience in the technology world, spread across multiple technologies and domains, and he has extensive knowledge of Java, J2ME and Adobe Flex, ActionScript, and so on. He is a Principle Engineer at multinational company in Bangalore, India. He is a Flex enthusiast and evangelist and has been working on Flex since its early 1.5 version days. His application built using Flex 3 has won a best-application award from Flash-based telephony company Ribbit (http://www.ribbit.com). You can visit his blog for more information at http://blog.satishkore.com.

Books From Packt

WordPress MU 2.7: Beginner's Guide
WordPress MU 2.7: Beginner's Guide

Zend Framework 1.8 Web Application Development
Zend Framework 1.8 Web Application Development

eZ Publish 4: Enterprise Web Sites Step-by-Step
eZ Publish 4: Enterprise Web Sites Step-by-Step

Apache Maven 2 Effective Implementations: RAW
Apache Maven 2 Effective Implementations: RAW

Building Enterprise Ready Telephony Systems with sipXecs 4.0: RAW
Building Enterprise Ready Telephony Systems with sipXecs 4.0: RAW

Alfresco 3 Enterprise Content Management Implementation
Alfresco 3 Enterprise Content Management Implementation

Pentaho Reporting 3.5 for Java Developers
Pentaho Reporting 3.5 for Java Developers

ICEfaces 1.8: Next Generation Enterprise Web Development: RAW
ICEfaces 1.8: Next Generation Enterprise Web Development: RAW

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software