Monday, February 4, 2008

Using Remote Objects

Using remote object can be tedious and confusing if you want to do it from the scratch and want to understand everything at once. A better approach is to have something that works and build on it, understand it bit by bit. I used this approach for Tomcat but this should work well for any J2EE container like Websphere or JBoss. I am not focussing on Remote Object basics or RMI here, just how you can make it work for yourself for Java.


Download Adobe LiveCycle Data Services ES from:

http://www.adobe.com/products/livecycle/dataservices/

Install it for J2EE and not for integrated JRun. We will be using the express version. Alternatively you could use BlazeDS. To see the differences between the two visit this link:

Differences between Flex Data Services Express and BlazeDS

Please remember that using either means that you will have to buy it at some stage for commercial applications. See the respective licence for details. That being said these services are extremely useful and without them Flex looses a lot of utility.


  • The installation folder contains many things that you will be using as you understand flex more. For time being our interest lies in a file by name flex.war
  • Take flex.war and unzip the contents into a folder. Name it apporpriately. This folder will be your template for a blank flex application that you may want to develop on your server.
  • Take this skeleton folder and copy in the webapps directory of your Tomcat.
  • Browse to WEB-INF/flex folder. Open a file named license.properties and add license keys (ie if you have one) for flex builder, flex charting and flex data services.
  • In the same folder open file services-config.xml and see the security tag. Uncomment the line for tomcat server and comment the rest.
  • Open Flex builder. Go to File->New->Flex Project. Choose Flex Data Services for data access and compile application on the server when the page is viewed. Click Next. Browse to the folder in tomcat webapps where you are hosting the skeleton app. Validate location and name the root URL and context root appropriately. Click Next. Give an appropriate name to your project and click Finish.
  • You have set up the stage to use Remote Object.

    Now, copy the java class you intend to use in the appropriate directory under WEB-INF/classes. Lets say we have a class file from your compiled java file called MyRemoteObj.class made from this file:

    package app;

    public class MyRemoteObj{

    public String getMessage(){ return "hello"; }

    }

    Browse to WEB-INF/flex and open remoting-config.xml. Make sure it looks something like this:

    <?xml version="1.0" encoding="UTF-8"?>

    <service id="remoting-service" class="flex.messaging.services.RemotingService">

    <adapters> <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/>
    </adapters>

    <default-channels>
    <channel ref="my-amf"/>
    </default-channels>

    <destination id="responder">
    <properties>
    <source>app.MyRemoteObj</source>
    <scope>application</scope>
    </properties>
    </destination>

    </service>

    Remember this xml file is just one of the files uploaded by services-config.xml. It just helps in breaking our config xml into usable parts. <adapters> define the backend object. <channels> are defined in service-config. Here we just specify the channel we intend to use. destination is the part that helps flex use the remote object. id is ised to refer to it. source is its location under the WEB-INF/classes directory.

    Declare your remoter object in the MXML as

    <mx:RemoteObject id="remoteObjRef" destination="responder" fault="handleFault(event)" result="handelResult(event)"/>

    Use the id in AS to call the methods directly on the object: remoteObjRef.getMessage();

    Monday, January 28, 2008

    Pondering on AJAX and Flex

    After working with Flex and AJAX for some time I feel like looking back and asking myself when I should use what. My opinion is this:

    I think AJAX, more specifically yui, can be used for most of the web-applications. It is simpler to use and written pretty well.

    However if we need controls with interactive graphics/charting data or we have a very big and complex application, flex would be a better option.

    Lets face it, flex is more powerful and easy to develop (and maintain) of the two. However it has its learning curve and people with good flex skills & strong programming basics are not that easy to find. If your application is indeed that complex and demands a high degree of interaction and/or analytics, flex is a wise decision. Else it is like using a hammer to kill a fly. It is good but you dont have to use it if you dont need it :).

    DataGrid Rendering

    The default editing control for an editable column is a text field. It is possible to specify the editor via itemEditor attribute and editorDataField. Following controls can be specified:

    Button, Label, CheckBox, NumericStepper, ComboBox, Text, DateField, TextArea, Image, TextInput

    You can also specify your own control as long as it implements IDropInListItemRenderer interface in its class definition

    Item renderers can be used to customize looks of individual columns.

    One way is to make a custom renderer (say using Canvas) as an MXML component and giving the appropriate DataGridColumn the full-qualified path to itemRenderer property. Remember that the data property will help you in the renderer to access row data.

    Another way is using
    tag. Efficient but not modular. Inside the renderer tag you will have to place tag. What is inside this tag will have its own scope, will need its own imports. You can talk to the containing app using outerDocument scope. But the properties you wish to access have to be public.

    labelFunction signature for DataGrids is:

    labelFunctionName(item:Object,dataField:DataGridColumn)


    Wednesday, December 19, 2007

    Introduction to Datagrids

    Datagrids give largest possible options for user to interact with data. This brings performance and size overhead to be kept in mind.

    Use editable property to make the grid uneditable. draggableColumns property used to enable/disable column resizing (true by default). variableRowHeight property used to tell Flex to resize row's height according to renderer. The columns for the grid can be specified within <mx:columns> tags. Useful when we want the order of columns to be different from what is received.

    Each column is specified using <mx:DataGridColumn> tag. Use its dataField property to specify the field to use to populate, headerText to give column header and editable to determine if it is editable (The parent grid has to be editable for this).




    <mx:DataGrid id="myGrid" editable="true" draggableColumns="false">
       <mx:columns>
          <mx:DataGridColumn dataField="field1" headerText="Field1 Data" editable="false"/>
          <mx:DataGridColumn dataField="editableField" headerText="Input"/>
       </mx:columns>
    </mx:DataGrid>


    Q&A
    1. How can you make a DataGrid editable?
    2. How do you control column resizing in a DataGrid?
    3. What will you do if you want the order of columns to be different from the order of data received in a DataGrid?
    4. Briefly explain the steps involved in initializing a column in a DataGrid.

    Monday, December 17, 2007

    And Then There Was AIR

    Kapil and myself have started exploring AIR by Adobe (code-named Apollo) and, man, is it exciting or what. For more, see:

    http://labs.adobe.com/technologies/air/

    I will be back with more :).

    Wednesday, December 12, 2007

    Datasets: Using Repeater

    We can loop over a data set in MXML using a Repeater component. General syntax for Repeater is:

    <mx:Repeater id="myRepeater" dataProvider="{someColl}"> </mx:Repeater>

    It will loop once for each object in the data set. currentItem property is reference data item being processed. currentIndex property is a zero-based counter indicating position of the current item in the data set. But these will be useful only during looping.

    After the looping is finished we need to get data from the items that may have been created dynamically inside the Repeater. For this Repeater has getRepeaterItem() method that returns the item in dataProvider property that was used to make the item as an Object type. This can be used on the appropriate event (say click). The code would look like:

    <mx:Repeater id="myRepeater" dataProvider="{someColl}"> <mx:RadioButton label="{myRepeater.currentItem.name}" click="someFunc(event.target.getRepeaterItem())"/>
    </mx:Repeater>

    The properties of the object this obtained can be used as desired.


    Another issue is addressing the components created using Repeater. You give an id in the loop. Flex will create an array of the items created by the name of the id. Using the array index individual items may be accessed. The code

    <mx:Repeater id="myRepeater" dataProvider="{someColl}"> <mx:RadioButton label="{myRepeater.currentItem.name}" id="myrb" click="someFunc(event.target.getRepeaterItem())"/>
    </mx:Repeater>

    will create array myrb. Individual information may be accessed using index as
    myrb[0].label

    TileList control instantiates objects when they are displayed whereas a Repeater inside a Tile container instantiates all the objects in the entire dataset, whether they are initially displayed or not. Depending on size of data, this may delay rendering on the flash player. However scrolling will be better once the page loads in this case as everything is there. If dataset is small, difference will not be noticable. But for bigger sets one has to think and decide.

    Q&A

    1. Why would you use a Repeater component?
    2. How can you get data from the items that may have been created dynamically inside a Repeater?
    3. Ho do you address the components created using a Repeater?
    4. What is the alternative to using Repeater?
    5. What is the difference between using a TileList control and a Repeater? How will you decide when to use what?

    Tuesday, December 4, 2007

    Flex Components: Understanding Containers

    Flex containers consist of two distinct sections: layout area where the children are drawn and chrome area which has borders, backgrounds, margins, scrollbars,headers, footers etc. In Panel class title bar is implemented as chrome.

    The base class flash.display.DisplayObjectContainer does not make any distinction between child components and chrome. But the mx.core.Container class (superclass of all Flex containers) overrides several methods including getChildAt() and numChildren() to give the appearance that the container's only children are child components. To gain access to all elements we need to use the rawChildren property. In panel anything added using addChild() will be rendered below title bar. To add elements to title bar you will need to use this property. eg: rawChildren.addChild(myButton);

    However this will only add but not size/position the children in the chrome. To do that we need to override the updatedDisplayList() method. This is called everytime the component is redrawn. Be sure to call super.updatedDisplayList() so as the correct rendering happens for the rest of the component. The method is passed two attributes, unscaledHeight and unscaledWidth, which are the actual height and width of component regardless of any scaling.

    Q&A
    1. What do you understand by chrome?
    2. How can you customize the title bar of a Panel class?