360|Flex and AMP
If you haven’t the chance to participate in a 360|Flex conference, you can watch 15 sessions from one event using AMP (Adobe Media Player). It is very simple:
- Install AMP
- Click “My Favorites” menu at the top.
- Click “Add RSS Feed” at the bottom.
- Paste: http://sessions.onflex.org/1733261879.xml
Enjoy!
Do you want a ticket to "Flash on the Beach" for free?
Between 28th September - 1st October it will be the Flash on the Beach conference in Brighton, UK. This is the third edition and it is a conference that you shouldn’t skip. Now, you have the chance to win a free ticket (a £499/€633 value). You have to send us a photo that is with you, and has a beach theme, and shows the love for Flash/Flex/AIR. And we will choose the winners - because we have 6 tickets to give it away!
Serje Jespers is collecting the photos via his blog. And each one of the six European platform evangelists will choose one winner: Andrew Shorten, Enrique Duvos, Serje Jespers, Cornel Creanga, myself and Mihai Pricope. We will announce the winners starting with 8th September.
Good luck people, and start making photos if you don’t have!
Paging a Data Grid on the client
My wife says that lately I have become obsessed, with data grids. Well, who am I kidding? While my wife is a psychologist and she does care about obsessions, she doesn’t care about Flex components. Anyway, the first time I saw a Flex data grid filled with items I asked myself: “What if I need to display more than 20 rows of data at the same time?” What visual hints, what UI should I use, to give the viewer a sense of what items he is looking at, how many there are left to see, and so on. Let’s take a look at it; here’s a data grid filled with a lot of data:
When I was a web developer with InterAKT Online, I worked on a product called NeXTensio list. This product was an extension for Dreamweaver, and it was used for generating lists from a table or from a query, and it provided navigation buttons and other visual items to help you view and edit the list items.
So, it is no wonder that, as soon I had some time to play, I started to build a Flex component that adds some interesting behavior to a data grid. You can see here the whole thing put it together, and you can download the project from here (in the root of the ZIP file there is a readme.txt file that explains how to setup the project). About my application:
- using a HTTPService, it reads all the data from the database; my example uses a MySQL table with 5.000 rows
- it displays the data using a data grid
- users navigate through the data grid using my custom component; the component adds buttons for navigating from page to page (where a page is the number of items you can view at the same time in the data grid), or you can directly navigate to the last/first page
- my custom component display some statistics on top of the navigation buttons (so you know what dataset are you looking at, and how many items there are)
- you can use the data grid toolbar, and in this case as you move around, the buttons and statistics are updated (just use the mouse or the keyboard to scroll the data grid, and you will see the buttons changing)
Here is a screen shot of the application:
How did I do it? Well, it wasn’t hard, but neither was it easy. The whole paging component is a custom Flex component (see the Paging.mxml file). All it needs is a reference to the data grid to which you want to add paging. You can configure how many buttons to render at the same time for moving through pages (I used 5 in my example). The trickiest part was to find how many items are displayed at one time in the data grid. When a data grid is initialized, the property rowCount from the data grid is 7, regardless of how many items are in the data grid. So, I need to have a listener registered on the data grid that it is triggered when rowCount changes. Because I couldn’t find an event for this, I ended up extending the data grid (see the MyDataGrid.mxml file) and I over-wrote the method setRowCount, to dispatch an event when rowCount changes.
For the rest of the story, have a look at the code and play with it. But please, don’t forget it isn’t production quality code, it’s just a proof of concept. Have fun!
LiveCycle Data Services 2.6 - new features
As you probably know, LCDS 2.6 was released last month. If you are not sure what new features it brings, or you want a more detailed description of them, you can look to my friend, Cornel Creanga, Blog posts here and here.
"30onMAX" or how to be in the MAX Keynote
If you want to be in the MAX Keynote, keep reading:) Adobe is putting together a video project of your videos called “30onMAX”. The selected videos will be used in MAX Keynote in San Francisco, Milan and Tokyo. To get there, you need to create a video on Why MAX?, upload the video on Youtube.com and tag it with “30onMAX”.
Duane’s World Episode 8
My friend Duane Nickull, (if you don’t know him, take a look at his blog), released episode 8 of his show. In this episode, you can watch interviews with Tim O’Reilly, John Markoff, Dries Buytaert and Bob Glushko.
Functional Testing Framework for AIR AJAX apps based on Selenium
My friends from the Romanian Adobe AIR team have been very busy lately. Marius and Alex have been working on, was to modifying Selenium so you can run automated / functional tests on AIR applications developed with HTML/JS.
To be honest, I am quite amazed about what they managed to pull off in so little time. And because we need your feedback, I have an archive ready for download here, so you can start playing with it in minutes. Here is what it is in ZIP:
- demo movies - two movies that show you the workflow supported for now
- sample tests - this is the interesting part. You have two applications and some tests files to test these applications with this framework. The first test uses a Selenium based model for dispatching UI events, the second uses a Java AWT robot to generate mouse and key events.
- selenium recorder - this lets you record your UI interaction with the application. Then with a little editing on the resulting test files you can create the test cases for your automated testing.
- selenium server - this is the heart of this framework. It acts as a proxy between the requests that are made from tests and the AIR application.
- readme.txt - for a quick start on trying the samples; this files describes how to create a Java project and run the tests from Eclipse as a JUnit Test Case.
- SeleniumWithAIR.pdf - the first draft of documentation for this framework, which includes the known issues.
It should work on Win and Mac, with Java 1.5 or newer and AIR SDK 1.1.
Here is a short explanation of how to quickly run the tests from the ZIP file:
- Download the ZIP, and unzip somewhere on your disk
- Create a system variable named ADL_EXE and set its value to the full path of the “adl” executable from your local AIR SDK

- Start the server: selenium/selenium server/runServer.bat

- Run the tests: selenium/sample tests/runTest.bat


Here is a snapshot of the Eclipse project to run the tests from the ZIP:
So, that’s it! Try these goodies and let me know what you think!
Extending ActionScript classes to provide AsyncToken like behavior
When you use a class from the Flex framework that does an asynchronous call, you can use the AsyncToken that the call returns to save values/objects that you need when the result event is triggered.
Let’s look at this code:
private function getData():void { //create a new HTTPService var myService = new HTTPService(); //add event listener for result myService.addEventListener(ResultEvent.RESULT, resultListener); //save the async token var token:AsyncToken = myService.send(); //add to token our own data token.myData = {name: “john doe”, id : 1}; } private function resultListener(event:ResultEvent):void { //retrieve from event.token our data myData:Object = event.token.myData; }
So, we have two functions. The first, getData() creates a HTTPService, attaches an event listener for the result event, and then makes a call to the server. When it makes a call, an AsyncToken is returned. I can use this token to store some info I need in the result listener. The second function is the definition of the result listener. When this function is called, you can access the AsyncToken from the property token from event: event.token. Having the token, it is easy to retrieve the data that I stored when I made the call to the service.
Why is that useful? Sometimes you want to be able to associated some data to a particular call, so when result event is called, you are able to take a different actions based on the data passed.
Unfortunately, when you do a call to a class from Flash, for example, flash.net.URLLoader you don’t have this AsyncToken returned. Consider the following code:
var loader:URLLoader = new URLLoader(); loader.addEventListener(Event.COMPLETE, completeListener); //this line does not working; the load() method is not returning anything var token = loader.load(new URLRequest(”http://mysite/pic.png));
How do you pass your data between the call and the result for objects that are not using AsyncToken? One simple way is to extend the object you want to use, and add one property to store an object. Let’s do this for the URLLoader class:
public class MyLoader extends URLLoader { private var _data:Object; public function MyLoader(data:Object) { super(); this._data = data; } public function get data():Object { return this._data; } }
Now, let’s see how you can use this object to do asynchronous calls and still be able to pass data:
var myData:Object = {name : “john doe”, id : 9}; var loader:MyLoader = new MyLoader(myData); loader.addEventListener(Event.COMPLETE, completeListener); //make a request for an item from server loader.load(new URLRequest(”http://myste/pic.png)); //complete listener for loader private function completeListener(event:Event):void { //retrieve the loader instance var myLoader:MyLoader = event.target; //retrieve the data object var myData:Object = myLoader.data; }
When I create the custom loader object, I pass a reference to the data object that I want to retrieve when the loader has the response (this object is stored using the _data property from MyLoader). When the complete event is reached, using the target property on the event object, I retrieve the MyLoader object that made the call . Having the loader object, I can access the data property to retrieve the original data I stored.
ScaleNine "Skin to Win Challenge" - contest for Flex themes
If you know how to skin Flex apps, and you need one of these: Macbook AIR with SSD, Creative Suite 3, Flex Builder Professional or a ticket to MAX 2008, just go here and submit your best themes for Flex, and you might win!
How to change the UI of a Data Grid at runtime
Some times you want to change the appearance of a data grid column or a cell at runtime. Maybe you want to react to a mouse click on a row/cell and you want to change the model behind as well as the UI presentation.
The single way to change the display of a list control (data grid, list, menu, and tree are all list controls) in Flex is to use item renderers. Each list component from Flex has a default renderer. For example, data grid has a default renderer called DataGridItemRenderer, which assumes that the data you want to display are text. When you want to display the data as something other than text, you need to create your own item renderer and then set the data grid to use your item renderer.
Item renderers act as a view for your data. And because they are not actually holding your data if your data grid displays 50 elements and you can see only 10 in the same time, it will create about 10 and reuse them as you scroll up and down. Reusing the item renderers is more efficient than creating all the item renderers for rows that are not in the current view.
The simplest way to create a custom item renderer for your data grid is inline. Using the tag mx:itemRenderer and than mx:Component you can declare any components from Flex you want. In order to get the data for the current row you use the “data” property. In the following example I create a custom renderer out of a VBox that hosts two other components: a label and a image. And to retrieve the “src” property for the current row I use this syntax: “data.src”.
<mx:DataGrid dataProvider=“{myData.item}”> <mx:columns> <mx:DataGridColumn> <mx:itemRenderer> <mx:Component> <mx:VBox> <mx:Label text=“{data.src}” /> <mx:Image source=“{data.src}”/> </mx:VBox> </mx:Component> </mx:itemRenderer> </mx:DataGridColumn> </mx:columns> </mx:DataGrid> <mx:Model id=“myData”> <root> <item> <src>pic1.jpg</src> </item> <item> <src>pic2.jpg</src> </item> </root> </mx:Model>
In order to use a component as an item renderer and to be able to bind the “data” property to it, the component must implement this interface: mx.core.IDataRenderer. Most Flex components implement this interface and this is why my previous example worked. However, if you create your own UIComponent and you are not extending a Flex component you will need to implement the interface IDataRenderer.
Now, depending on your use case, you might want to:
- change the appearance of an entire column from your data grid
- change just one cell from your data grid
As usual I created a sample project. At the end of this article you can find a link for testing the code (you can right click on the page and choose view source from the contextual menu) and one for downloading the project.
Changing the appearance of an entire column
This is the easie of the two task. Suppose I want to change the appearance of the whole column when some one clicks on the data grid. First I will create two item renderers, one for each view of the column. Then I assign to the data grid the default item renderer for the column I want to customize. Next I attach an click item event listener on the data grid and inside of this event listener I switch the default item renderer with the second one. For fun I use a flag, to toggle the views. The interesting code is the event listener function. You don’t set directly the new item renderer to the column itemRenderer property. Instead, you set the item renderer that you want to be used wrapped in a ClassFactory object. This object it is used to generate instances of the given type with identical properties.
/** * @var flag to keep track of what item renderer to use for the first data grid */ private var toggle:Boolean = false; /** * Event listener registered for the first data grid for Item click events. * It changes the item renderer for the second column of the data grid * @param event */ private function clickCell(event:Event):void { if (!(event is ListEvent)) return; //retrieve the data grid object var grid:DataGrid = (event as ListEvent).target as DataGrid; //using the columns array from the data grid, we change the item renderer for the second column //by assigning a different item render for the “itemRenderer” property of the column if (!toggle) (grid.columns[1] as DataGridColumn).itemRenderer = new ClassFactory(ItemRenderer1); else (grid.columns[1] as DataGridColumn).itemRenderer = new ClassFactory(ItemRenderer2); toggle = !toggle; }
Changing the appearance of one cell
If you want to change just one cell, you can’t switch the renderers as this action will change the whole icon. Instead you can create your custom item renderer with different states, one for each different view you want. The default state will be the one you want to be displayed by the data grid when the data is loaded. To change the state for a given item renderer, you change the data displayed by the row. And in your renderer you evaluate the data to decide what view to display. Here is the code for item renderer:
<?xml version=“1.0″ encoding=“utf-8″?> <mx:VBox xmlns:mx=“http://www.adobe.com/2006/mxml” horizontalAlign=“center”> <mx:Script> <![CDATA[ import mx.events.FlexEvent; /** * over ride the set data function in order * to control the states we want to display */ override public function set data(value:Object):void { if (value != null) { super.data = value; if (value.showProgresBar) { currentState = "loading"; } else { currentState = ""; } // Dispatch the dataChange event. dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE)); } } ]]> </mx:Script> <mx:states> <mx:State name=“loading”> <mx:AddChild position=“lastChild”> <mx:ProgressBar indeterminate=“true”/> </mx:AddChild> </mx:State> </mx:states> <mx:Label text=“{data.price}” /> </mx:VBox>
Remember when I said that most of the Flex components implements IDataRenderer? By over riding the setter method, I am able to control what state I want to display.
The code that modifies the data model is inside of the event listener registered for the data grid item click event. It retrieves the data object from the item renderer, and because this object is of type Object, I can set dynamically a property. In this case, I add “showProgresBar” and I set to true. As the data provider is bindable and I just change one item, the set data method is called on my item renderer for each row from the current view. This gives me the opportunity to check the presence and the value of this flag and to switch the state.
/** * The listener for click item event for the second data grid. * It changes the appearance of the cell, by changing the data model, * which in turns it is used by the custom item renderer to decide * what state to display. * @param event */ private function clickCell2(event:Event):void { if (!(event is ListEvent)) return; var ev:ListEvent = event as ListEvent; //retrieve the data object associated with the current row var data:Object = ev.itemRenderer.data; if (data["showProgresBar"] == null || data["showProgresBar"] == false) { //set the showProgresBar to true to change the UI of the cell data.showProgresBar = true; } else { //set the showProgresBar to false to change the UI of the cell data.showProgresBar = false; } }
The wrong way
You may be tempted to try another approach to change the appearance of a cell: to retrieve the item renderer of the cell you clicked on and directly inject into it new components. This is the wrong way to do it. For a instructional purposes, I included in an example along these lines in my project, and you can test it. In some cases will its seems to work, but remember that the data grid reuses the item renderers when you scroll down. So if you click on the first row, a progress bar is inserted in the second cell from the row, and as you start scrolling down, you will see other cells with the same progress bar (this is because of renderer reuse).
You can test this code here and you can download the project from here (choose Import > Flex Builder > Flex Project wizard to import it into Flex Builder).
