Java Micro Edition (Java ME) Tutorial
Java Micro Edition or Java ME is a Java platform designed for mobile phones and embedded systems.Java ME was formerly known as Java 2 Platform, Micro Edition (J2ME).Java ME was designed by Sun Microsystems, now a subsidiary of Oracle Corporation.
Java ME devices implement a profile, of which there are currently two: the Connected Limited Device Configuration (CLDC) and the Connected Device Configuration (CDC).
In this tutorial we learn how to install environment to built Java ME application. Later part of this tutorial shows how to build Java ME application. Our target device is Nokia phone. If you don't have Nokia phone then there is no problem, Forum Nokia provides such a nice system that you can access devices over internet just like you have those device with you. To learn more about Remote Device Access follow this link.
Basic tools you need to install before starting
See the following table for free download and configuration.
| Name of tool | Recommended version | Download link | Notes/Configuration |
| Java Development Kit(JDK) | JDK 6 Update 20 | Download link. | Save the following file to your c:\javame\ (for example)jdk-6u20-windows-i586.exe and double click on it and follow the screen |
| Eclipse Pulsar | Galileo win32 | Download link | Click on Download Pulsar, then on right column click on Windows 32-bit, select any mirror image and download eclipse-pulsar-galileo-SR1-win32.zip to c:\javame\ (for example), unzip the file and that will create a folder eclipse and inside you see eclipse.exe, this is our IDE (Integrated development environment) You can make a short cut to it if you like. |
| Sun Java Wireless Toolkit | 2.5.2_01 Final Release for Windows | Download link | In this tutorial, we have used Sun Java Wireless Toolkit 2.5.2_01 for CLDC, so you can try the same. Download (sun_java_wireless_toolkit-2[1].5.2_01-win.exe) to your PC and install it by clicking on the exe. |
| Nokia S60 SDK | S60_3rd_MIDP_SDK_FP1 | Download link | This is Nokia SDK for Midlet development, We could not make it working, so we use Sun Java Wireless Toolkit untill we succede, if we don't use Nokia SDk we miss some Nokia specific features |
In the following configuartion, please use Sun Java Wireless Toolkit instead of S60 SDK. When we shall know how to use Nokia SDK then we switch to it and untill that time we use Sun Java Wireless Toolkit.
Configuring the tools
First we need to configure Eclipse
1. Open Eclipse by clicking on eclipse.exe (You saved it some where)
2. Select Windows -> Preferences
3. Select Java ME then Device Management
4. Click on import
5. Browse the folder to tell the system where to find the Nokia SDK (C:\S60\devices). This will search the SDK, it will take some time and finally click on Finish
6. Select emulator or device as default if necessary
7. Finally press on OK
Now we have installed the tools that we need. Now we are able to create our first hellomymidlet and put it to Nokia device.
Follow the following instruction to run your first Java ME midlet.
Step 1: Select File | New | Midlet Project
Step 2: Give a name to the project MyJava
Step 3: In the configurations, select S60 emulator
Step 4: Press next
Step 5: This will bring a window (Midlet Project Content) Select MicroEdition Configuration to Connected Limited Device Configuration 1.1
Step 6: Select Mobile Device Information Profile 2.1
Step 7: Press on Next and Finish
Now our project is read and we need to create classes that can be used to make the helloJava.
Step 8: File | New | Java ME Midlet
Step 9: Give a Name mymidlet, press on Next and then Finish
Step 10. This will create a file name mymidlet.java. Copy contents of this file and paste it to it. Step 11: Right Click on MyJava and select Mobile Tool for Java | Create Package
Step 12: This will create jar and jad file in depoyed folder.
Step 13: Send the Jar file to your phone or use Forum Nokia RDA.
Congratulation, we have done our first Midlet that works in phone (at least it works to me :-))
If you want to import all the implementation file from existing project you just copy the respective folder and paste it to respective folder in your project just after Step 7.
0. MIDP 2.0
The MIDP (the Mobile Information Device Profile) is designed for mobile phones and PDAs. And it is designed to operate on top of the Connected, Limited Device Configuration (CLDC).

1. Requirements of MIDP 2.0
MIDP device has the following minimum characteristics:
- Display:
- screen size 96x54
- Input:
- One or more of the following user-input mechanisms: one-handed keyboard, two-handed keyboard, or touch screen
- Memory:
- 256 kilobytes of non-volatile memory for the MIDP implementation, beyond whats required for CLDC
- 8 kilobytes of non-volatile memory for application-created persistent data
- 128 kilobytes of volatile memory for the Java runtime (e.g., the Java heap)
- Networking:
- Two-way, wireless, possibly intermittent, with limited bandwidth
- Sound:
- The ability to play tones, either via dedicated hardware, or via software algorithm.
2. Midlet
MIDP application is a MIDlet. The activity of a MIDlet is managed by the Application Management Software of the mobile device. AMS control the life cycle of a midlet. AMS creates, starts, pauses and destroys the instance of MIDlet. AMS controls the activity of a MIDlet by means of startApp(), pauseApp() and destroyApp() methods.

Our MIDP application, MIDlet, must extend the abstract MIDlet class, which consists of the abstract methods startApp(), pauseApp() and destroyApp(). We have to write these methods also into our MIDlet.

MIDlet States
AMS creates the MIDlet object by allocating memory for it and calling its no-argument constructor. The application can do only little initialization in no-argument constructor. Middlet instance is first in the paused state. If an exception occurs during create phase of the MIDlet object, the application enters immediately the destroyed state. After the exceptionless return from constructor AMS calls startApp() method of the MIDlet. The application enters just before startApp() method call active state. Application has most of the initialization tasks in the startApp() method.

Example.
The following simple MyMIDlet has a TextBox user interface component with some text and an exit command. MyMIDlet is derived from the MIDlet class and it has the no-argument constructor, startApp(), pauseApp() and destroyApp() methods.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class MyMIDlet extends MIDlet implements CommandListener
{
private Command exitCommand;
private Display display;
public MyMIDlet()
{
display = Display.getDisplay(this);
exitCommand = new Command("Exit", Command.SCREEN, 2);
}
public void startApp()
{
TextBox t = new TextBox("The first midlet", "Welcome to the wonderfull world of midlets", 50, 0);
t.addCommand(exitCommand);
t.setCommandListener(this);
display.setCurrent(t);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
public void commandAction(Command c, Displayable s)
{
if(c == exitCommand)
{
destroyApp(false);
notifyDestroyed();
}
}
}
3. User interface
The user interface for MIDP applications consists of the UI API in the javax.microedition.lcdui package.
Display class represents the manager of the display and input devices of the system. There is exactly one instance of Display per MIDlet and the application can get a reference to that instance by calling the Display.getDisplay() method. Method call is in the constructor or in the startApp() method.
Display instance has no graphical representation form, it only manages the display and input device of the mobile device. Display instance has setCurrent(Displayable displayable) method, which makes Displayable object visible on the display. Displayable class is the super class of all GUI component classes, that has the capability of being placed on the display and that can contain user command activities. The following figure contains the most important classes of the MIDP graphical user interface.

Screen and Canvas classes are extended from Displayable class. Screen class is common superclass of all high-level user interface classes. Canvas is a base class for applications, that need to handle low-level events and to issue graphics for drawing to the display. Java games use Canvas class and its subclasses.
One instance of the four subclasses of the Screen class, TextBox, List, Alert or Form, can be made visible on the display of a mobile device.
Form class represents a form which can contain other user interface controls. The controls added to a Form instance must be derived from Item class. The following classes of MIDP are derived from Item: ChoiceGroup, TextField, DateField, ImageItem, StringItem, Gauge, CustomItem and Spacer.
User interface classes extended from Displayable class derive addCommand() method which enables them to add user interface actions and commands to themselves. All MIDP user interface actions are presented by means of Command classes.
Command class
The Command class is a construct that encapsulates the semantic information of an user interface action. Command only contains information about the command activity, it doesn't contain the program code of the activity. Program code is written in a CommandListener object associated with the Displayable instance.
Commands can be presented to the user of a device in different ways depending on the model of the device, on the type of the command, on the total number of commands, etc.. The presentation way of a action can be a soft key, item in a menu, some other direct user interaction contruct, voice command, ... A Command object is mapped to a GUI component through addCommand() method.
The constructors of the Command class are below:
- Command(String label, int commandType, int priority)
- Command(String shortLabel, String longLabel, int commandType, int priority)
Paramters label, shortLabel and longLabel are a string the application shows to the user which. The string can be direct on the display or a item of a menu. If the string is direct on the display, it presents a soft key.
The second parameter, commandType, specifies the intent of the command. MIDP defines the following command types:
- BACK, return to the previous screen
- CANCEL, standard negative answer to a dialog
- EXIT, exit from application
- HELP, on-line help
- ITEM, hint the implementation of item of the Screen or the elements of a Choice
- OK, standard positive answer to a dialog
- SCREEN, application defined command
- STOP, stop some currently running process, operation, etc.
The commandType definition doesn't do any activity automatically in the application. The activity have to been programmed in the midlet. Command can have a standard presentation way on a display by means of commandType definition. For example, if the application specifies that the command is of type BACK, and if the device has a standard of placing the "back" operation on a certain soft-button, the implementation can follow the style of the device by using the semantic information as a guide.
The last parameter of Command constructor, priority, describes the importance of this command relative to other commands on the same screen. Priority values are integers, where a lower number indicates greater importance. The priority of a command can have meaning, when application decide, if the command is showed in a menu or in a soft key. The in the constructor given value of the priority is only directive, the actual values of priority are chosen by the application.
Example of a definition of a Command instance is below:
new Command("Back", Command.BACK, 1)
CommandListener interface
A program code for user interface action is written in a class that implements CommandListener interface. The CommandListener interface contains only a method, commandAction(). The signature of the method is:
public void commandAction(Command command, Displayable d)
The first parameter, command, identifies the Command instance, which is attached to the user interface command and the second parameter, d, identifies the user interface component, which the activity occured in.
A CommandListener is attached to a user interface component with its setCommandListener() method, whose signature is below:
public void setCommandListener(CommandListener listener)
Parameter listener is a class that implements CommandListener interface.
Often the midlet self implements CommandListener interface and contains commandAction() method, where the program is coded.
Form
A Form is a screen that contains other from Item class derived GUI components: TextField, DateField, ChoiceGroup, ImageItem, StringItem, Gauge, CustomItem, Spacer. In general, any subclass of the Item class may be contained within a form. The Form instance handles layout, traversal and scrolling of the GUI components it contains.
Items within a Form are referred to by their indexes, which are consecutive integers in the range from zero to size()-1, with zero referring to the first item and size()-1 to the last item.
The items contained within a Form may be managed by using following methods:
- append(Item item) adds an Item into the Form and it becomes the last Item in the Form
- append(String string) adds a String into the end of the Form
- append(Image image)adds an Image into the end of the Form
- insert(int itemNum, Item item), inserts an Item into the Form just prior to the item specified.
- delete(int itemNum), deletes the Item referenced by itemNum
- set(int itemNum, Item item), sets the item referenced by itemNum to the specified item, replacing the previous item
Because a Form class is derived form Displayable class, a Command objects can be attached to the Form instance. In addition a Form instance can set a CommandListener object by using the method setCommandListener().
The constructors of the Form class are following:
- public Form(String title), creates an empty Form with a title
- public Form(String title, Item[] items), creates a Form with specified content ja a title
TextField
A TextField is an editable text component that may be placed into a Form. The TextField has a maximum limit, how many characters it can contain. This limit is given at the creation time of the component.
The TextField can have input constraints so that user's input is restricted in a variety ways:
- ANY, the user is allowed to enter any text.
- CONSTRAINT_MASK, the mask value for determining the constraint mode
- DECIMAL, numeric values with optional decimal fractions
- EMAILADDR, an e-mail address
- INITIAL_CAPS_SENTENCE, the initial letter of each sentence should be capitalized
- INITIAL_CAPS_WORD, the initial letter of each word should be capitalized
- NON_PREDICATIVE,
- NUMERIC, only an integer value
- PASSWORD, he text entered is confidential data that should be obscured whenever possible
- PHONENUMBER, a phone number
- SENSITIVE,
- UNEDITABLE, editing is currently disallowed
- URL, the user is allowed to enter a URL
The constructor of the TextField is following:
public TextField(String label, String text, int maxSize, int constraints)
, where the parameter label is a given label, parameter text is the initial contents, parameter maxSize is the maximum size in characters and parameter constraints is the input constraints, whose possible values are listed above.
Example
The following Form1 midlet has Form
instance f1 with two TextField
components, user and password,
and two Command objects, okCommand
and exitCommand. When a user inputs the user id
and password and selects "Ok" command,
the midlet changes the Form instance and shows
it with a text.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Form1 extends MIDlet implements CommandListener
{
private Display display;
private Form f1;
private Form f2;
private TextField user;
private TextField password;
private Command okCommand;
private Command exitCommand;
public Form1()
{
display = Display.getDisplay(this);
f1 = new Form("Login");
user = new TextField("User", "", 10, TextField.ANY);
password = new TextField("Password", "", 6, TextField.PASSWORD);
okCommand = new Command("Ok", Command.OK, 0);
exitCommand = new Command("Exit", Command.SCREEN, 0);
}
public void startApp()
{
f1.append(user);
f1.append(password);
f1.addCommand(okCommand);
f1.addCommand(exitCommand);
f1.setCommandListener(this);
display.setCurrent(f1);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
public void commandAction(Command c, Displayable s)
{
if(c == okCommand)
{
f2 = new Form("Welcome");
String text = new String();
text = "Welcome, " + user.getString() + ", your password is wrong";
f2.append(text);
f2.addCommand(exitCommand);
f2.setCommandListener(this);
display.setCurrent(f2);
}else if(c == exitCommand)
{
destroyApp(false);
notifyDestroyed();
}
}
}
ChoiceGroup
A ChoiceGroup is a group of selectable elements intended to be placed within a Form. The component has tree modes:
- single choice, user can select only one item (radio buttons), EXLUSIVE type
- multiple choice, user can select multiple items (check boxes), MULTIPLE type
- single choice, user can see first only one item and after a action the user can see all items, POPUP type
The ChoiceGroup class has 2 constructors:
- ChoiceGroup(String label, int choiceType)
- ChoiceGroup(String label, int choiceType, String[] stringElements, Image[] imageElements)
The first parameter label describes the selectable item's label and the second parameter choiceType describes the type of the ChoiceGroup, the value of which can be EXCLUSIVE, MULTIPLE or POPUP. The parameters stringElements and imageElements are arrays to be used as initial contents of the ChoiceGroup component.
Example
The following ChoiceGroup1
midlet has EXCLUSIVE type ChoiceGroup
component. A user can select a phone and the midlet shows the selection in
another Form.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class ChoiceGroup1 extends MIDlet implements CommandListener
{
private Display display;
private Form f1;
private Form f2;
private ChoiceGroup phones;
private Command selCommand; //select
private Command exitCommand; // exit
private Command backCommand; // back
public ChoiceGroup1()
{
display = Display.getDisplay(this);
String models[] = {"Nokia", "Motorola", "Sony-Ericsson"};
phones = new ChoiceGroup("Select a phone", ChoiceGroup.EXCLUSIVE, models, null);
f1 = new Form("Selecting");
selCommand = new Command("Select", Command.SCREEN, 0);
exitCommand = new Command("Exit", Command.EXIT, 0);
backCommand = new Command("Back", Command.BACK, 0);
}
public void startApp()
{
f1.append(phones);
f1.addCommand(selCommand);
f1.addCommand(exitCommand);
f1.addCommand(backCommand);
f1.setCommandListener(this);
display.setCurrent(f1);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
public void commandAction(Command c, Displayable s)
{
if(c == selCommand)
{
f2 = new Form("Selection");
String text = "Your selection was " + phones.getString(phones.getSelectedIndex());
f2.append(text);
f2.addCommand(backCommand);
f2.setCommandListener(this);
display.setCurrent(f2);
}else if(c == exitCommand)
{
destroyApp(false);
notifyDestroyed();
}else if(c == backCommand)
{
display.setCurrent(f1);
}
}
}
Example.
The following
ChoiceGroup2
midlet has a MULTIPLE type ChoiceGroup.
A user can select multiple phones and the midlet shows the selections in an
other Form.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class ChoiceGroup2 extends MIDlet implements CommandListener
{
private Display display;
private Form f1;
private Form f2;
private ChoiceGroup phones;
private Command selCommand;
private Command exitCommand;
private Command backCommand;
public ChoiceGroup2()
{
display = Display.getDisplay(this);
phones = new ChoiceGroup("Select phones", ChoiceGroup.MULTIPLE);
f1 = new Form("Selecting ..");
selCommand = new Command("Select", Command.SCREEN, 0);
exitCommand = new Command("Exit", Command.EXIT, 0);
backCommand = new Command("Back", Command.BACK, 0);
}
public void startApp()
{
phones.append("Toshiba", null);
phones.append("Nokia", null);
phones.append("Siemens", null);
phones.append("Sony-Ericsson", null);
phones.append("Motorola", null);
f1.append(phones);
f1.addCommand(selCommand);
f1.addCommand(exitCommand);
f1.addCommand(backCommand);
f1.setCommandListener(this);
display.setCurrent(f1);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
public void commandAction(Command c, Displayable s)
{
if(c == selCommand)
{
f2 = new Form("Selections");
String text = "Your selection was ";
for(int i = 0; i < phones.size(); i++)
{
if(phones.isSelected(i) == true)
text = text + "\n" + phones.getString(i) ;
}
f2.append(text);
f2.addCommand(backCommand);
f2.setCommandListener(this);
display.setCurrent(f2);
}else if(c == exitCommand)
{
destroyApp(false);
notifyDestroyed();
}else if(c == backCommand)
{
display.setCurrent(f1);
}
}
}
Example.
The following ChoiceGroup3
midlet has a POPUP type ChoiceGroup.
A user can see first only one item and after some action the user can see all
items. The user can select only one item and the midlet shows the selection in an
other Form.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class ChoiceGroup3 extends MIDlet implements CommandListener
{
private Display display;
private Form f1;
private Form f2;
private ChoiceGroup phones;
private Command selCommand;
private Command exitCommand;
private Command backCommand;
public ChoiceGroup3()
{
display = Display.getDisplay(this);
phones = new ChoiceGroup("Select phones", ChoiceGroup.POPUP);
f1 = new Form("Selecting ..");
selCommand = new Command("Select", Command.SCREEN, 0);
exitCommand = new Command("Exit", Command.EXIT, 0);
backCommand = new Command("Back", Command.BACK, 0);
}
public void startApp()
{
phones.append("Toshiba", null);
phones.append("Nokia", null);
phones.append("Siemens", null);
phones.append("Sony-Ericsson", null);
phones.append("Motorola", null);
f1.append(phones);
f1.addCommand(selCommand);
f1.addCommand(exitCommand);
f1.addCommand(backCommand);
f1.setCommandListener(this);
display.setCurrent(f1);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
public void commandAction(Command c, Displayable s)
{
if(c == selCommand)
{
f2 = new Form("Selections");
String text = "Your selection was ";
for(int i = 0; i < phones.size(); i++)
{
if(phones.isSelected(i) == true)
text = text + "\n" + phones.getString(i) ;
}
f2.append(text);
f2.addCommand(backCommand);
f2.setCommandListener(this);
display.setCurrent(f2);
}else if(c == exitCommand)
{
destroyApp(false);
notifyDestroyed();
}else if(c == backCommand)
{
display.setCurrent(f1);
}
}
}
DateField
A DateField is an editable component for presenting date and time (calendar) information that may be placed into a Form.
Example
DateField1
midlet contains two DateField components. The
first component is for entering a date and the second is for entering a time.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;
public class DateField1 extends MIDlet implements CommandListener
{
private Display display;
private Form f1;
private Form f2;
private DateField date;
private DateField time;
private Command okCommand;
private Command exitCommand;
private Command backCommand;
public DateField1()
{
display = Display.getDisplay(this);
date = new DateField("Date", DateField.DATE);
time = new DateField("Time", DateField.TIME);
f1 = new Form("Date and time");
okCommand = new Command("Ok", Command.SCREEN, 0);
exitCommand = new Command("Exit", Command.EXIT, 0);
backCommand = new Command("Back", Command.BACK, 0);
}
public void startApp()
{
f1.append(date);
f1.append(time);
f1.addCommand(okCommand);
f1.addCommand(exitCommand);
f1.setCommandListener(this);
display.setCurrent(f1);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
public void commandAction(Command c, Displayable s)
{
if(c == okCommand)
{
f2 = new Form("Date and time");
Calendar cal = Calendar.getInstance();
Date datex = date.getDate();
cal.setTime(datex);
String text = "Date: " + cal.get(Calendar.DATE) + "." +
cal.get(Calendar.MONTH) + "." +
cal.get(Calendar.YEAR);
cal.setTime(time.getDate());
text = text + "\ntime: " + cal.get(Calendar.HOUR) + ":" +
+ cal.get(Calendar.MINUTE);
f2.append(text);
f2.addCommand(backCommand);
f2.setCommandListener(this);
display.setCurrent(f2);
}else if(c == exitCommand)
{
destroyApp(false);
notifyDestroyed();
}else if(c == backCommand)
{
display.setCurrent(f1);
}
}
}
List
A List is a choice component and because it is derived from Screen class, it is present on the whole display. The List is suitable for representing a menu. The List has three types: IMPLICIT, EXCLUSIVE and MULTIPLE.
Examples
- List1 midlet has an IMPLICIT type List component. Notice the use of SELECT_COMMAND
- List2 midlet has an EXCLUSIVE type List component
- List3 midlet has a MULTIPLE type List component
Alert
An Alert is a screen that shows data to the user and waits for a certain period of time before proceeding to the next screen. The intent of Alert is to inform the user about events, warnings, errors and other exceptional conditions. An alert can contain a text string and an image.
The Alert class has 2 constructors:
- Alert(String title)
- Alert(String title, String alertText, Image alertImage, AlertType alertType)
Parameter title is the title string, alertText is the text in the display, alertImage is the image in the display and alertType is the type of alert (ALARM, CONFIRMATION, ERROR, INFO or WARNING).
The application can set the alert time with setTimeout(int time) method. The time is in milliseconds. If the time parameter is Alert.FOREVER, the alert time is infinite. Then the Alert is in the modal mode and user have to quit the alert.
Example.
If you select Email in the display of the Alert1
midlet, an Alert screen appears on the display
for 3 seconds. If you select Text messages, an
modal Alert screen appears and you have to quit
it, if you want it to disappear.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Alert1 extends MIDlet implements CommandListener
{
private Display display;
private List list;
private Alert alert1;
private Alert alert2;
private Command cmExit;
public Alert1()
{
display = Display.getDisplay(this);
String medias[] = {"Emails", "Text messages", "Calls", "MMS messages"};
list = new List("Medias", List.IMPLICIT, medias, null);
cmExit = new Command("Exit", Command.EXIT, 0);
}
public void startApp()
{
list.addCommand(cmExit);
list.setCommandListener(this);
display.setCurrent(list);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
public void commandAction(Command c, Displayable s)
{
if(c == List.SELECT_COMMAND)
{
if(list.getSelectedIndex() == 0){
alert1 = new Alert("Warning", "Email is out of order", null, AlertType.WARNING);
alert1.setTimeout(3000);
display.setCurrent(alert1);
}
if(list.getSelectedIndex() == 1){
alert2 = new Alert("Question", "Do you really want to read the text messages?", null, AlertType.INFO);
alert2.setTimeout(Alert.FOREVER);
display.setCurrent(alert2);
}
String selection = list.getString(list.getSelectedIndex());
System.out.println("Selection: " + selection);
}
else if(c == cmExit)
{
destroyApp(false);
notifyDestroyed();
}
}
}
Image
The Image class is used to hold graphical image data. Images may be placed within Alert, Choice, Form, or ImageItem objects.
Image object is created with one of the static createImage() methods of the Image class:
- createImage(byte[] imagedata, int imageOffset, int imageLength),
- createImage(Image source)
- createImage(Image image, int x, int y, int width, int height, int transform)
- createImage(InputStream stream)
- createImage(int width, int height)
- createImage(String name)
- createImage(int[] rgb, int width, int height, boolean processAlpha)
ImageItem
ImageItem class is extended from Item class and can so be placed into a form. ImageItem object can contain a image. Each ImageItem object contains a reference to an Image object.
ImageItem has 2 constructors:
ImageItem(String label, Image img, int layout, String altText)
ImageItem(String label, Image img, int layout, String altText, int appearanceMode)
Parameter label is a label string, img is the image, layout is combination of layout directives, altText is a alternative text and appearanceMode is an appearance mode.
The layout directives are LAYOUT_CENTER, LAYOUT_DEFAULT, LAYOUT_LEFT, LAYOUT_NEWLINE_BEFORE, LAYOUT_NEWLINE_AFTER, LAYOUT_RIGHT.
The appearance modes are PLAIN, HYPERLINK, BUTTON.
Example.
Image1
midlet creates an Image and ImageItem
objects with an image of Duke. Download the image , Duke.png,
to the res directory of your project.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Image1 extends MIDlet
{
private Display display;
private Form form;
private ImageItem image;
public Image1()
{
display = Display.getDisplay(this);
form = new Form("Picture");
Image im = null;
try{
im = Image.createImage("/Duke.png");
}catch(Exception e){
System.out.println("** Error creating image");
}
image = new ImageItem("Picture of Duke",im, Item.LAYOUT_CENTER, "Duke's image" );
}
public void startApp()
{
form.append(image);
display.setCurrent(form);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
}
The display of the midlet is in the following figure.

4.Low level UI API
The Canvas class is a base class
for writing applications that need to handle low-level events and to issue
graphics calls for drawing to the display.
Canvas uses coordinate system for placing graphical figures on the display. The display has the dimensions: width and height. Location 0,0 in the coordinates is in the upper left corner of the display, x value increases to the right and y value increases down.

We can use getHeight() and getWidth() methods of Displayable class to get the height and width in pixel of the display of the device.
Because the Canvas class is defined as abstract, you have to create a subclass of Canvas. Canvas class has abstract paint(Graphics g) method for using graphics. So you have to write paint(Graphics g) method into your canvas.
The Graphics class provides primitives for drawing lines, rectangles, arcs, text and images. Rectangles and arcs may also be filled with a solid color. Rectangles may also be specified with rounded corners. The Graphics class includes among others following methods:
- drawArc(), draws the outline of a circular or elliptical arc
- drawChar(), draws the specified character using the current font and color
- drawChars(), draws the specified characters using the current font and color
- drawImage(), draws the specified image
- drawLine(), draws a line between 2 coordinates
- drawRect(), draws the specified rectangle
- drawRoundRect(), draws the outline of the specified rounded corner rectangle
- drawString(), draws a String using the current font and color
- fillArc(), fills the specified arc with a current color
- fillRect(), fills the specified rectangle with a current color
- setColor(), set the current color to the specified RGB values
- setFont(), set the current font
- setGrayScale(), set the current grayscale to be used for all subsequent renderin operatios. The value must be in the range 0-255 ( 0 means black and 255 means white).
Example.
The underlying midlet Drawing1 sets into the
display a Canvas instance, Canvas1.
The Canvas1 class is below.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Drawing1 extends MIDlet {
public void startApp () {
Display.getDisplay (this).setCurrent (new Canvas1 ());
}
public void pauseApp () {}
public void destroyApp (boolean forced) {}
}
The Canvas1 class shows firstly on the console the width and height of the display, clean the display and draw a line and a rectanular. Then it changes the color and draws a circle and finally it changes again color and fills a rectangular. See accurate method descriptions in the API documentation of the MIDP.
import javax.microedition.lcdui.*;
class Canvas1 extends Canvas {
public void paint (Graphics g) {
// shows the width and height of the display on console
System.out.println("Width " + getWidth());
System.out.println("Height " + getHeight());
// clean the display
g.setGrayScale (255);
g.fillRect (0, 0, getWidth (), getHeight ());
g.setGrayScale (0);
g.drawLine (20, 33, 170, 61);
g.drawRect(40, 65, 60, 40);
g.setColor(255, 0, 255);
g.drawArc(10,120,50,50,0,360);
g.setColor(0, 255, 255);
g.fillRect(130, 110, 30, 40);
}
}
You see below what kind of figures the midlet has drawn.

The method setColor(int red, int green, int blue) of Graphics class changes the drawing and filling color in the following way.
| Parameters of setColor() | Color |
| setColor(255,0,0) | red |
| setColor(0,255,0) | green |
| setColor(0,0,255) | blue |
| setColor(0,0,0) | black |
| setColor(255,255,255) | white |
| setColor(255,255,0) | yellow |
When drawing lines, rectangles and arcs, the line can be solid or dash line. Graphics class has setStrokeStyle() method for setting the style of the line. It's parameter can be Graphics.DOTTED or Graphics.SOLID.
Drawing text
The method drawString(String str, int x, int y, int anchor) of the Graphics class draws a string on the canvas:
- parameter str is the string to be drawn
- parameters x and y declare the position of the text.
- the third parameter anchor is a point for
positioning the text in the relation to the point (x,y).
Its value must be zero (0) or one of the horizontal constans(
LEFT, HCENTER, RIGHT) combined by using bit-wise or operator with one of the vertical constants(TOP, BASELINE, BOTTOM)
Example.
Canvas2 draws "Good
morning" string into the position: x = 2 and y = 5. And then it
draws the strings "ONE", "TWO"
and "THREE" into the same location,
whose position is: x = getWidth()/2 and y = getHeight()/2
(the middle point of the display). But every string has different anchor in
relation to the drawing location.
import javax.microedition.lcdui.*;
class Canvas2 extends Canvas {
public void paint (Graphics g) {
g.setGrayScale (255);
g.fillRect (0, 0, getWidth (), getHeight ());
g.setGrayScale (0);
g.drawString("Good morning!",2, 5, 0);
g.drawString("ONE",getWidth ()/2, getHeight ()/2, Graphics.LEFT|Graphics.TOP);
g.drawString("TWO",getWidth ()/2, getHeight ()/2, Graphics.RIGHT|Graphics.BOTTOM);
g.drawString("THREE",getWidth ()/2, getHeight ()/2, Graphics.LEFT|Graphics.BASELINE);
}
}
You can see in the picture below, how the strings are located on the display.

Drawing arcs
The Graphics class has drawArc() method for drawing arcs. The signature of the drawArc() method is following:
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
where
- x = the x coordinate of the upper-left corner of the arc to be drawn
- y = the y coordinate of the upper-left corner of the arc to be drawn
- width = the width of the arc to be drawn
- height = the height of the arc to be drawn
- startAngle = the beginning angle (0 = at 3 o'clock)
- arcAngle = the angular extent of the arc, relative to the start angle (360 = the whole circle)
Example.
Canvas3
draws vertical and horizontal dotted lines and divides the screen to 4 parts.
Then different arcs are drawn in every part of the screen.
import javax.microedition.lcdui.*;
class Canvas3 extends Canvas {
public void paint (Graphics g) {
// clean the display
g.setGrayScale (255);
g.fillRect (0, 0, getWidth (), getHeight ());
// draw the dotted lines
g.setGrayScale (0);
g.setStrokeStyle(Graphics.DOTTED);
g.drawLine (getWidth()/2, 0, getWidth()/2, getHeight());
g.drawLine (0, getHeight()/2, getWidth(), getHeight()/2);
// draw the red arcs with solid lines
g.setStrokeStyle(Graphics.SOLID);
g.setColor(255, 0, 0);
g.drawArc(20,40,80,80,0,240);
g.drawArc(140,40,80,80,90,240);
g.drawArc(30,160,60,110,0,360);
g.fillArc(140,170,80,80,0,110);
}
}
The display of the program is below:

Drawing rectangles
Graphics class has drawRect() and drawRoundRect() methods for drawing of rectangles:
void drawRect(int x, int y, int width, int height) void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
Example.
Canvas4
draws four rectangles: a rectangle, a rectangle with rounded corners, a filled
rectangle and a filled rectangle with rounded corners.
import javax.microedition.lcdui.*;
class Canvas4 extends Canvas {
public void paint (Graphics g) {
// clean the display
g.setGrayScale (255);
g.fillRect (0, 0, getWidth (), getHeight ());
// draw the dotted lines
g.setGrayScale (0);
g.setStrokeStyle(Graphics.DOTTED);
g.drawLine (getWidth()/2, 0, getWidth()/2, getHeight());
g.drawLine (0, getHeight()/2, getWidth(), getHeight()/2);
// draw rectangles and filled rectangles
g.setStrokeStyle(Graphics.SOLID);
g.setColor(0, 0, 255);
g.drawRect(20,20,50,40);
g.drawRoundRect(105,20,60,40, 20, 20);
g.fillRect(20,100,50,40);
g.setColor(0, 255, 0);
g.fillRoundRect(100,100,60,40,15,15);
}
}
The display of the Canvas4 is below.

Drawing images
For drawing images the Graphics class has a drawImage(Image image, int x, int y, int anchor) method. Parameter image is Image object, which has to create before drawing the image.
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 as blank images containing only white pixels. The application may render on a mutable image by calling getGraphics() of the Image object to obtain a Graphics object expressly for this purpose.
Example.
Canvas5 creates
a immutable image and shows it. The constructor creates first a Image
object from a image file, picx.png. The method paint()
calls the drawImage() method of the Graphics
ohject and draws the image on the display. Download picx.png
and place it to res directory of the MIDP
project.
import javax.microedition.lcdui.*;
class Canvas5 extends Canvas {
Image image;
public Canvas5()
{
try{
image = Image.createImage("/picx.png");
}catch(java.io.IOException e){
System.out.println("** Error, creating image");
}
}
public void paint (Graphics g) {
// clean the display
g.setGrayScale (255);
g.fillRect (0, 0, getWidth (), getHeight ());
if(image != null)
g.drawImage(image, 20, 40, 0);
}
}
The creation of a mutable image has the following phases:
- allocate the image in the memory:
Image image = Image.createImage(60, 50); - get the Graphics object for creating of
the image content
Graphics g = image.getGraphics(); - create the content of the image using text, rectangles, arcs, lines
and colors
g.drawRect(10, 20, image.getWidth(), image.getHeight(); - show the image on the display
public void paint (Graphics g) {
....
g.drawImage(image, 10, 30, 0);
Example.
Canvas6
creates a mutable image and displays it.
import javax.microedition.lcdui.*;
class Canvas6 extends Canvas {
Image image;
public Canvas6()
{
try{
image = Image.createImage(60, 50);
Graphics g = image.getGraphics();
g.setColor(0, 0, 255);
g.fillRect(0, 0, image.getWidth()-1, image.getHeight()-1);
g.setColor(255, 0, 0);
g.fillArc(24,6, 12, 36, 0, 360);
g.fillArc(8,18, 44, 10, 0, 360);
}catch(Exception e){
System.out.println("** Error, creating image");
}
}
public void paint (Graphics g) {
// clean the display
g.setGrayScale (255);
g.fillRect (0, 0, getWidth (), getHeight ());
if(image != null)
g.drawImage(image, getWidth()/2, 10, Graphics.HCENTER|Graphics.TOP);
}
}
The display of the program is below.

Commands in the Canvas
Example.
XMidlet
has a Canvas with the Exit Command.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class XMidlet extends MIDlet
{
private Display display;
private XCanvas canvas;
public XMidlet()
{
display = Display.getDisplay(this);
canvas = new XCanvas(this);
}
public void startApp()
{
display.setCurrent(canvas);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
public void exit()
{
destroyApp(false);
notifyDestroyed();
}
}
class XCanvas extends Canvas implements CommandListener
{
private XMidlet midlet;
private Command cmExit;
public XCanvas(XMidlet midlet)
{
this.midlet = midlet;
cmExit = new Command("Exit", Command.EXIT, 0);
addCommand(cmExit);
setCommandListener(this);
}
public void paint (Graphics g) {
// clean the display
g.setGrayScale (255);
g.fillRect (0, 0, getWidth (), getHeight ());
g.setGrayScale (0);
g.drawLine (20, 33, 170, 61);
g.drawRect(40, 65, 60, 40);
g.setColor(255, 0, 255);
g.drawArc(10,120,50,50,0,360);
g.setColor(0, 255, 255);
g.fillRect(130, 110, 30, 40);
}
public void commandAction(Command c, Displayable s)
{
if(c == cmExit)
{
midlet.exit();
}
}
}
Canvas class has keyPressed(int keyCode), keyReleased(int keyCode) and keyRepeated(int keyCode) methods, which are called, when the corresponding key event occurs. Parameter keyCode defines, what key was pressed or released. MIDP defines the following key codes: KEY_NUM0, KEY_NUM1, KEY_NUM2, KEY_NUM3, KEY_NUM4, KEY_NUM5, KEY_NUM6, KEY_NUM7, KEY_NUM8, KEY_NUM9, KEY_STAR, KEY_POUND. These key codes correspond to keys on a standard keypad. Method keyRepeated() is called when a key is repeated held down, but the method may not be supported on all devices.
The method getKeyName(int keyCode) returns a name of the key code.
MIDP defines some constants for game action key codes: UP, DOWN, LEFT, RIGHT, FIRE, GAME_A, GAME_B, GAME_C, GAME_D.
Example.
The following YMidlet
midlet has in the display YCanvas, which
reacts to "key pressed" and "key released" events by
means of the keyPressed()and keyReleased()methods
and shows the name of the event and the name of the key on the display.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class YMidlet extends MIDlet
{
private Display display;
private YCanvas canvas;
public YMidlet()
{
display = Display.getDisplay(this);
canvas = new YCanvas(this);
}
public void startApp()
{
display.setCurrent(canvas);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
public void exit()
{
destroyApp(false);
notifyDestroyed();
}
}
class YCanvas extends Canvas implements CommandListener
{
private YMidlet midlet;
private Command cmExit;
private String text = null;
public YCanvas(YMidlet midlet)
{
this.midlet = midlet;
cmExit = new Command("Exit", Command.EXIT, 0);
addCommand(cmExit);
setCommandListener(this);
}
public void paint (Graphics g) {
// clean the display
g.setGrayScale (255);
g.fillRect (0, 0, getWidth (), getHeight ());
g.setGrayScale (0);
g.setColor(0,0,255);
g.drawLine (0, 10, getWidth(), 10);
if(text != null)
{
g.setColor(0, 0, 0);
g.drawString(text, 10, 30, 0);
}
}
protected void keyPressed(int keyCode)
{
text = "pressed " + getKeyName(keyCode);
repaint();
}
protected void keyReleased(int keyCode)
{
text = "released " + getKeyName(keyCode);
repaint();
}
public void commandAction(Command c, Displayable s)
{
if(c == cmExit)
{
midlet.exit();
}
}
}
5. Timer functions
MIDP includes for timer functions (scheduling) two classes: Timer and TimerTask classes.
The Timer class is for scheduling when a task will occur. The TimerTask class is for performing a task.
The Timer class has 6 scheduling methods and one terminating cancel() method:
- void schedule(TimerTask task, long delay),
- void schedule(TimerTask task, Date time),
- void schedule(TimerTask task, Date firstTime, long period),
- void schedule(TimerTask task, long delay, long period),
- void scheduleAtFixedRate(TimerTask task, long delay, long period),
- void scheduleAtFixedRate(TimerTask task, Date firstTime, long period),
- void cancel()
which have the following parameters:
- task is a task to be scheduled
- delay is a delay in milliseconds before the task is to be executed
- time is a time at which the task is to be executed
- firstTime is the first time at which the task is to be executed
- period is a time in milliseconds between successive task executions.
The schedule() methods with a periodically repeating task are fixed-delay type: the start of each task is based on the time since the previous task finished. The execution time of a task can increase for any reason (for example garbage collection). The scheduleAtFixedRate() methods are fixed-rate type: the start of each task is based on the time since the previous task started.
The cancel() method terminates the timer and discards any currently scheduled tasks.
A task, that can be scheduled for one-time or repeated execution by a Timer object, has to code in a class that is extended from abstract TimerTask class. TimerTask class implements a Runnable interface and so it must have public void run() method, which contains the executed task.
Example.
Timer1 midlet
has a Timer object for scheduling a task, which
is programmed in the run() method of a TestTimerTask
class. The midlet uses all 6 scheduling ways of the Timer
class. Take the comments away from each schedule()
method by turns.
//Example from the book:Core J2ME Technology, John W. Muchow
import java.util.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Timer1 extends MIDlet implements CommandListener
{
private Display display;
private Form fmMain;
private Command cmExit;
private Command cmStop; // Stop the timer
private Timer tm; // Timer
private TestTimerTask tt; // Task
private int count = 0; // How many times has task run
public Timer1()
{
display = Display.getDisplay(this);
fmMain = new Form("Timer Test");
fmMain.append("waiting...\n");
cmExit = new Command("Exit", Command.EXIT, 1);
cmStop= new Command("Stop", Command.STOP, 2);
fmMain.addCommand(cmExit);
fmMain.addCommand(cmStop);
fmMain.setCommandListener(this);
// Create a timer that will go off in 5 seconds
tm = new Timer();
tt = new TestTimerTask();
tm.schedule(tt,5000);
// Create a timer that will go off in 5 seconds, repeating every 3 seconds
// tm = new Timer();
// tt = new TestTimerTask();
// tm.schedule(tt,5000, 3000);
// Create a timer that will go off in 5 seconds, repeating every 3 seconds
// tm = new Timer();
// tt = new TestTimerTask();
// tm.scheduleAtFixedRate(tt,5000, 3000);
// Create timer that starts at current date
// tm = new Timer();
// tt = new TestTimerTask();
// tm.schedule(tt, new Date());
// Create timer that starts at current date, repeating every 3 seconds
// tm = new Timer();
// tt = new TestTimerTask();
// tm.schedule(tt, new Date(), 3000);
// Create timer that starts at current date, repeating every 3 seconds
// tm = new Timer();
// tt = new TestTimerTask();
// tm.scheduleAtFixedRate(tt, new Date(), 3000);
}
public void startApp ()
{
display.setCurrent(fmMain);
}
public void destroyApp (boolean unconditional) {}
public void pauseApp () { }
public void commandAction(Command c, Displayable d)
{
if (c == cmStop)
{
tm.cancel();
}
else if (c == cmExit)
{
destroyApp(false);
notifyDestroyed();
}
}
private class TestTimerTask extends TimerTask
{
public final void run()
{
fmMain.append("run count: " + ++count + "\n");
}
}
}
Animation.java, AnimationCanvas.java, AnimateTimerTask.java
6. The Game API
The Game API package provides a series of classes that enable the development of rich gaming content for wireless devices. The Game API classes are in the javax.microedition.lcdui.game package.
The Game API is comprised of five classes:
GameCanvas
This class is a subclass of LCDUI's Canvas and provides the basic 'screen' functionality for a game. In addition to the methods inherited from Canvas, this class also provides game-centric features such the ability to query the current state of the game keys and synchronous graphics flushing; these features simplify game development and improve performance.
Layer
The Layer class represents a visual element in a game such as a Sprite or a TiledLayer. This abstract class forms the basis for the Layer framework and provides basic attributes such as location, size, and visibility.
A game can have many layers.
LayerManager
For games that employ several Layers, the LayerManager simplifies game development by automating the rendering process. It allows the developer set a view window that represents the user's view of the game. The LayerManager automatically renders the game's Layers to implement the desired view.
Sprite
A Sprite is basic animated Layer that can display one of several graphical frames. The frames are all of equal size and are provided by a single Image object. In addition to animating the frames sequentially, a custom sequence can also be set to animation the frames in an arbitrary manner. The Sprite class also provides various transformations (flip and rotation) and collision detection methods that simplify the implementation of a game's logic.
TiledLayer
This class enables a developer to create large areas of graphical content without the resource usage that a large Image object would require. It is a comprised of a grid of cells, and each cell can display one of several tiles that are provided by a single Image object. Cells can also be filled with animated tiles whose corresponding pixel data can be changed very rapidly; this feature is very useful for animating large groups of cells such as areas of water.
7. Network connections
CLDC has the Generic Connection Framework for supporting input/output and networking in a generalized, extensible fashion.
The basic idea is to have one class, the Connector, that can create any kind of connection: file, http, datagram, etc. Connector class has the static open() method, which creates the connection and whose method call is following:
Connection Connector.open("protocol:address;parameters");
The open() method returns Connection object, which represents a general network connection. The parameter of the method is a string with an URL address. The URL address contains 3 part: a name of the protocol, some kind of network address and parameterss in the form: "name=value".
Examples of the Connector.open() methods are below:
Connector.open("http://www.company.com/somepath/document.doc");
Connector.open("socket://127.166.8.16:9000");
Connector.open("file:/foo.txt");
Connection
The Connection interface represents data communication connection generally. It has only a method, close(), which closes the connection. The opening of the connection was achieved with the Connector.open() method.
Many kind of interfaces, which represent different kind of communications, are extened from Connection interface. See the figure below. HttpConnection is for HTTP connection and HttpsConnection for secure HTTP connection.

HttpConnection
The HttpConnection interface defines the necessary methods and constants for an HTTP connection.
HTTP is an Internet protocol, which functions according to the request-response principle. The parameters of a request must be set before sending of the request. The HTTP connection exists in one of three states:
- Setup, in which state the midlet has no connection to a server and the request parameters can be set
- Connected, in which state the midlet has connection to the server, request parameters have been sent and the response is expected
- Closed, the final state, in which the HTTP connection as been terminated
The following methods may be invoked only in the Setup state:
- setRequestMethod()
- setRequestProperty()
The transition from Setup to Connected is caused by any method that requires data to be sent to or received from the server. The following methods cause the transition to the Connected state, when the connection is in Setup state.
- openInputStream()
- openDataInputStream()
- getLength()
- getType()
- getEncoding()
- getHeaderField()
- getResponseCode()
- getResponseMessage()
- getHeaderFieldInt()
- getHeaderFieldDate()
- getExpiration()
- getDate()
- getLastModified()
- getHeaderField()
- getHeaderFieldKey()
The following methods may be invoked while the connection is in Setup or Connected state.
- close()
- getRequestMethod()
- getRequestProperty()
- getURL()
- getProtocol()
- getHost()
- getFile()
- getRef()
- getPort()
- getQuery()
It is recommended to launch a thread to handle the network connection. This prevents the main program stopping while connecting and reading or writing data in a network. The task of the main program is to handle a user interface and its events.
Example.
The Conn
midlet requests a docuX.txt file on the localhost
server (http://localhost:8080/docuX.txt) and
shows the content of the docuX.txt on the
display. Edit docuX.txt
text file and save it into the ROOT directory of
Tomcat server. The midlet has a "Connect" command, which start a
thread. And the thread connect to the server and read the text file.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
public class Conn extends MIDlet implements CommandListener
{
private String url = "http://localhost:8080/docuX.txt";
private Display display;
private TextBox text;
private Command cmConnect;
private Command cmExit;
public Conn()
{
display = Display.getDisplay(this);
text = new TextBox("Network connection", "", 100, TextField.ANY);
cmConnect = new Command("Connect", Command.SCREEN, 1);
cmExit = new Command("Exit", Command.EXIT, 1);
}
public void startApp()
{
text.addCommand(cmConnect);
text.addCommand(cmExit);
text.setCommandListener(this);
display.setCurrent(text);
}
public void commandAction(Command c, Displayable s)
{
if(c == cmConnect)
{
Thread t = new Thread(){
public void run(){
connect();
}
};
t.start();
}
else if(c == cmExit)
{
destroyApp(false);
notifyDestroyed();
}
}
private void connect()
{
HttpConnection httpConn = null;
InputStream in = null;
try
{
httpConn = (HttpConnection) Connector.open(url);
in = httpConn.openInputStream();
int length = (int) httpConn.getLength();
byte data[] = new byte[length];
in.read(data);
String str = new String(data);
text.setString(str);
System.out.println("The content of docuX:\n" + str);
in.close();
httpConn.close();
}catch(IOException ex){
text.setString("** Error, connecting... : " + ex.getMessage());
}
}
public void pauseApp(){}
public void destroyApp(boolean b){}
}
Example.
A Conn2 is a technical midlet without a user
interface. The midlet sends a HTTP request to the server, gets a HTTP response
and shows HTTP technical information on the console. Because the midlet has no
user interface, it doesn't need to start a thread.
/*-------------------------------------------------- * * Send client request (method, header, body) * Get server response (status, header, body) * * Example from the book: Core J2ME Technology * Copyright John W. Muchow http://www.CoreJ2ME.com * You are free to use/modify this source code. *-------------------------------------------------*/ import javax.microedition.midlet.*; import javax.microedition.io.*; import java.io.*; public class Conn2 extends MIDlet { private String url = "http://localhost:8080/docuX.txt"; public void startApp() { try{ connect(); } catch (Exception e) { System.out.println("*** Connecting error" + e.getMessage()); } } private void connect() throws IOException { HttpConnection httpConn = null; InputStream iStrm = null; try { httpConn = (HttpConnection) Connector.open(url); httpConn.setRequestMethod(HttpConnection.GET); httpConn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.1"); System.out.println("url: " + url); System.out.println("-------------------------"); System.out.println("Msg: " + httpConn.getResponseMessage()); System.out.println("Code: " + httpConn.getResponseCode()); if (httpConn.getResponseCode() == HttpConnection.HTTP_OK) { System.out.println("field 0: " + httpConn.getHeaderField(0)); System.out.println("field 1: " + httpConn.getHeaderField(1)); System.out.println("field 2: " + httpConn.getHeaderField(2)); System.out.println("-------------------------"); System.out.println("key 0: " + httpConn.getHeaderFieldKey(0)); System.out.println("key 1 : " + httpConn.getHeaderFieldKey(1)); System.out.println("key 2: " + httpConn.getHeaderFieldKey(2)); System.out.println("-------------------------"); System.out.println("content: " + httpConn.getHeaderField("content-type")); System.out.println("date: " + httpConn.getHeaderField("date")); System.out.println("last-modified: " + httpConn.getHeaderField("last-modified")); System.out.println("-------------------------"); String str; iStrm = httpConn.openInputStream(); int length = (int) httpConn.getLength(); if (length != -1) { byte serverData[] = new byte[length]; iStrm.read(serverData); str = new String(serverData); } else // Length not available... { ByteArrayOutputStream bStrm = new ByteArrayOutputStream(); int ch; while ((ch = iStrm.read()) != -1) bStrm.write(ch); str = new String(bStrm.toByteArray()); bStrm.close(); } System.out.println("The content of the file:\n " + str); System.out.println("Host: " + httpConn.getHost()); System.out.println("Port: " + httpConn.getPort()); System.out.println("Type: " + httpConn.getType()); } } finally { if (iStrm != null) iStrm.close(); if (httpConn != null) httpConn.close(); } } public void pauseApp() { } public void destroyApp(boolean unconditional) { } }
Servlet connection
Example.
ConnServlet is a simple servlet, which
sends a HTTP response to a HTTP request sended by GET
method.. The response contains some
text and an increasing number. Conn3 is a midlet, which sends a HTTP request
by GET method to the preceding servlet.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class ConnServlet extends HttpServlet
{
private int number = 0;
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.print("This a servlet \nand the number is " + ++number);
out.close();
}
}
The web descriptor of the preceding servlet, web.java, is below.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>servletX</servlet-name>
<servlet-class>ConnServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletX</servlet-name>
<url-pattern>/servlet/example1</url-pattern>
</servlet-mapping>
</web-app>
And Conn3 midlet is in the following program code.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
public class Conn3 extends MIDlet implements CommandListener
{
private Display display;
private Form form;
private Command cmConnect;
private Command cmExit;
private StringItem teksti;
public Conn3()
{
display = Display.getDisplay(this);
cmConnect = new Command("Connect", Command.SCREEN, 1);
cmExit = new Command("Exit", Command.EXIT, 1);
teksti = new StringItem(null, "If you want servlet connection, select Connect");
form = new Form("Servlet connection");
form.addCommand(cmExit);
form.addCommand(cmConnect);
form.append(teksti);
form.setCommandListener(this);
}
public void startApp()
{
display.setCurrent(form);
}
public void pauseApp()
{ }
public void destroyApp(boolean unconditional)
{ }
public void commandAction(Command c, Displayable s)
{
if (c == cmConnect)
{
Thread t = new Thread(){
public void run(){
try{
connect();
} catch (Exception e){
System.err.println("Msg: " + e.toString());
}
}
};
t.start();
}
else if (c == cmExit)
{
destroyApp(false);
notifyDestroyed();
}
}
private void connect() throws IOException
{
HttpConnection conn = null;
InputStream input = null;
String url = "http://localhost:8080/servlet/example1";
try
{
conn = (HttpConnection) Connector.open(url);
input = conn.openInputStream();
if (conn.getResponseCode() == HttpConnection.HTTP_OK)
{
int length = (int) conn.getLength();
String str;
if (length != -1)
{
byte data[] = new byte[length];
input.read(data);
str = new String(data);
}
else // no length of the message
{
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
int ch;
while ((ch = input.read()) != -1)
bStream.write(ch);
str = new String(bStream.toByteArray());
bStream.close();
}
teksti.setText(str);
} else
teksti.setText(new String(conn.getResponseMessage()));
}
finally
{
if (input != null)
input.close();
if (conn != null)
conn.close();
}
}
}
Example.
Conn4Servlet is a servlet, which gets in a
GET request two parameters, userID and password,
and sends a response. Conn4 is a midlet, which
sends a GET request with two parameters , userID
and password, and receives the response and
shows it on the display.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class Conn4Servlet extends HttpServlet
{
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
String userID = req.getParameter("userID");
String password = req.getParameter("password");
out.println(userID + ", Password is not valid");
out.close();
}
}
The Conn4 midlet is below.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
public class Conn4 extends MIDlet implements CommandListener
{
private Display display;
private Form form;
private Form form2;
private TextField userID;
private TextField password;
private StringItem text;
private Command cmConnect;
private Command cmExit;
public Conn4()
{
display = Display.getDisplay(this);
cmConnect = new Command("Connect", Command.SCREEN, 1);
cmExit = new Command("Exit", Command.EXIT, 1);
userID = new TextField("User id:", "", 10, TextField.ANY);
password = new TextField("Password:", "", 10, TextField.PASSWORD);
form = new Form("Login");
form.addCommand(cmExit);
form.addCommand(cmConnect);
form.append(userID);
form.append(password);
form.setCommandListener(this);
}
public void startApp()
{
display.setCurrent(form);
}
public void pauseApp()
{ }
public void destroyApp(boolean unconditional)
{ }
public void commandAction(Command c, Displayable s)
{
if (c == cmConnect)
{
Thread t = new Thread(){
public void run(){
try{
connect();
} catch (Exception e){
System.err.println("Msg: " + e.toString());
}
}
};
t.start();
}
else if (c == cmExit)
{
destroyApp(false);
notifyDestroyed();
}
}
private void connect() throws IOException
{
HttpConnection conn = null;
InputStream input = null;
String url = "http://localhost:8080/servlet/example2?userID=" +
userID.getString() + "&password=" + password.getString();
try
{
conn = (HttpConnection) Connector.open(url);
input = conn.openInputStream();
process(conn, input);
}
finally
{
if (input != null)
input.close();
if (conn != null)
conn.close();
}
}
private void process(HttpConnection conn, InputStream input) throws IOException
{
text = new StringItem("Login:", "");
if (conn.getResponseCode() == HttpConnection.HTTP_OK)
{
int length = (int) conn.getLength();
String str;
if (length != -1)
{
byte data[] = new byte[length];
input.read(data);
str = new String(data);
}
else // no length returned
{
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
int ch;
while ((ch = input.read()) != -1)
bStream.write(ch);
str = new String(bStream.toByteArray());
bStream.close();
}
text.setText(str);
} else
text.setText(new String(conn.getResponseMessage()));
// show main window
form2 = new Form("Main window");
form2.addCommand(cmExit);
form2.append(text);
form2.setCommandListener(this);
display.setCurrent(form2);
}
}
Web descriptor for the servlet, web.xml, is following.
<servlet>
<servlet-name>servletY</servlet-name>
<servlet-class>Conn4Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletY</servlet-name>
<url-pattern>/servlet/example2</url-pattern>
</servlet-mapping>
Example.
Conn5Servlet is a servlet, which receives
HTTP request by POST method and sends a
response. The request has two parameters, userID and password.
Conn5 is a midlet , which
sends a POST request with two parameters , userID
and password, and receives the response and
shows it on the display.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class Conn5Servlet extends HttpServlet
{
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
String userID = req.getParameter("userID");
String password = req.getParameter("password");
out.println(userID + ", Password is not valid");
out.close();
}
}
The Conn5 midlet is below.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
public class Conn5 extends MIDlet implements CommandListener
{
private Display display;
private Form form;
private Form form2;
private TextField userID;
private TextField password;
private StringItem teksti;
private Command cmConnect;
private Command cmExit;
public Conn5()
{
display = Display.getDisplay(this);
cmConnect = new Command("Connect", Command.SCREEN, 1);
cmExit = new Command("Exit", Command.EXIT, 1);
userID = new TextField("User id:", "", 10, TextField.ANY);
password = new TextField("Password:", "", 10, TextField.PASSWORD);
form = new Form("Login");
form.addCommand(cmExit);
form.addCommand(cmConnect);
form.append(userID);
form.append(password);
form.setCommandListener(this);
}
public void startApp()
{
display.setCurrent(form);
}
public void pauseApp(){ }
public void destroyApp(boolean unconditional){ }
public void commandAction(Command c, Displayable s)
{
if (c == cmConnect)
{
Thread t = new Thread(){
public void run(){
try{
connect();
} catch (Exception e){
System.err.println("Msg: " + e.toString());
}
}
};
t.start();
}
else if (c == cmExit)
{
destroyApp(false);
notifyDestroyed();
}
}
private void connect() throws IOException
{
HttpConnection conn = null;
OutputStream output = null;
InputStream input = null;
String url = "http://localhost:8080/servlet/example3";
try
{
conn = (HttpConnection) Connector.open(url);
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.1");
output = conn.openOutputStream();
byte data[] = ("userID=" + userID.getString()).getBytes();
output.write(data);
data = ("&password=" + password.getString()).getBytes();
output.write(data);
output.close();
input = conn.openInputStream();
kasittely(conn, input);
}
finally
{
if (input != null)
input.close();
if (conn != null)
conn.close();
}
}
private void kasittely(HttpConnection conn, InputStream input) throws IOException
{
teksti = new StringItem("Login:", "");
if (conn.getResponseCode() == HttpConnection.HTTP_OK)
{
int length = (int) conn.getLength();
String str;
if (length != -1)
{
byte data[] = new byte[length];
input.read(data);
str = new String(data);
}
else // no length returned
{
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
int ch;
while ((ch = input.read()) != -1)
bStream.write(ch);
str = new String(bStream.toByteArray());
bStream.close();
}
teksti.setText(str);
} else
teksti.setText(new String(conn.getResponseMessage()));
// shows main window
form2 = new Form("Main window");
form2.addCommand(cmExit);
form2.append(teksti);
form2.setCommandListener(this);
display.setCurrent(form2);
}
}
Web descriptor for the servlet, web.xml, is following.
<servlet>
<servlet-name>servletZ</servlet-name>
<servlet-class>Conn5Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletZ</servlet-name>
<url-pattern>/servlet/example3</url-pattern>
</servlet-mapping>
8. RMS - Record Management Systems
MIDP provides a mechanism for midlets to persistently store data and later retrieve it. This persistent storage mechanism, called the Record Management System (RMS), is modeled after a simple record-oriented datastorage.
The classes and interfaces of the RMS are in the javax.microedition.rms package. The most important class is RecordStore, which represents a record store. It's most important methods are:
- openRecordStore(), opens (and possibly create) a record store
- deleteRecordStore(), deletes a named record store
- addRecord(), adds a new record to the record store
- getRecord(), returns the data stored in the given record
Example.
The following Storage1
midlet creates a DB1 named record store. A user
can enter some text and save it with Save
command. The user can also retrieve the saved record by using Retrieve
command.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
public class Storage1 extends MIDlet implements CommandListener
{
private Display display;
private TextBox text;
private Command cmSave;
private Command cmRetrieve;
private Command cmExit;
private int n = 1;
private RecordStore rs;
public Storage1()
{
display = Display.getDisplay(this);
cmSave = new Command("Save", Command.SCREEN, 1);
cmRetrieve = new Command("Retrieve", Command.SCREEN, 1);
cmExit = new Command("Exit", Command.EXIT, 1);
text = new TextBox("Text", "", 44, TextField.ANY);
text.addCommand(cmExit);
text.addCommand(cmSave);
text.addCommand(cmRetrieve);
}
public void startApp()
{
text.setCommandListener(this);
display.setCurrent(text);
try{
rs = RecordStore.openRecordStore("DB1", true);
}catch(Exception e){
System.err.println("** Error: openRecordStore(): " + e.getMessage());
}
}
public void pauseApp()
{ }
public void destroyApp(boolean unconditional)
{ }
public void commandAction(Command c, Displayable s)
{
if (c == cmSave)
{
try{
String str = text.getString();
byte[] record = str.getBytes();
rs.addRecord(record, 0, str.length());
}catch(Exception e){
System.err.println("** Error: addRecord(): " + e.getMessage());
}
}
else if (c == cmRetrieve)
{
try{
byte[] data;
data = rs.getRecord(n);
String record = new String(data);
text.setString(record);
n++;
}catch(Exception e){
System.err.println("** Error: getRecord(): " + e.getMessage());
}
}
else if (c == cmExit)
{
try{
rs.closeRecordStore();
}catch(Exception e){
System.err.println("** Error: closeRecordStore(): " + e.getMessage());
}
destroyApp(false);
notifyDestroyed();
}
}
}
Example.
The following Storage2
midlet use the record store created in the previous example. The midlet has a Retrieve
command, which fetches records from the record store sequentially. The Exit
command deletes the record store.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
public class Storage2 extends MIDlet implements CommandListener
{
private Display display;
private TextBox text;
private Command cmSave;
private Command cmRetrieve;
private Command cmExit;
private int n = 1;
private RecordStore rs;
public Storage2()
{
display = Display.getDisplay(this);
cmSave = new Command("Save", Command.SCREEN, 1);
cmRetrieve = new Command("Retrieve", Command.SCREEN, 1);
cmExit = new Command("Exit", Command.EXIT, 1);
text = new TextBox("Text", "", 44, TextField.ANY);
text.addCommand(cmExit);
text.addCommand(cmRetrieve);
}
public void startApp()
{
text.setCommandListener(this);
display.setCurrent(text);
try{
rs = RecordStore.openRecordStore("DB1", false);
}catch(Exception e){
System.err.println("** Error: openRecordStore(): " + e.getMessage());
}
}
public void pauseApp()
{ }
public void destroyApp(boolean unconditional)
{ }
public void commandAction(Command c, Displayable s)
{
if (c == cmRetrieve)
{
try{
byte[] data;
data = rs.getRecord(n);
String record = new String(data);
text.setString(n + ". " + record);
n++;
}catch(InvalidRecordIDException e){
text.setString("** no record **");
}catch(Exception e){
System.err.println("** Error: getRecord(): " + e.getMessage());
}
}
else if (c == cmExit)
{
try{
rs.closeRecordStore();
RecordStore.deleteRecordStore("DB1");
}catch(Exception e){
System.err.println("** Error: deleteRecordStore(): " + e.getMessage());
}
destroyApp(false);
notifyDestroyed();
}
}
}
original source: http://myy.haaga-helia.fi/~atk57f/
