In my previous article on this topic, I discussed the foundations of the Java 2 Platform, Micro Edition (J2ME). If you're not familiar with that article, you should probably read it before delving into this one. The most crucial building block of J2ME is the MIDlet. Here, we'll take a look at the MIDlet in detail, examining its states and state application, as well as its methods for handling events and exceptions. We'll conclude by building a simple application that will demonstrate the concepts explained here.By the time we're finished, you should be on your way towards writing your own J2ME apps.
The Mobile Information Device Profile (MIDP) is a set of Java APIs targeted at mobile information devices such as mobile phones and entry-level palmtop devices. A MIDlet is a MIDP application. Throughout this article, the terms MIDlet and MID application are used interchangeably. MIDlets form the building blocks of the Java 2 Platform, Micro Edition (J2ME) runtime environment.
The MIDlet is designed to be run and controlled by the application manager in the K Virtual Machine (KVM), a stripped-down version of the Java Virtual Machine designed to run on mobile devices. The javax.microedition.midlet.MIDlet class acts as an interface between the MIDlet and the application manager. The methods of this class allow the application manager to create, start, pause, and destroy a MIDlet.
J2ME applications must extend the javax.microedition.midlet.MIDlet class, which provides a framework for the following actions:
- To allow the application manager to control the MIDlet by notifying and requesting MIDlet state changes.
- To allow the MIDlet to retrieve properties from the application descriptor, a registry of applications maintained by the application manager.
Figure 1 illustrates the interaction between a MIDlet and the application manager.
Figure 1. The MIDlet environment

A MIDlet can be in various states in its lifetime. These states allow the application manager to manage the activities of multiple MIDlets within a runtime environment. It can select which MIDlets are active at a given time by starting and pausing them individually. The application manager also maintains the state of the MIDlet. A MIDlet can be in any of the following states:
- Active: The MIDlet enters an active state at startup and may acquire some resources.
- Paused: In the paused state, the MIDlet releases shared resources and becomes quiescent.
- Destroy: This is the MIDlet's termination phase. The terminating MIDlet must release all resources and save any persistent state with the application manager.
Figure 2 shows the state transitions of a MIDlet. The arrows show permitted state changes. For instance, a MIDlet in the active state can move either to the paused state or the destroy state.
Figure 2. MIDlet state changes

State implementations: Moving from state to state
The application manager invokes certain methods on the MIDlet to change states. The MIDlet implements these methods to update its internal activities and resource usage as directed by the application manager:
startApp(): This method signals the MIDlet that it has entered an active state. It consists of the initialization procedures for setting up of an interactive display environment for the MIDlet.pauseApp(): This method signals the MIDlet to stop and enter the paused state.destroyApp(): This method signals the MIDlet to terminate and enter the destroyed state.
The MIDlet can initiate some state changes itself and notifies the application manager of those state changes by invoking one of these methods:
notifyDestroyed(): This method is used by a MIDlet to notify the application manager that it has entered into the destroyed state.notifyPaused(): This method notifies the application manager that the MIDlet does not want to be active and has entered the paused state.resumeRequest(): This method provides a MIDlet with a mechanism to indicate that it is interested in entering the active state. Calls to this method can be used by the application manager to determine which applications to move to the active state. When the application manager decides to activate a MIDlet, it will call that MIDlet'sstartApp()method.
The MIDlet is provided with a mechanism to retrieve named properties from the application manager: its getAppProperty() method. These properties, provided as part of the MIDlet deployment, are retrieved from the combination of the application descriptor file and the manifest.
If a runtime exception occurs during startApp() or pauseApp(), the MIDlet will be destroyed immediately.
When a user interacts with the MIDlet, events are generated. The MIDlet provides certain interfaces as part of its event handling mechanism so that the application is notified of events and responds to them. Each of the interfaces provides methods known as callback methods, which are invocations of programmer-defined methods that are executed by the application in response to events.
Events generated while a MIDlet is running might include:
- Input from screen commands
- Changes in the internal state of a screen item
- Changes in the internal state of a phone database associated with a MIDlet
The MIDlet event handling mechanism is based on a listener model. Each object should implement a listener so that it can be notified of and respond to any event. To achieve this, the MIDlet provides three interfaces: ItemStateListener, CommandListener, and RecordListener. Let's look at each in some detail.
A CommandListener is responsible for notifying the MID application of any events generated by displayable items (e.g., a command entered on the screen). It provides a commandAction(Command c, Displayable d) method that an object extending the listener must implement. This method indicates that a command event has occurred on Displayable d.
An ItemStateListener is responsible for notifying the MID application of any change in the internal state of a display item (e.g., the value of a TextField on the screen). It provides an itemStateChanged(Item I) method called when the internal state of an item has been changed by the user. The change in internal state can be due to the user:
- Changing the set of selected values in a
ChoiceGroup - Adjusting the value of an interactive
Gauge - Entering or modifying the value in a
TextField - Entering a new date or time in a
DateField
You can learn more about all these display items in my previous article.
It is up to the device to decide when it considers a new value to have been entered into an item. For example, implementations of text editing within a TextField vary greatly from device to device.
An ItemStateListener is not called if the application itself changes the value of an interactive item, only if the user does.
The RecordListener is responsible for receiving record change-related events from a record store that may be associated with an application. To use it, an application must implement the following methods, which the RecordListener provides:
recordAdded(): Called when a record has been added to a record store.recordDeleted(): Called after a record in a record store has been changed.recordChanged(): Called after a record has been deleted from a record store.
Associating listeners with objects
Listeners must be associated with objects so that those objects can respond to events as the MIDlet runs. The MIDlet class provides certain methods to associate an event listener with an object:
setCommandListener(): This method sets the listener for every command to aDisplayable, replacing any previousCommandListener.setItemStateListener(): This method sets the item state listener for screen items, replacing any previousitemStateListener.addRecordStateListener(): This method adds the record state listener to a record store.
Figure 3 shows the MIDlet event handling model.
Figure 3. MIDlet event handling

A MIDlet is capable of dealing with unusual situations through exception handling. An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. The MIDlet preserves the model of the Java exception handling mechanism. When such an error occurs within a method, the method creates an exception object and hands it off to the runtime system. The exception object contains information about the exception, including its type and the state of the program when the error occurred. The runtime system is then responsible for finding some code to handle the error. In Java terminology, creating an exception object and handing it to the runtime system is called throwing an exception.
As we have seen earlier, the MIDlet can be in various states in its lifetime. The MIDlet signals by throwing an implicit MIDletStateChangeException that a requested MIDlet state change has failed.
For more on Java exception handling, see the Resources section below.
Example: A phone image application
In this section, we will develop a J2ME image application illustrating the role of the MIDlet in its various stages. The application will also have the capability to quit through an event handling mechanism.
The PhoneImage application will invoke a constructor in response to calls to its MIDlet methods. This constructor performs the initialization procedures by creating a phone display environment, phone display items, and a screen command for exiting the application.
The phone display environment is represented by the Display class. There is exactly one instance of Display per MIDlet and the PhoneImage constructor gets a reference to that instance by calling the getDisplay() method:
display = Display.getDisplay(this);
|
The UI aspect of this application is the javax.microedition.lcdui.Image class, which is used to hold graphical image data. Image objects exist independently from the display device. They exist only in off-screen memory and will not be painted on the display unless an explicit command is issued by the application (such as within the paint() method of a Canvas), or until an Image object is placed within a Form screen or an Alert screen and that screen is made current.
Images are either mutable or immutable, depending upon how they are created. Immutable images are generally created by loading image data from resource bundles, from files, or from the network. They may not be modified once created. Mutable images are created in off-screen memory. The application may paint into them after having created a Graphics object expressly for that purpose. Images placed within Alert, Choice, Form, or ImageItem objects must be immutable because the runtime environment may use them to update the display at any time, without notifying the application.
The PhoneImage application creates an immutable image item by invoking the createImage(String resourceName) method of the javax.microedition.lcdui.Image class. This method creates an immutable image from decoded image data obtained from the named resource, which may reside in resource bundles, on a filesystem, or on the network, depending on device implementations. The resourceName implies the name of the resource containing the image data in one of the supported image formats. Implementations are required to support images stored in version 1.0 of the PNG (Portable Network Graphics) format.
The method throws a NullPointerException if the resource name is null. It throws an IOException if the resource does not exist, the data cannot be loaded, or the image data cannot be decoded. Listing 1 shows how all this works.
Listing 1. Creating an Image
try
{
image = Image.createImage("/img/JavaPowered-8.png");
}
catch (java.lang.NullPointerException exc)
{
exc.printStackTrace();
}
catch (java.io.IOException ioExc)
{
ioExc.printStackTrace();
}
startApp
|
The PhoneImage application enters an active state by invoking the startApp() method. The Image item is embedded in a Form object (see Listing 2). The implementation handles layout, traversal, and scrolling. The Form is also associated with the screen commands.
Listing 2. Adding an Image to the phone display
displayForm = new Form("Image");
displayForm. append(
new ImageItem("Default Layout",
image,
ImageItem.LAYOUT_DEFAULT,
"Image Cannot be shown"));
displayForm.addCommand(exitCommand);
|
The startApp() method is responsible for setting up an event handling mechanism by associating each command with a listener and defining the Form as the current displayable item, as Listing 3 demonstrates.
Listing 3. Adding user interaction properties to the display
displayForm.setCommandListener(this); displayForm.setItemStateListener(this); |
The application manager's invocation of the pauseApp() method makes the PhoneImage application enter a paused state. This is a no-op method when there are no background activities or record stores are closed. The destroyApp() method initiates the termination phase for the PhoneImage application. This method is responsible for releasing all resources.
The commandAction method (see Listing 4) allows the PhoneImage MIDlet to be responsive to commands and is invoked on every screen command action. A handler for the exitCommand is defined that terminates the MIDlet when the exitCommand is invoked.
Listing 4. Implementing a command callback
public void commandAction (
Command c, Displayable s) {
if (c == exitCommand) {
destroyApp(false);
notifyDestroyed();
}
}
|
Listing 5 contains the full source code for the PhoneImage application:
Listing 5. PhoneImage
// Import of API classes
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;
//A first MIDlet with simple text and a few commands.
public class PhoneImage extends MIDlet
implements CommandListener, ItemStateListener {
//The commands
private Command exitCommand;
//The display for this MIDlet
private Display display;
// Display items e.g. Form and Image
Form displayForm;
Image image;
public PhoneImage() {
display = Display.getDisplay(this);
exitCommand = new Command("Exit", Command.SCREEN, 1);
try
{
image = Image.createImage("/img/JavaPowered-8.png");
}
catch (java.io.IOException ioExc)
{
ioExc.printStackTrace();
}
}
// Start the MIDlet by creating the Form and
// associating the exit command and listener.
public void startApp() {
displayForm = new Form("Image");
displayForm. append(
new ImageItem("Default Layout",
image,
ImageItem.LAYOUT_DEFAULT,
"Image Cannot be shown"));
displayForm.addCommand(exitCommand);
displayForm.setCommandListener(this);
displayForm.setItemStateListener(this);
display.setCurrent(displayForm);
}
public void itemStateChanged(Item item)
{
}
// Pause is a no-op when there is no background
// activities or record stores to be closed.
public void pauseApp() { }
// Destroy must cleanup everything not handled
// by the garbage collector.
public void destroyApp (boolean unconditional) { }
// Respond to commands. Here we are only implementing
// the exit command. In the exit command, cleanup and
// notify that the MIDlet has been destroyed.
public void commandAction (
Command c, Displayable s) {
if (c == exitCommand) {
destroyApp(false);
notifyDestroyed();
}
}
}
|
Figure 4 shows the application running on a device emulator.
Figure 4. The PhoneImage application

Writing wireless applications that run on all mobile phones or pagers has become a lot easier with MIDlets. The well-defined architecture of the MIDlet is built on a set of well-defined methods, which provide broad capabilities but maintain an encapsulated architecture. I hope this article will help you get started building your own MIDlets.
- Get introduced to the J2ME Technology in my previous introductory developerWorks article Think small with J2ME.
- JavaWorld has run a useful series on exception handling.
- Check out the latest developments at IBM's Pervasive Computing site.
- Take a look at the MIDP homepage to learn about the MIDP APIs.
- Browse through a range of articles on the Java Wireless initiative.
- Examine the MIDP API documentation that comes with the J2ME Wireless Toolkit.
A graduate in computer science and engineering, Soma Ghosh has developed a wide range of e-commerce and networking Java applications over the past six years. She believes that wireless commerce represents the near future of the industry, and has recently been drawn to wireless initiatives of existing desktop models. She is currently a senior application developer with Entigo, a pioneer in B2B sell- and service-side e-commerce products and solutions. Contact Soma at sghosh@entigo.com.
