|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV |
TODAY'S TOP SOA & WEBSERVICES LINKS Yakov's Gas Station Creating a Flashy Monitoring Application
Building an application in Flex using declarative GUI language MXML mixed with ActionScript 3 and XML
By: Yakov Fain
Nov. 22, 2006 11:30 AM
Do you know what's the main goal of any gas station owner? To get lots of trucking accounts. Business from small car drivers is worth pennies, and it gets on my nerves to hear them ask again and again, "Five dollars of regular, please." Trucks are different. They usually pump in a couple of hundreds of gallons at a time. For instance, here comes a flashy 18-wheeler with a sign "Software Delivered." These guys ship reusable open source components around the globe. As a former programmer, I was trying to play it smart by asking why they don't just let people download these components from the Internet? But the smiley truckers (many of whom used to be software developers too) just shrug and tell me that nothing beats personal delivery, plus the tips. If you think about it, their ventures are the basis of a new business model. Ten years ago, only professional vendors would create and sell well-documented, working software. Then, independent developers started writing code jointly, but since they did not bother spending time writing documentation and testing, they gave away their software for free, while charging a premium for adding custom features and explaining undocumented ones. Now there is a new trend: delivering software to your doorsteps for tips. This makes sense to me - most paid programmers live in Bangalore, and since they can't deliver, they can't compete.
Developing with MXML, XML, and ActionScript We'll read the initial gas station activities data from the XML shown in Listing 1 (all the source code for this article is there). The final version of our application will include a timer with a random data generator that will add new messages to the window from Figure 1, emulating the data feed of three types of messages: sale, purchase, and spill. In real life, I'll be using Java and message-oriented middleware on the server, but this is beyond the scope of this article. The first version of GasStation.mxml (see Listing 2) reads and parses the data from GSActivities.xml using this one liner: <mx:XML id="activities" source="GSactivity.xml" /> No additional XML parsing is required. Behind the scenes, Flex creates an object with the reference variable activities, which is used as a data provider for the data grid as follows: <mx:DataGrid id="messageBook" dataProvider="{activities.message}" width="100%" height="100%"> The dataProvider activities.message represents the <message> XML element from GSActivity.xml, which is displayed as a row in the data grid. The curly braces mean that our XML object is bindable, and that the content of the XML element <message> from Listing 1 will be used to populate each row of the data grid. The ActiveScript renderer function paid(), that is being called for each row, calculates the amount by multiplying the number of gallons and the price per gallon. The <mx:CurrencyFormatter> ensures that the calculated column "paid" is displayed as a dollar amount. The rest of the code in Listing 2 displays other controls that we'll use for filtering and illustrating master-detail relations later in this section. Note: The combobox cbMsgTypes is populated from an array messageType, which is marked as [Bindable] and will be used later for filtering the messages in the data grid. Also, since in this version we did not define the data grid column, Paid By, the corresponding data from the data provider are not shown. Adding a Collection Class There are several ways of using collections as data providers, but I'll just show you one. Eventually, I'll add a middleman between the XML object and the data grid. Now the data grid's provider will become an XMLListCollection built on top of activities XML: <mx:XML id="activities" source="GSactivity.xml" /> Just recompile and run the application again - it will display the same window as in Figure 1. Filtering msgList.filterFunction=filterMessages; In Flex, you can assign the name of the function to an object's property and execute it. The filtering will happen when we call the function refresh() on the collection. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" Run the application after making these changes, and you'll see an empty table on the screen. This is because, when creation of the application was complete, Flash VM called the method init, which assigned the filter function to our XMLListCollection, and then refresh() applied this filter to the each XML node of our collection. Since no checkbox was selected, the function filterMessages correctly returned false to each node, leaving the datagrid empty. To fix this, let's make a slight change in the checkboxes so they will be initially checked off: <mx:CheckBox id="cbx93" label="93" selected="true"/> Now the program will show all the rows again. Try to uncheck the boxes - nothing happens, because the application doesn't know that it needs to re-apply the filter function to the msgList again. This is an easy fix - let's refresh the msgList on each click on the checkbox: <mx:CheckBox id="cbx93" label="93" selected="true" click="msgList.refresh()"/> Filtering by octane number is done. By adding the code snippet below to the beginning of the filterMessages() function, you'll engage filtering by message type according to the combobox selection: if (cbMsgTypes.selectedLabel !="all" && Please note the @ sign. This is how you access XML attributes (see Listing 1) using E4X notation. The XML elements are accessed using a regular dot notation. Master-Details Relationships We'll start with creating an actions.xml file where we store recommended actions for each message type (see Listing 3). To read and parse this file into an XML object, we need to write yet another one liner: <mx:XML id="msgTypes" source="MessageTypes.xml" /> The next step is to specify that selecting a different row in a datagrid should call the function that finds and displays an appropriate message from MessageTypes.xml. Again, E4X makes this job a breeze: private function getAction():void { The expression msgTypes.message.(@type==messageBook.selectedItem.@msgType) means the following: select the XML <message> element, which has an attribute type the same as in the selected row in the datagrid in column @msgType. When this XML element is identified, assign its <actions> value to the text area txtAction. As I stated earlier, changing the selected row in the data grid should initiate the getAction() function call. Let's modify the declaration and add the change event processing: <mx:DataGrid id="messageBook" dataProvider="{msgList}" width="100%" If you compile and run this program, then click on a row in a data grid, the action text box will be populated, as shown in Figure 2. We're almost there. Why almost? Because if the user starts filtering the data by octane or a message type, the actions text field won't be cleaned. To fix this, let's create our own function refreshData() that will not only refresh the XMLListCollection, but also clean the text field: private function refreshData():void{ Don't forget to replace all calls to msgList.refresh() with refreshData(). Adding a Data Feed This version of the application was built based on the XML data feed, not because it's the best solution for these kinds of applications, but rather to introduce the reader to the ease of XML parsing with E4X. If the speed of your data feed is crucial, or, as a Java programmer you'd like to have more control over the data, use ActionScript objects as a data feed and ArrayCollection instead of XMLListCollection. This object should define getters providing data for all data grid columns, including the calculated amount for the column Paid. Keeping calculations in the function paid() is not a good idea because the so-called label function is called every time the program inserts a new element into the underlying XML collection. Flash repaints each visible data grid row upon each insertion of a new gas transaction, which means the paid amounts for each visible row will be recalculated. Granted, you can create simple prototype applications in Flex with few lines of code, but let's not fool ourselves - making efficient applications still requires programming, such as in good old Java. To see this application in action, just point your Web browser at http://samples.faratasystems.com/gasstation/GasStation3.html. Adobe Flash Player 9 is required to run this application, but if you don't have it installed, my HTML will automatically detect it - just follow the prompts and it'll be installed pretty quickly. For a bit more advanced Flex-Java application read the article "Rich Internet Applications with Adobe Flex 2 and Java" at http://java.sys-con.com/read/210991.htm. In the past, I used only Java for all my programming needs. But as the medieval saying goes, if the only tool you have is a gasoline hose, every problem looks like a car tank. These days are gone, and now I'm using Java on the server-side and Adobe Flex as a tool for building Rich (as in Bill Gates) Internet Applications. YOUR FEEDBACK
XML JOURNAL LATEST STORIES . . .
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK BREAKING XML NEWS |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||