MIDP Programming: Design Applications and High-Level User Interface
- MIDPlets
- High-Level API
- Low-Level API
- Summary
Introduction
In This Chapter
MIDlets
High-Level API
Low-Level API
This chapter handles the life cycle and user interface of Mobile Information Device Profile (MIDP) applications. First, the general design of MIDP applications will be discussed. Then, the high-level user interface API will be explained. Finally, the low-level user interface API for free graphics and games will be described.
MIDlets
All applications for the MID Profile must be derived from a special class, MIDlet. The MIDlet class manages the life cycle of the application. It is located in the package javax. microedition.midlet.
MIDlets can be compared to J2SE applets, except that their state is more independent from the display state. A MIDlet can exist in four different states: loaded, active, paused, and destroyed. Figure 3.1 gives an overview of the MIDlet lifecycle. When a MIDlet is loaded into the device and the constructor is called, it is in the loaded state. This can happen at any time before the program manager starts the application by calling the startApp() method. After startApp() is called, the MIDlet is in the active state until the program manager calls pauseApp() or destroyApp(); pauseApp() pauses the MIDlet, and desroyApp() terminates the MIDlet. All state change callback methods should terminate quickly, because the state is not changed completely before the method returns.
Figure 3.1 The life cycle of a MIDlet.
In the pauseApp() method, applications should stop animations and release resources that are not needed while the application is paused. This behavior avoids resource conflicts with the application running in the foreground and unnecessary battery consumption. The destroyApp() method provides an unconditional parameter; if it is set to false, the MIDlet is allowed to refuse its termination by throwing a MIDletStateChangeException. MIDlets can request to resume activity by calling resumeRequest(). If a MIDlet decides to go to the paused state, it should notify the application manager by calling notifyPaused(). In order to terminate, a MIDlet can call notifyDestroyed(). Note that System.exit() is not supported in MIDP and will throw an exception instead of terminating the application.
Note
Some devices might terminate a MIDlet under some circumstances without calling destroyApp(), for example on incoming phone calls or when the batteries are exhausted. Thus, it might be dangerous to rely on destroyApp() for saving data entered or modified by the user.
Display and Displayable
MIDlets can be pure background applications or applications interacting with the user. Interactive applications can get access to the display by obtaining an instance of the Display class. A MIDlet can get its Display instance by calling Display.getDisplay (MIDlet midlet), where the MIDlet itself is given as parameter.
The Display class and all other user interface classes of MIDP are located in the package javax.microedition.lcdui. The Display class provides a setCurrent() method that sets the current display content of the MIDlet. The actual device screen is not required to reflect the MIDlet display immediatelythe setCurrent() method just influences the internal state of the MIDlet display and notifies the application manager that the MIDlet would like to have the given Displayable object displayed. The difference between Display and Displayable is that the Display class represents the display hardware, whereas Displayable is something that can be shown on the display. The MIDlet can call the isShown() method of Displayable in order to determine whether the content is really shown on the screen.
HelloMidp Revisited
The HelloMidp example from Chapter 1, "Java 2 Micro Edition Overview," is already a complete MIDlet. Now that you have the necessary foundation, you can revisit HelloMidp from an API point of view.
First, you import the necessary midlet and lcdui packages:
import javax.microedition.midlet.*; import javax.microedition.lcdui.*;
Like all MIDP applications, the HelloMidp example is required to extend the MIDlet class:
public class HelloMidp extends MIDlet {
In the constructor, you obtain the Display and create a Form:
Display display; Form mainForm;
public HelloMidp () { mainForm = new Form ("HelloMidp"); }
A Form is a specialized Displayable class. The Form has a title that is given in the constructor. You do not add content to the form yet, so only the title will be displayed. (A detailed description of the Form class is contained in the next section.)
When your MIDlet is started the first time, or when the MIDlet resumes from a paused state, the startApp() method is called by the program manager. Here, you set the display to your form, thus requesting the form to be displayed:
public void startApp() { display = Displayable.getDisplay (this); display.setCurrent (mainForm); }
When the application is paused, you do nothing because you do not have any allocated resources to free. However, you need to provide an empty implementation because implementation of pauseApp() is mandatory:
public void pauseApp() { }
Like pauseApp(), implementation of destroyApp() is mandatory. Again, you don't need to do anything here for this simple application:
public void destroyApp(boolean unconditional) { } }
Note
The HelloMidp Midlet does not provide a command to exit the MIDlet, assuming that the device provides a general method of terminating MIDlets. For real MIDP applications, we recommend that you add a command to terminate the MIDlet because the MIDP specification does not explicitly support this assumption. More information about commands can be found in the section "Using Commands for User Interaction."
MIDP User Interface APIs
The MIDP user interface API is divided into a high- and low-level API. The high-level API provides input elements such as text fields, choices, and gauges. In contrast to the Abstract Windows Toolkit (AWT), the high-level components cannot be positioned or nested freely. There are only two fixed levels: Screens and Items. The Items can be placed in a Form, which is a specialized Screen.
The high-level Screens and the low-level class Canvas have the common base class Displayable. All subclasses of Displayable fill the whole screen of the device. Subclasses of Displayable can be shown on the device using the setCurrent() method of the Display object. The display hardware of a MIDlet can be accessed by calling the static method getDisplay(), where the MIDlet itself is given as parameter. In the HelloMidp example, this step is performed in the following two lines:
Display display = Display.getDisplay (this); ... display.setCurrent (mainForm);
Figure 3.2 shows an overview of the MIDP GUI classes and their inheritance structure.
The following sections first describe the high-level API and then the low-level API. A more complex sample application that uses both levels of the lcdui package together is shown in Chapter 9, "Advanced Application: Blood Sugar Log."
Figure 3.2 The MIDP GUI