Archive for July, 2008

05
Jul

Let’s Go Through the Sequence of Events

When the green button is clicked, the greenButtonHandler is called and it creates and dispatches
the addItemEvent event back to itself. The event bubbles to the parent container(s), notifying all
listening parties of the event. The BlindShoppingCart listens for such an event and responds by
adding text. Run this application, click on the button, and the window should look like this:
Figure 4.18 The output of RedAndGreenApplication.mxml
Now one more time: the green button component shoots the event to the outside world without
knowing anything about it. That is very different from the case when we would write “glue” code
like cart.addEventListener(”click”, applicationResponseMethodDoingSomethingInsideTheCart).
Sending Data Using Custom Events
To make our blind shopping cart more useful, we have to be able not only to fire a custom event,
but have this event deliver a description of the item that was passed to shopping cart. To do this,
we’ll have to create a custom event class with an attribute that will store application-specific data.
This class has to extend flash.events.Event; override its method clone to support event bubbling;
and call the constructor of the super-class, passing the type of the event as a parameter. The AS3
class below defines a itemDescription property that will store the application-specific data.
package cart {
import flash.events.Event;
public class ItemAddedEvent extends Event {
var itemDescription:String; //an item to be added to the cart
public static const ITEMADDEDEVENT:String =”ItemAddedEvent”;
public function ItemAddedEvent(description:String )
{
super(ITEMADDEDEVENT,true, true); //bubble by default
CHAPTER 4
RIA WITH ADOBE FLEX AND JAVA 151
itemDescription=description;
}
override public function clone():Event{
return new ItemAddedEvent(itemDescription); // bubbling support inside
}
}
}
Listing 4.45 The custom event ItemAddedEvent
The new version of the shopping cart component is called ShoppingCart and its event handler
extracts the itemDescription from the received event and adds it to the text area.
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:TextArea xmlns:mx=”http://www.adobe.com/2006/mxml”
backgroundColor=”#ff0000″ creationComplete=”init()”>
<mx:Script>
<![CDATA[
private function init():void{
parent.addEventListener(ItemAddedEvent.ITEMADDEDEVENT,addItemToCartEventHandler);
}
private function addItemToCartEventHandler(event:ItemAddedEvent){
text+=”Yes! Someone has put ” + event.itemDescription + “\n”;
}
]]>
</mx:Script>
</mx:TextArea>
Listing 4.46 ShoppingCart.mxml
There’s a design pattern called Inversion of Control or Dependency Injection, which means that an
object doesn’t ask other objects for required values, but assumes that someone will provide the required
values from outside. This is also known as the Hollywood principle or “Don’t call me, I’ll call
you.” Our ShoppingCart does exactly this - it waits until some unknown object triggers an event
it listens to that carries an item description. Our component knows what to do with it, i.e., display
in the red text area, validate it against the inventory, send it over to the shipping department, and
so on.
Next, we’ll completely rework our LargeGreenButton class into a NewItem component to include a
label and a text field to enter some item description and the same old green button:
<?xml version=”1.0″ encoding=”utf-8″?>
Learning Flex Through Applications
152 RIA WITH ADOBE FLEX AND JAVA
<mx:HBox xmlns:mx=”http://www.adobe.com/2006/mxml” >
<mx:Metadata>
[Event(name=”addItemEvent”, type=”flash.events.Event”)]
</mx:Metadata>
<mx:Label text=”Item name:”/>
<mx:TextInput id=”enteredItem” width=”300″/>
<mx:Button
width=”104″ height=”28″ cornerRadius=”10″ fillColors=”[#00ff00, #00B000]”
label=”Add Item” fontSize=”12″ click=”greenClickEventHandler()”/>
<mx:Script>
<![CDATA[
import cart.ItemAddedEvent;
private function greenClickEventHandler():void{
trace(”Ouch! I got clicked! Let me tell this to the world.”);
dispatchEvent(new ItemAddedEvent(enteredItem.text));
}
]]>
</mx:Script>
</mx:HBox>
When we look at our new application with its new ShoppingCart and NewItem components, it’s
almost indistinguishable from the original one. If we kept the old class names, we could have used
the old application.
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”vertical”
xmlns:ctrl=”controls.*” xmlns:cart=”cart.*”>
<ctrl:NewItem />
<cart:ShoppingCart width=”350″ height=”150″ fontSize=”14″/>
</mx:Application>
Listing 4.47 RedAndGreenApplication2.mxml
When the user enters the item description and clicks the green one, the application creates a new
instance of the ItemAddedEvent, passing the entered item to its constructor, and the ShoppingCart
properly displays the selected “New Item to Add” on the red carpet (see Figure 4.19).
CHAPTER 4
RIA WITH ADOBE FLEX AND JAVA 153
Figure 4.19 The output of RedAndGreenApplication.mxml
Making components loosely bound simplifies development and distribution but comes at a higher
cost in testing and maintenance. Depending on the delivery timeline, size, and lifespan of your application,
you’d have to make a choice between loosely coupled or strongly typed components.
One last note. The itemDescription in Listing 4.45 doesn’t have an access-level qualifier. It’s socalled
package-level protection. The ShoppingCart can access itemDescription directly, but the
classes outside the “cart” package can’t.

05
Jul

Flex Custom Events

While Flex components come with their pre-defined events, developers can create custom events
specific to their applications. Event-driven programming is a very important design concept because
it allows an application to react to user interaction without imposing a pre-defined “flow”
on the end user. It means that unlike back-end processes that tend to have a “single track of mind”
design, front-end applications have to react to what often seems like an unrelated sequence of enduser
actions. Fortunately, the event-driven model offers an excellent architecture for such interaction
based on loosely coupled components consuming and throwing the events.
This simply means a properly designed component knows how to perform some functionality and notifies
the outside world by broadcasting one or more custom events. We need to stress that such a component
doesn’t send these events to any other component(s). It just broadcasts its “exciting news” to
the event dispatcher. If any other component is interested in processing this event, it must register a listener
for this event. Unlike direct component-to-component calls via public interfaces, this approach
lets you add processing components and set up priorities without affecting the working components.
Before explaining how to create an event-driven component, we’ll state how to use them. This is a
typical scenario: MyApplication uses Component1 and Component2. The components don’t know
about each other. Any event-handling component has to define this event inside.
For example, Component1 dispatches this custom event and sends out an instance of the event
object, which may or may not carry some additional component-specific data. MyApplication
handles this custom event and, if needed, communicates with Component2 with or without feeding
it with data based on the results of the first component event.
We’ll create a new shopping cart application that will include a main file and two components: the
first, a large green button, and the second, a red TextArea field. We’ll create two separate directories,
“controls” and “cart,” respectively, where our components will live.
To create our first MXML component in Flex Builder, select the “controls” directory and click on
the menu File | New MXML Component. In the pop-up screen we’ll enter LargeGreenButton as a
component name and we’ll pick Button from a dropdown as a base class for our component.
Flex Builder will generate the following code:
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Button xmlns:mx=”http://www.adobe.com/2006/mxml”>
</mx:Button>
Next, we’ll make this button large and green with rounded corners (just to give it a Web 2.0 look).
This component will dispatch an event named greenClickEvent. But when? You’ve got it: when
someone clicks on large and green.
CHAPTER 4
RIA WITH ADOBE FLEX AND JAVA 147
Custom events in MXML are annotated within the metadata tag to be visible to MXML. In Listing
4.41 we declared a custom event of the generic flash.events.Event type in the metadata tag. Since the
purpose of this component is to notify the sibling objects that someone has clicked the button, we’ll
define the greenClickEventHandler()event handler to create and dispatch our custom event.
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Button xmlns:mx=”http://www.adobe.com/2006/mxml”
width=”104″ height=”28″ cornerRadius=”10″ fillColors=”[#00ff00, #00B000]”
label=”Add Item” fontSize=”12″ click=”greenClickEventHandler()”>
<mx:Metadata>
[Event(name=”addItemEvent”, type=”flash.events.Event”)]
</mx:Metadata>
<mx:Script>
<![CDATA[
private function greenClickEventHandler():void{
trace(”Ouch! I got clicked! Let me tell this to the world.”);
dispatchEvent(new Event(”addItemEvent”, true));// bubble to parent
}
]]>
</mx:Script>
</mx:Button>
Listing 4.41 LargeGreenButton.mxml
Please note that the LargeGreenButton component has no idea what will process its addItemEvent.
It’s none of its business - loose coupling in action!
In dynamic languages the following naming conventions are common practice: to add an “Event”
suffix to each of the custom events you declare, and a “Handler” suffix to each of the event-handler
functions.
Here’s the application that will use the LargeGreenButton component:
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
xmlns:ctrl=”controls.*” layout=”absolute”>
<ctrl:LargeGreenButton greenClickEvent=”greenButtonHandler(event)”/>
<mx:Script>
<![CDATA[
private function greenButtonHandler(event:Event):void{
Learning Flex Through Applications
148 RIA WITH ADOBE FLEX AND JAVA
trace(”Someone clicked on the Large Green Button!”);
}
]]>
</mx:Script>
</mx:Application>
Listing 4.42 EventApplication.mxml
We have defined an extra namespace “ctrl” here to make the content of the “controls” directory visible
to this application. Run this application in debug mode, and it’ll display the window in Figure
4.17. When you click on the green button it will output the following on the console:
Ouch! I got clicked! Let me tell this to the world. Someone clicked on the Large Green Button.
While adding attributes to <ctrl:LargeGreenButton>, please note that code hints work and Flex
Builder properly displays the greenClickEvent in the list of available events under the new custom
component button.
Figure 4.17 The output of GreenApplication.xmxl
Our next component will be called BlindShoppingCart. This time we’ll create a component in the
“cart” directory based on the TextArea:
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:TextArea xmlns:mx=”http://www.adobe.com/2006/mxml”
backgroundColor=”#ff0000″ creationComplete=”init()”>
CHAPTER 4
RIA WITH ADOBE FLEX AND JAVA 149
<mx:Script>
<![CDATA[
private function init():void{
parent.addEventListener(”addItemEvent”,addItemToCartEventHandler);
}
private function addItemToCartEventHandler(event:Event){
this.text+=”Yes! Someone has put some item inside me, but I do not know what
it is. \n”;
}
]]>
</mx:Script>
</mx:TextArea>
Listing 4.43 BlindShoppingCart.mxml
Note that the BlindShoppingCart component doesn’t expose any public properties or methods to
the outside world. It’s a black box. The only way for other components to add something to the
cart is by dispatching the addItemEvent event. The next question is how to map this event to the
function that will process it. When someone instantiates the BlindShoppingCart, Flash Player will
dispatch the creationComplete event on the component and our code will call the init() private
method that adds the addItemEvent event listener mapping to the addItemToCartEventHandler
function. This function just appends the text “Yes! Someone has put…” to its red TextArea.
The RedAndGreenApplication application uses the LargeGreenButton and BlindShoppingCart
components.
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”vertical”
xmlns:ctrl=”controls.*” xmlns:cart=”cart.*”>
<ctrl:LargeGreenButton addItemEvent=”greenButtonHandler(event)”/>
<cart:BlindShoppingCart width=”350″ height=”150″ fontSize=”14″/>
<mx:Script>
<![CDATA[
private function greenButtonHandler(event:Event):void{
trace(”Someone clicked on the Large Green Button!”);
}
]]>
</mx:Script>
</mx:Application>

05
Jul

Flex Events

In object-oriented languages, if object A needs to notify object B about some important event, it’s
done using a so-called Observer design pattern; Java implements this pattern in the Observer interface
and Observable class. An observable object may have something interesting going on, and
other objects that want to know about this implement the Observer interface and register themselves
with the observable class.
AS3 implements this design pattern using an event model. Objects can trigger events to each other.
System events are triggered by the AVM, while others are triggered as a result of user interactions
with your application, such as a click on a button or a mouse move. Below are some situations
when events can be dispatched (triggered):

  • When Flash Player finishes creating a component, it dispatches a creationComplete event.

The DisplayObject class is a subclass of the EventDispatcher class, which means that each of
the display objects can register an event listener and process events as they occur.

  • User-defined classes can dispatch events according to the business logic of the application.
  • The EnterFrame event is triggered by the AVM at the application’s frame rate. In movie-type

applications it’s being dispatched when the playhead is entering a new frame. Even though
Flex applications don’t have multiple frames, this event is continuously dispatched. This
makes it a good candidate to check if some important action has occurred, i.e., a Boolean flag
indicating the status of some business transaction is set to true.

  • The objects of your application can send custom events to each other.

In an MXML application you’d just specify the name of the event and its handler function (or inline
code) in the attribute of the component without worrying too much about the underlying
CHAPTER 4
RIA WITH ADOBE FLEX AND JAVA 139
AS3 code. But all Flex events are subclasses of flash.events.Event, and in AS3 programs you should
register an event listener to “listen” to this event and write a function to handle this event when it
arrives. For example, the next code snippet specifies that Flash Player has to call a method onEnteringFrame
(written by you) on each EnterFrame event:
addEventListener(Event.ENTERFRAME, onEnteringFrame);
In Java, event listeners are objects, but in AS3 only functions or methods can listen to the events.
If you need to trigger an event from the ActionScript class, it has to be either a subclass of Event-
Dispatcher or implement the IEventDispatcher interface. The latter is the more preferred way because
AS3 doesn’t support multiple inheritance, and your class may need to extend another class.
The other reason to use a lighter interface is that you may not need all the functionality that was
defined in the EventDispatcher class and implement the required interface method as you see fit.
For example:
class MyClass extends HisClass implements IEventDispatcher{
}
Event Flow
When the event listener calls an event handler function, it receives an event object as a parameter,
which contains various attributes of the event, and the most important one is the event’s target.
This terminology might be a little confusing to Java developers since they refer to the component
that generates an event as an event source. But here we say that all events are generated by the
Flash Player. They are initiated at the stage level and flow to the target component (capturing the
stage), i.e., Button, Shape, etc.. After reaching the target, the event “bubbles” its way through to the
parents. So, when you click on a button, we can say that a button is the event target. If a button is
located on a panel, this event will flow from the stage to the panel and then to the button - and
then all the way back.
Flash Player 9 implements an event model based on the World Wide Web Consortium’s (W3C) specification
entitled Document Object Model Events available at http://www.w3.org/TR/DOM-Level-
3-Events/events.html. According to this document, the lifecycle of an event that deals with display
objects consists of three phases: capture, target, and bubbling.

  • Capture: During this phase, Flash Player makes a first pass to check every object from the root

of the display list to the target component to see if any parent component might be interested
in processing this event. By default, events are ignored by the parents of the target component
at the capture phase.

  • Target: At this phase, event object properties are set for the target and all registered event

listeners for this target will get this event.
Learning Flex Through Applications
140 RIA WITH ADOBE FLEX AND JAVA

  • Bubbling: Finally, the event flows back from the target component all the way up to the root

to notify all interested parties identified during the capture phase. Not all events have a bubbling
phase and you should consult the AS3 language reference for the events you’re interested
in.
The three event phases described above don’t apply to the user-defined events because Flash Player
9 doesn’t know about parent-child relations between user-defined event objects. But AS3 developers
can create custom event dispatchers, if they want to arrange event processing in three phases.
Event Propagation or Bubbling
Consider the following sample MXML code with a button in a panel.
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” >
<mx:Panel x=”17.5″ y=”20″ width=”209″ height=”142″ layout=”absolute”
click=”trace(‘click event in the Panel’)” title=”Just a Panel”>
<mx:Button label=”ClickMe” x=”60.5″ y=”38″
click=”trace(‘click event in the Button’)”/>
</mx:Panel>
</mx:Application>
Listing 4.38 Events.mxml
Run this simple program in the debug mode to enable trace and it’ll show you the following output:
Figure 4.14 Output of the Events.mxml
Clicking on the button in the Flex Builder’s console will show the following:
CHAPTER 4
RIA WITH ADOBE FLEX AND JAVA 141
click event in the Button
click event in the Panel
This illustrates events propagation or bubbling: the click event bubbles up from the target (button)
to its parent (panel).
Now let’s create another version of this application, where the button and the panel as well as the
event processing are coded in AS3. This way you’ll see and appreciate all the legwork that MXML
did for us:
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
creationComplete=”onCreationComplete();” >
<mx:Script>
<![CDATA[
import mx.controls.Button;
import mx.containers.Panel;
private var myButton:Button;
private var myPanel:Panel;
// An event handler for creationComplete event
private function onCreationComplete():void {
myPanel=new Panel();
myPanel.width=200;
myPanel.height=150;
myPanel.title=”Just a Panel”;
addChild(myPanel);
myButton = new Button();
myButton.label = “Click me”;
addChild (myButton);
}
]]>
</mx:Script>
</mx:Application>
Listing 4.39 Creating a button and a panel in ActionScript
Learning Flex Through Applications
142 RIA WITH ADOBE FLEX AND JAVA
If you run this code, the output will look like this:
Figure 4.15 A button and a panel without nesting
This is not exactly the result we were looking for and the reason is simple: both the panel and the
button were added to the application’s display list independently. Let’s fix this by adding the button
to the panel by replacing addChild(myButton) with myPanel.addChild(myButton).
Now the hierarchy of the nodes in the display list will be different, and the node representing the
button will be created under the parent node of the panel as shown in Figure 4.16.
Figure 4.16 A button and a panel with nesting
This is much better, but still not exactly the same as Figure 4.14. Let’s try to set the coordinate of the
CHAPTER 4
RIA WITH ADOBE FLEX AND JAVA 143
button to values from Listing 4.38:
myButton.x=60.5;
myButton.y=38;
It did not help because, by default, the panel container uses the vertical layout (see Chapter 3) and
ignores the absolute coordinates. Let’s add one line to change it into an absolute layout:
myPanel.layout=”absolute”;
Now if you run the application it’ll look the same as in Figure 4.13.
We’ve written a lot of ActionScript code, and we haven’t even processed the click events yet! We still
need to add event listeners and event handlers to the button and the panel:
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
creationComplete=”onCreationComplete();” >
<mx:Script>
<![CDATA[
import mx.controls.Button;
import mx.containers.Panel;
import flash.events.MouseEvent;
private var myButton:Button;
private var myPanel:Panel;
// An event handler for creationComplete
private function onCreationComplete():void {
myPanel=new Panel();
myPanel.width=200;
myPanel.height=150;
myPanel.layout=”absolute”;
myPanel.title=”Just a Panel”;
addChild(myPanel);
myButton = new Button();
myButton.label = “Click me”;
myButton.x=60.5;
myButton.y=38;
myPanel.addChild (myButton);
Learning Flex Through Applications
144 RIA WITH ADOBE FLEX AND JAVA
// Adding the click event processing
myButton.addEventListener(MouseEvent.CLICK, buttonClickHandler);
myPanel.addEventListener(MouseEvent.CLICK, panelClickHandler);
}
// The button click handler (the target phase)
private function buttonClickHandler(event:MouseEvent) :void{
trace (”click event in the Button”);
}
// The panel handler to demo bubbling
private function panelClickHandler(event:MouseEvent) :void{
trace (”click event in the Panel”);
}
]]>
</mx:Script>
</mx:Application>
Listing 4.40 AS_Bubbling.mxml
Run this application in debug mode and the console screen will look the same as the MXML version
of our application:
click event in the Button
click event in the Panel
The order of these messages is a clear indication that the target event was processed first and the
panel responded in the bubbling phase.
Typically, during the capture stage event, listeners on the parent components aren’t called, but
there’s a version of the addEventListener()method that can request calling the listeners during the
capture phase. To turn on event handling during the capture phase, you should use the three-arguments
version of the addEventListener() function in the panel:
myPanel.addEventListener(MouseEvent.CLICK, panelClickHandler, true);
When the third argument equals true, it tells the Flash Player that we are registering this particular
listener for the capture phase (there’s no way to do this in MXML). Now run the application through
the debug mode again and you’ll see that the panel responds first, then the target button. There’s
no event processing in the bubbling phase.
click event in the Panel
click event in the Button
CHAPTER 4
RIA WITH ADOBE FLEX AND JAVA 145
If you’d like to process parent events during both the capture as well as bubbling phase, register two
listeners for the panel - one with the three arguments and one with two. These listeners
myButton.addEventListener(MouseEvent.CLICK, buttonClickHandler);
myPanel.addEventListener(MouseEvent.CLICK, panelClickHandler, true);
myPanel.addEventListener(MouseEvent.CLICK, panelClickHandler);
will produce the output proving that the panel has processed the button click event twice: during
both the capture and bubbling phases.
click event in the Panel
click event in the Button
click event in the Panel
Let’s make a change in the panel event handler to show how you can prevent the event from being
delivered to the target if something bad has occurred (from a business application perspective):
private function panelClickHandler(event:MouseEvent) :void{
var badNews: Boolean = true; // a flag to emulate a bad situation
if (event.eventPhase == EventPhase.CAPTURING_PHASE){
trace (”Capturing phase: click event in the Panel”);
if (badNews){
trace (”Capturing phase: Bad news. Will not propagate click to But
ton”);
event.stopPropagation();
}
}else {
trace (”click event in the Panel”);
}
}
The stopPropagation() method can be called at any phase of the event flow. The line
myPanel.addEventListener(MouseEvent.CLICK, panelClickHandler);
means “listen to the click event, and when it’ll occur, call the function panelClickHandler.”
Handling events was so much easier in MXML…
Why do we even need to know about these addEventListener() function calls? Well, first, there are
some classes that don’t have equivalents in MXML, hence you don’t have a choice. Second, if your
program is adding components dynamically, addListener() is your only choice since there’s no way to
use MXML notation there. And third, you may prefer writing your components only in AS3.

05
Jul

Adding a Data Feed

In the real world, all the messages should be pushed to our application by some kind of messaging
program. Another possibility is to have the gas station front end poll the data at some specified
interval by some kind of a server-side program that can be written in JSP, ASP, PHP, or whatever else
can bake an HTTPResponse. In coming chapters of this book, you’ll learn about various ways to
communicate with remote programs. But at this point, for simplicity’s sake, we’ll emulate a realtime
data feed by using a random-number generator and a timer that will add items to our msgList
collection at specified time intervals. Since the data collection will be constantly receiving new
data, the output window should reflect this by adding new rows to the data grid.
If the speed of your data feed is crucial, don’t pass the data as XML, and consider using ArrayCollection
for storing data instead of XMLListCollection.
Here’s the final code for the application:
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
backgroundColor=”#e0e0FF” applicationComplete=”init()”>
<mx:XML id=”msgTypes” source=”MessageTypes.xml” />
<mx:XML id=”activities” source=”GSactivity.xml” />
<mx:XMLListCollection id=”msgList” source=”{activities.message}” />
<mx:Canvas x=”10″ y=”10″ width=”100%” height=”100%”>
<mx:HBox x=”10″ y=”20″ width=”100%” height=”30″>
<mx:CheckBox id=”cbx93″ label=”93″ selected=”true” click=”refreshData()”/>
<mx:CheckBox id=”cbx89″ label=”89″ selected=”true” click=”refreshData()”/>
<mx:CheckBox id=”cbx87″ label=”87″ selected=”true” click=”refreshData()”/>
<mx:Label text=”Msg.Type” />
<mx:ComboBox id=”cbMsgTypes” width=”117″ dataProvider=”{messageType}”>
<mx:change>refreshData()</mx:change>
</mx:ComboBox>
</mx:HBox>
CHAPTER 4
RIA WITH ADOBE FLEX AND JAVA 135
<mx:VBox x=”10″ y=”64″ height=”100%” width=”100%”>
<mx:Label text=”Activity” width=”100%” fontSize=”15″/>
<mx:DataGrid id=”messageBook” dataProvider=”{msgList}” width=”100%”
height=”100%” change=”getAction()”>
<mx:columns>
<mx:DataGridColumn headerText=”Message Type” dataField=”@msgType”/>
<mx:DataGridColumn headerText=”Transaction ID” dataField=”transID”/>
<mx:DataGridColumn headerText=”Octane” dataField=”octane”/>
<mx:DataGridColumn headerText=”Price per gal.” dataField=”price”/>
<mx:DataGridColumn headerText=”Amount(gal.)” dataField=”gallons”/>
<mx:DataGridColumn headerText=”Paid” labelFunction=”paid”/>
<mx:DataGridColumn headerText=”Paid by” dataField=”paidby”/>
</mx:columns>
</mx:DataGrid>
<mx:Label text=”Required actions” fontSize=”15″ />
<mx:TextArea id=”txtAction” width=”100%”/>
</mx:VBox>
</mx:Canvas>
<!–Defining USD formatting –>
<mx:CurrencyFormatter id=”usdFormatter” precision=”2″
currencySymbol=”$” useThousandsSeparator=”false” alignSymbol=”left” />
<!– Gallons Amount formating with 2 digits after dec.point –>
<mx:NumberFormatter id=”numberFormatter” precision=”2″/>
<mx:Script>
<![CDATA[
//Message type combo data
[Bindable]
private var messageType: Array = [”all”,”sale”, “spill”, “purchase”];
import mx.collections.*;
private var sortMessages:Sort;
[Bindable]
private var grandTotalSale:Number=0;
private function init():void {
Learning Flex Through Applications
136 RIA WITH ADOBE FLEX AND JAVA
// assign the filter function
msgList.filterFunction=filterMessages;
// perform filtering
refreshData();
// emulating message feed in specified intervals
var myTimer:Timer = new Timer(5000, 0); // every 5 sec
myTimer.addEventListener(”timer”, addMessage);
myTimer.start();
}
private function filterMessages(item:Object):Boolean{
// filter by message types
if (cbMsgTypes.selectedLabel !=”all” &&
item.@msgType!=cbMsgTypes.selectedLabel ){
return false;
}
// Check every checkbox and the combobox and
// populate the datagrid with rows that match
// selected criteria
if (item.octane==”87″ && this.cbx87.selected)
return true;
if (item.octane==”89″ && this.cbx89.selected)
return true;
if (item.octane==”93″ && this.cbx93.selected)
return true;
return false;
}
private function paid(item:Object, column:DataGridColumn):String {
// calculate total gain/loss. Label function is not
// the best place for calculations as it’s being called
// on each change of the underlying collection
var total:Number=Number(item.gallons)* Number(item.price);
if (item.@msgType!=”sale”){
total*=-1;
}
return “”+usdFormatter.format(total); //USD formatting
}
private function getAction():void {
CHAPTER 4
RIA WITH ADOBE FLEX AND JAVA 137
txtAction.text=msgTypes.message.(@type==messageBook.selectedItem.@msgType).
actions;
}
private function refreshData():void{
msgList.refresh();
txtAction.text=”";
}
private function addMessage(event:TimerEvent):void{
// create and add one message with randomly-generated
// values to the collection
var newNode:XML = new XML();
var transID:String=Math.round(Math.random()*5000).toString();
var octanes: Array = [”87″, “89″, “93″ ];
var octaneIndex:Number=Math.round(Math.random()*2);
var octane:String=octanes[octaneIndex];
var prices: Array = [2.49, 2.69, 2.99 ];
var price:Number=prices[octaneIndex];
var msgTypes: Array = [”sale”, “purchase”, “spill”];
var msgType:String=msgTypes[Math.round(Math.random()*2)];
var payTypes: Array = [”MC”, “Visa”, “Cash” ];
var payType:String=msgType==”sale”?payTypes[Math.round(Math.random()*2)]:”";
var gals:String=(numberFormatter.format(Math.random()*50).toString());
newNode=<message msgType={msgType}>
<transID>{transID}</transID>
<octane>{octane}</octane>
<price>{price}</price>
<gallons>{gals}</gallons>
<paidby>{payType}</paidby>
</message>;
// adding new messages always on top
activities.insertChildBefore( activities.message[0], newNode);
}
]]>
</mx:Script>
</mx:Application>




 

July 2008
M T W T F S S
« Jun   Aug »
 123456
78910111213
14151617181920
21222324252627
28293031  

Badge Farm

  • Textmate