MIDlets and the Display: The Basics
The Basics
A MIDlet is a Java application designed to run on a mobile device. There are two core Java libraries that make up the development environment for these mobile applications: the Connected, Limited Device Configuration (CLDC) and the Mobile Information Device Profile (MIDP).
Each MIDlet goes through several phases as part of its lifecycle and is always in one of the following three states:
PausedThe constructor has been called but has not been started by the application manager. A MIDlet may alternate between the Paused and Active states any number of times during its lifecycle. Transitions occur when the application manager pauses/reactivates the MIDlet or when the MIDlet makes a specific request to be paused/ reactivated.
ActiveThe MIDlet is running.
DestroyedThe MIDlet has released any resources that it acquired and has been shut down by the application manager.
We create a MIDlet by extending the class javax.microedition.midlet.MIDlet. This class contains three abstract methods, startApp(), destroyApp(), pauseApp(). Here is a simple application "shell" that contains a reference to each of the required methods:
import javax.microedition.midlet.*; public class Shell extends MIDlet { // This method (constructor) is NOT required public Shell () { } // Called by application manager to start the MIDlet public void startApp() { } // Called by application manager before pausing the MIDlet public void pauseApp() { } // Called by application manager prior to shutdown public void destroyApp(boolean unconditional) { } }
Working with the Display Class
There is one Display object per MIDlet. Through this object we can query information about the current device display, such as how many colors or shades of gray are supported. Although there is only one Display object per MIDlet, there may be many objects within a MIDlet that are displayable. We'll cover this idea in a moment.
Creating a Display Object
A Display object is made available to a MIDlet through a call to a static method declared inside the Display class. This reference is often held for the lifetime of the MIDlet in a variable, as shown below:
public class DisplayStats extends MIDlet { private Display display; // Reference to Display object // MIDlet constructor public DisplayStats() { display = Display.getDisplay(this); ... } ... }
Displayable Class
Although there is only one Display object per MIDlet, a Display object can show any number of Displayable objects. The MID Profile includes two subclasses of Displayable, Screen and Canvas. Here are a few class definitions to help clarify:
abstract public class Displayable public abstract class Canvas extends Displayable public abstract class Screen extends Displayable
Objects that subclass Screen (Textbox, List, Form, and Alert) are all high-level user-interface components. The majority of code for displaying and interacting with these components is provided for us.
The Canvas object is used for custom graphics and low-level event handling, such as when writing games. It is our responsibility as developers to draw on the device and to capture and process all events.
Creating a Displayable Object
We don't create Displayable objects directly; instead, we reference subclasses of Displayable. Here are three general ways in which this is done:
Extend the Canvas class directly:
public class GameScreen extends Canvas { draw images, shapes, text ... }
Create an instance of a TextBox, List, Form, or Alert (each is a subclass of Screen):
private Form frmMain; private TextBox tbxMessage; ... frmMain = new Form("Test Exception"); tbxMessage = new TextBox("Title", "Contents", 25, TextField.ANY);
Extend Form, TextBox, List, or Alert. For example:
public class FormPrefs extends Form implements CommandListener
One benefit of extending a Form, TextBox, List, or Alert is encapsulating event handling. Each subclass will receive only those events that are initiated on that component.
Comprehensive Example
The following example ties together all the concepts presented thus far. Here are the main points addressed:
Create a class that extends a MIDlet and provides a body of code for each of the required methods
Create an instance of the Display class and save a reference in a variable
Create two Displayable objects, one that is an instance of a Form and one that extends the Form class
Encapsulate event processing through the commandAction() method
There are two classes that make up this MIDlet, MainMIDlet and FormSubclass. The former is the main body of code, extending the MIDlet class, creating an instance of Form that will act as the main user interface, and providing all the required methods discussed previously. There is also a "button" on the interface that will initiate a call to display the form FormSubclass.
Following is the declaration of the main MIDlet. Notice the reference to the two formsone is an instance of Form (as defined in the MID Profile), and the second is an instance of the class FormSubclass (which is a class that we create here). (See Figure 1.) All event handling for this form will be accomplished inside commandAction().
Figure 1 Form frmMain (left) and FormSubclass frmSub (right).
public class MainMIDlet extends MIDlet implements CommandListener { private Display display; // Our display private Form frmMain; // Main form private FormSubclass frmSub; // Subclass of form ... public void commandAction(Command c, Displayable d) { ... } }
The following is a glimpse of the code block that extends the Form class. The method commandAction() will process all events that occur on this Form:
public class FormSubclass extends Form implements CommandListener { ... public void commandAction(Command c, Displayable d) { ... } }
The output of the MIDlet is shown in Listing 1 and Listing 2.
Listing 1: MainMIDlet.java
/*-------------------------------------------------- | MainMIDet.java | | Show the "main" form with a command button that | will invoke a subclass of form *-------------------------------------------------*/ import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MainMIDlet extends MIDlet implements CommandListener { private Display display; // Our display private Form frmMain; // Main form private FormSubclass frmSub; // Subclass of form private Command cmdExit; // Command to exit private Command cmdForm; // Command to call form subclass /*-------------------------------------------------- * MIDlet constructor. *-------------------------------------------------*/ public MainMIDlet() { // Get reference to display object display = Display.getDisplay(this); // Create the main form and an instance of the class // that subclasses form frmMain = new Form("Main Form"); frmSub = new FormSubclass("Subclass of Form", this); // Commands cmdExit = new Command("Exit", Command.EXIT, 1); cmdForm = new Command("Form", Command.SCREEN, 2); // Add all to form and listen for events frmMain.addCommand(cmdExit); frmMain.addCommand(cmdForm); frmMain.setCommandListener(this); } /*-------------------------------------------------- * Show the main Form *-------------------------------------------------*/ public void startApp () { displayMainMIDlet(); } /*-------------------------------------------------- * Shutting down *-------------------------------------------------*/ public void destroyApp (boolean unconditional) { } /*-------------------------------------------------- * No pause code necessary *-------------------------------------------------*/ public void pauseApp () { } /*-------------------------------------------------- * Display the main MIDlet interface *-------------------------------------------------*/ public void displayMainMIDlet() { display.setCurrent(frmMain); } /*-------------------------------------------------- * Process events for the main form *-------------------------------------------------*/ public void commandAction(Command c, Displayable d) { if (c == cmdExit) { destroyApp(false); notifyDestroyed(); } else if (c == cmdForm) { display.setCurrent(frmSub); } } }
Listing 2: FormSubclass.java
/*-------------------------------------------------- | FormSubclass.java | | Subclass the Form class. Event processing for | this subclass is managed locally *-------------------------------------------------*/ import javax.microedition.lcdui.*; public class FormSubclass extends Form implements CommandListener { private Command cmdBack; private MainMIDlet midlet; public FormSubclass(String title, MainMIDlet midlet) { // Call the Form constructor super(title); // Save reference to MIDlet this.midlet = midlet; // Commands cmdBack = new Command("Back", Command.BACK, 1); // Add command and listen for events addCommand(cmdBack); setCommandListener(this); } /*-------------------------------------------------- * Process events for this form only *-------------------------------------------------*/ public void commandAction(Command c, Displayable s) { if (c == cmdBack) midlet.displayMainMIDlet(); } }