|
MIDP Programming II
by Loke Kar Seng (lks@webpres.com.my)
The structure of a MIDlet program, like an applet, implements a complete life cycle management, that is, it has methods that start, pause and stop the application, named respectively, startApp, pauseApp and destroyApp.
MIDP provides a two tier approach to using the graphical user interface components. The high-level components handle alerts, forms, lists and text boxes, all of which are from the Screen class.
The low-level component, Canvas, has graphics drawing routines, such as drawLine, fillRect, drawRect, drawString, drawImage and so on. The Canvas class is a base class for writing applications that need to handle low-level events and to issue graphic calls for drawing to the display. Game applications will likely make heavy use of the Canvas class.
Screen updates for the high-level interface components are repainted automatically, hence there is no need to call the repaint() method. The low-level component, canvas, handle their own update via the paint(Graphics g) and repaint(). Method serviceRepaints() can be called to force pending repaint requests to be serviced immediately.
MIDP does not provide direct device-specific access for its low-level graphics API. Direct manipulaton of pixel values, such as raster operations or alpha blending is not supported. Sprites also is not supported. MIDP supports the Portable Network Graphics (PNG) image format. Image files in PNG format packaged as a resource can be loaded using the createImage(string Name) method from the Image or Alert class.
Both the Canvas and the Screen class belong the Displayable class, all of which are abstract classes that must be extended. The Displayable has methods that allow abstract commands to be added and listened to.
Abstract commands allow the MIDlet to map specific commands to device hardware depending on configuration, thus freeing the developer from hardcoding it to device-specific hardware. MIDP also provides abstract game action keys as part of the Canvas class. The game-action key UP, DOWN, LEFT, RIGHT, FIRE, GAME_A, GAME_B, GAME_C and GAME_D returned can be tested using the getGameAction(int keycode) method. The mapping of these codes are determined by the manufacturer and varies from device to device. Portable applications should use game actions instead of key codes.
Events in the high-level components are handled via the CommandListener interface. The MIDlet class can implement the CommandListener interface or it can be introduced as an anonymous class (see code below). The high-level components has a setCommandListener method that can be used to register the appropriate CommandListener. The CommandListener implementation must include the commandAction method.
The sample code provide a simple example on how to add abstract commands to the Displayable classes, the parent class to both Canvas and Screen. However both Canvas and Screen are both abstract classes and hence has to be extended before they can be used. Form, Alert, List, and TextBox are predefined classes extended from Screen.
The example uses a simple Form class to add an abstract command “Exit”. At the MIDlet constructor an abstract command is created.
exitCmd = new Command("Exit", Command.EXIT, 2);
Then a new Form is created and addCommand is used to add the exit command.
form = new Form("Test1 Form");
form.addCommand(exitCmd);
Then a CommandListener is added to the form by passing itself to it since the MIDlet has already implemented the CommandListener interface by having the method commandAction.
form.setCommandListener(this);
If the MIDlet has not implemented the CommandListener interface, then it could use an anonymous class:
form.setCommandListener(
new CommandListener (){
public void commandAction(Command c, Displayable d) {
if(c==exitCmd){
destroyApp(true);
notifyDestroyed();
}
}
}
);
To display the form, at the startApp method, it has to set the Displayable (in this case the Form) to current.
display.setCurrent(form);
The display is obtained by using getDisplay at the MIDlet constructor.
display=Display.getDisplay(this);
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class test1 extends MIDlet implements CommandListener
{
private Command exitCmd;
private Display display;
private Form form;
public test1(){
/* get the display of this object */
display=Display.getDisplay(this);
/* create a new abstract command to be mapped to the Exit key */
exitCmd = new Command("Exit", Command.EXIT, 2);
/* create a displayable object, could be either from canvas or
screen class but both are abstract classes so must be extended or
predefined such as Alert, Form, Lists or TextBox */
form = new Form("Test1 Form");
/* add the command to the displayable and set the CommandListener
to this object as it implements the commandAction method */
form.addCommand(exitCmd);
form.setCommandListener(this);
/* if this class did not implement CommandListener, then an
anonymous CommandListener class can be created instead, eg.
form.setCommandListener(
new CommandListener (){
public void commandAction(Command c, Displayable d) {
if(c==exitCmd){
destroyApp(true);
notifyDestroyed();
}
}
}
);
*/
}
}
public void startApp() throws MIDletStateChangeException {
/* start doing something, like, displaying the current screen */
display.setCurrent(form);
}
/* must release shared resources and become quiescent */
public void pauseApp() {
}
/* Signals to the Midlet to clean up, release resources and save persistent state,
however if the parameter cleanup is set to false, the Midlet can resist going
into the Destroyed state by throwing an exception */
public void destroyApp(boolean cleanup) {
/* Release all resources and save any persistent state. */
}
/* execute command actions */
public void commandAction(Command c, Displayable d) {
if(c==exitCmd){
destroyApp(true);
/*MIDlet notify the application management software that it
has entered into the Destroyed state. */
notifyDestroyed();
}
}
}
[ Top ]
|