Showing posts with label WTK. Show all posts
Showing posts with label WTK. Show all posts

Tuesday, February 3, 2009

Developing mobile applications using Gear episode 5: Display a splash screen

During the first phase of a MIDlet's life, it's common to find a lot of setup code used to initialize resources, data structures, user interfaces and anything else will be required. In this case, it's a best practice to display a splash screen to inform the user that the application is not frozen but is starting up. With the release of version 1.2.0 of Gear Java Mobile Framework, we've included a consistent yet customizable implementation for this feature.

1 How to achieve it ?
To properly setup Gear SplashScreen, all you have to do is create some keys inside the JAD file:
  • "SplashScreenImage:" -> contains a string with the path to the desired background image
  • "SplashScreenText:" -> contains a string with the desired text
If you are developing your application inside Eclipse with MTJ plugin (former EclipseME), you can easily achieve this by opening the Application Descriptor tab and "Add" the two key-value entries.


If your development environment is a different one, you have to manually insert those keys inside your application's JAD file.

As long as there is at least one of the two keys inside your JAD file, Gear will display the SplashScreen, so if you don't want it, simply don't specify anything.

2 Writing initialization code
Now that the SplashScreen is enabled, all you have to do is to override a single method inside your MIDlet
protected void onMidletInitializationComplete()
and fill it with your custom initializzation logic. We encourage users to follow this practice to put setup code inside this function rather than into the GearMIDlet constructor so they can take advantage from SplashScreen avoiding user interface freezes.
Here is an example of a possible implementation:
protected void onMidletInitializationComplete() {
// Call some custom initializzation methods
initDatabase();
doSomeHeavyDutyWork();
initUserInterface();
// ... and finally show the user the UI
EventManager.getInstance().enqueueEvent(new DisplayWidget(this, LoginForm.class));
}

3 The result
Gear's SplashScreen can display an image background, text and comes with an animated throbber centered vertically and anchored to the bottom of the screen. This is a possible result obtained with it:


Unfortunately this screen-shot is just a static image and you can't actually see the spinning animation of the throbber.

Thursday, January 29, 2009

Developing mobile applications using Gear episode 7: Work with EventManager and async messages

With this tutorial we're going to learn the basic concepts behind EventManager class and how we can send asynchronous messages across our Midlet with Gear Java Mobile Framework. To better understand this guide, we suggest you to read at least this post about configuring Eclipse and to download Gear's latest release (1.2.0).

1.0 EventManager:

Working with Gear in most cases requires to use EventManager class to dispatch asynchronous messages to other Objects within your MIDlet. It's implemented following the Singleton pattern so there will be only one instance of it during execution time and you can reference it wherever you want inside your code via public method getInstance(). Let's go on how to use this class and its methods.

1.1 Events

Every message you want to be forwarded through EventManager must derive from the abstract class Event. It contains the basic structure and methods to keep track of the sending Object and category. Here's an example:
public class ConnectionClosed extends Event {
// Public constructor with empty EventArgs object
public HideMidlet(Object sender){
super(sender);
}
// Public constructor with user defined EventArgs
public HideMidlet(Object sender, ConnectionClosedEventArgs eventArgs){
super(sender, eventArgs);
// Override of getCagegory method to return the desired type
public Category getCategory() {
return Category.APPLICATION;
}
}
1.2 EventArg

As you noticed in last example, you can assign some custom defined arguments to an event to pass on additional data to the receiving Object. To achieve this, you have to extend EventArg class and implement your own private fields along with proper getter and setters. Here's an example:
public class ConnectionClosedEventArgs extends EventArg {
private ConnectionStatus connectionStatus;

public ConnectionClosedEventArgs(ConnectionStatus connectionStatus) {
super();
this.connectionStatus = connectionStatus;
}

public ConnectionStatus getConnectionStatus() {
return connectionStatus;
}

where ConnectionStatus is a user defined class containing additional information about the reason for connection termination.

1.3 Dispatch events

This task is pretty simple. Suppose Object A wants to send some message to Object B (we'll see on the next poit how B will actually receive it). All it have to do is to obtain a reference to EventManager and enqueue the desired message, wrapped inside an Event object.
EventManager.getInstance().enqueueEvent(new MyEvent(this))
That's it. In this particular case, we're sending a MyEvnet (which derives from Event class) and we don't have to care about anything else. EventManager will internally manage our request and dispatch it. Notice we passed "this" parameter to the Event constructor to allow a reference of the original sender to be kept.

1.4 Register and receive Events

In order to receive an Event, an Object must first implement an interface named EventHost and thus it's only method
public void notify(Event event);
and secondly register itself to EventManager by calling
public void registerHost(EventHost host, Event.Category category)
where the second argument is one of the categories mentioned before. A class that is registered to at least one Event.Category will be notified of incoming messages. Whenever you need to unregister an Object from EventManager you can call
public void removeHost(EventHost host)
to totally remove it from the queue or
public void removeHost(EventHost host, Event.Category category)
if you just want to stop being notified for a specific category of events.


1.5 Events and GearMIDlet

By default, GearMidlet register itself to APPLICATION and GRAPHICS categories inside its base constructor, but if you need to be aware of more Events or less you can register/unregister from EventManager as seen in previous sections.

2.0 Putting it all together

With all the concepts from previous section, we can now create a GearMidlet with full support for asynchronous messages:


public class GearTouchDemo extends GearMidlet {

protected boolean onDestroy() {
return true;
}

protected void onPause() {

}

protected void onStart() throws MIDletStateChangeException {
// Enqueue a request to display MainMenu user interface
EventManager.getInstance().enqueueEvent(new DisplayWidget(this, MainMenu.class));
}

public class MainMenu extends GWGrid {
public MainMenu(){
super(2,2);
addItem("Photo browser", "/icons/c1.png");
addItem("Drops", "/icons/c2.png");
addItem("None", "/icons/c3.png");
addItem("Nothing here", "/icons/c4.png");
setTitle("Main menu");
addCommand(CommonCommands.SELECT);
addCommand(CommonCommands.EXIT);
setCommandListener(new MainMenuCommandListener());
}

public void itemClicked(ImageItem clickedItem) {
if (commandListener != null){
commandListener.commandAction(CommonCommands.SELECT, this);
}
}

public void selectElement(){
switch (getSelectedIndex()){
case 0:
// Enqueue a request to display MainMenu user interface
EventManager.getInstance().enqueueEvent(new DisplayWidget(this, PhotoBrowser.class));
break;
case 1:
// Enqueue a request to terminate the MIDlet.
EventManager.getInstance().enqueueEvent(new QuitEvent(this));
break;
default:
displayAlert("Function not implemented");
break;
}
}

}

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.

Thursday, July 24, 2008

Developing mobile applications using Gear episode 1: Create the first empty application

This is the first episode of a series of tutorials about developing mobile applications in J2ME using Gear framework. This tutorial will cover the first steps required to start developing any J2ME applications with or without using the Gear framework, the next tutorials will be more focused on Gear based applications. Every step of the tutorial has been tested on Windows Vista/XP and Ubuntu Linux, if you want to develop using MacOS, due to the lack of official Sun emulator, you should try MPowerPlayer or MicroEmulator tutorials.

Step 1: Obtain the required software
There are two IDEs suitable for J2ME development: Eclipse and NetBeans, this tutorial will cover the steps required to develop using Eclipse. The required software thus will be:
Download Eclipse IDE and Sun WTK from the links above and install both on your system. Installing Eclipse requires simply to extract the compressed package downloaded from the Eclipse site in a folder, typically "c:\Programs" on Windows or "/opt" on Linux. The Wireless Toolkit has a self installing procedure that will ask the user the target installation directory, again the typical directories are "c:\Programs" and "/opt".
If you plan to use Gear framework download the Gear jar and javadoc and put them in a directory of your choice (/opt in this tutorial).
We'll assume that after this step you'll have an Eclipse and a WTK directory in either one of the two directories listed above and eventually Gear files in the directory "/opt".


Step 2: Configure Eclipse and EclipseME
Now that you have installed the basic software it is time to execute Eclipse and configure it to support J2ME development.

  • First run Eclips and go to the plug in install section.
  • Select "Search for new features to install", click "Next" and add a new remote site.
  • Select finish and install the plugin.
  • Go to the preferences dialog and enter the "J2ME" section.
  • Enter the "Device Management" subsection, press the "Import" button, select the directory where you have installed the WTK before and press "Finish" button.
  • Now go to the "Java->Debug" section of the preferences and change the "Debugger timeout" value to 30000.
Now Eclipse is configured correctly to write, run and debug J2ME applications.

Step 3: Create an application and reference the Gear framework
Now it is time to create an empty J2ME application.
  • Enter the Eclipse "New" menu and select "Other".
  • Now create a new J2ME midlet suite, enter the name
    and press Next until you find the "Java settings" screen.
The following steps are optional, if you don't want to use the Gear framework just press "Finish".
  • Select the "Libraries" tab, press the "Add External JARs..." button and select the Gear jar file from the directory where you saved it.
  • Add JavaDoc to Gear: click "javadoc location" sub menu and press the "Edit" button.
  • Select Gear to be deployed within your application: enter the "Order and Export" tab, and click on Gear check box.
Now simply press the "Finish" button and you'll be ready to start programming your J2ME application.

Conclusions
The midlet suite we have created, is now ready to be filled with a set of midlets and all your application classes. In the next tutorials we'll describe how to create the midlets, how to display an interface, how to andle user's input and much more.