Friday, September 5, 2008

Developing mobile applications using Gear episode 2: Start using gear widgets and events

The previous episode of this tutorial covered all the necessary steps to setup a development environment for J2ME applications using Eclipse, EclipseME end Gear.
The previous instructions (available here) are still valid except for the Gear framework version since a new release is now available for download (Gear 1.0.0) .
This tutorial will cover the basic steps required to develop a simple application displaying two forms using Gear widgets system end its event based paradigm.
At the end of this tutorial you will have produced an application like the one you can see in the following screen shots:


Step 1: Create the first GearMidlet
In the step 3 of the previous tutorial we have created an empty J2ME application (midlet suite) and we have added Gear to it.
The midlet suite itselft is not a real application, it's a container for one or more midlet and each midlet is potentially a completely independent application, however most of the midlet suites available contain just one midlet thus a midlet suite is commonly considered equivalent to a mobile application.
Anyay, to start developing our application, we need to create a midlet that will be considered the execution entry point of our midlet suite.
  • Enter the "New->Other" menu and select "J2ME Midlet"
  • Enter the midlet name, the package and change the superclass to "gear.application.GearMidlet"
  • Now you have the midlet created it still does nothing but you can try executing it by right clicking on it and selecting "Run As->Emulated J2ME Midlet" as shown in the following screen shot.


NOTE: In order to continue developing the application of this tutorial it is necessary to add this icon to the "res" folder of your project.

Step 2: Create two forms using GWGrid and GWList
To crate a form using Gear Widgets system simply create a class and inherit one of the available form types.
In Gear version 1.0.0 there are four forms already implemented (GWText, GWGrid, GWList and GWScrollableList) each of these forms can be extended to add any functionality and new forms can be created by extending GWCanvas and GWForm classes.
In this article we'll learn how to display two forms containing 4 items using GWGrid and GWList classes.
  • First we have to create two classes and make one inherit from GWGrid and the other one from GWList, the two classes should look similar to these two:
    public class TestGWGrid extends GWGrid{
    public TestGWGrid() {
    super();
    }
    }
    public class TestGWList extends GWList{
    public TestGWList() {
    super();
    }
    }
  • Now we have to fill both classes with the items to be displayed and we have to set the title and the title icon, to do so we have to put the following code in the TestGWGrid constructor:
    // Constructs the grid with 2 rows and 2 columns
    super(2,2);

    // Set the Grid to stretch properly the icons
    setStretchIcons(true);

    // Add four items to the Grid
    addItem("Item 0", "/digitalapes.png");
    addItem("Item 1", "/digitalapes.png");
    addItem("Item 2", "/digitalapes.png");
    addItem("Item 3", "/digitalapes.png");

    // Set the grid title
    setTitle("TestGWGrid");

    // Set the grid title icon
    setTitleIcon("/digitalapes.png");

    and the following code in TestGWList constructor:

    super();

    // Set the List to stretch properly the icons
    setStretchIcons(true);

    // Add four items to the list
    addItem("Item 0", "/digitalapes.png");
    addItem("Item 1", "/digitalapes.png");
    addItem("Item 2", "/digitalapes.png");
    addItem("Item 3", "/digitalapes.png");

    // Set the list title
    setTitle("TestGWGrid");

    // Set the list title icon
    setTitleIcon("/digitalapes.png");
    Setting title and title icon is not compulsory, if none is set the top bar is not displayed

  • Finally to interact with the user we'll add two commands to the forms and we'll intercept these commands.
    To do this we have to add the following code at the end of both constructors:
    // Add two commands
    addCommand(CommonCommands.NEXT);
    addCommand(CommonCommands.EXIT);

    // Add this class as a command listener
    addCommandListener(this);
    And both classes have to implement the "GWCommandListener" interface this way:
    public void commandAction(Command command, GWCanvas sender) {
    if (command == CommonCommands.NEXT){
    // Do something
    } else if (command == CommonCommands.EXIT){
    // Do something else
    }
    }
Step 3: Connecting everything using events
The Gear architecture is based on a multi threading paradigm, so, to permit easy thread to thread communication, Gear provides an event based communication system.
Each event is an object of a class inheriting from the "Event" class, an event may be dispatched by any object and caught by any other.
Dispatching an event requires simply to call the method "enqueueEvent" of the "EventManager" singleton.
Catching an event is a bit more complicated: the class which wants to catch the event should implement the "EventHost" interface and should register to the "EventManager" using the "registerHost" method.
By default the GearMidlet catches the "Quit" and the "DisplayWidget" events. When receiving the first one the midlet will call the "onDestroy" callback and will quit the application if the return value is true. When receiving the "DisplayWidget" event the midlet will handle the eventual widget instantiation and will make the widget visible on screen and active.
  • To start a widget on midlet start we'll have to dispatch a "DisplayWidget" event in the midlet constructor.
    public TestGearMidlet() {
    // This event requires the midlet to handle
    // instantiation of a TestGWGrid and display it
    EventManager.GetInstance().enqueueEvent(
    new DisplayWidget(this,TestGWGrid.class));
    }
  • To permit the user to exit and switch between the two forms we'll have to add the proper event dispatching functions in the command handling callbacks.
    In TestGWList command callback we'll have to put the following code:
    public void commandAction(Command command, GWCanvas sender) {
    if (command == CommonCommands.NEXT){
    EventManager.GetInstance().enqueueEvent(
    new DisplayWidget(this,TestGWList.class));
    } else if (command == CommonCommands.EXIT){
    EventManager.GetInstance().enqueueEvent(
    new Quit(this));
    }
    }
    And in TestGWGrid command callback we'll have to put this code:
    public void commandAction(Command command, GWCanvas sender) {
    if (command == CommonCommands.NEXT){
    EventManager.GetInstance().enqueueEvent(
    new DisplayWidget(this,TestGWList.class));
    } else if (command == CommonCommands.EXIT){
    EventManager.GetInstance().enqueueEvent(
    new Quit(this));
    }
    }
    This way, when the user will press the "Exit" command a "Quit" event will be dispatched and midlet will close.
    And, when the user will press the "Next" command a "DisplayWidget" event will be dispatched and the midlet will change the currently displayed forom.
Conclusions
The application we have just created shows the structure of a typical Gear based application and gives some examples of basic widgets handling.
It is possible to download the source code and the binary package of this application from this page.
In the next tutorial more advanced features of the Gear widgets system will be explained (like transitions, list and grid items customization, arrows and fire keys handling, themes, etc...), then the tutorials will focus more on the event communication system, the location abstraction layer and the other Gear functionalities.