High-Level API
Now that you know the basics of the MIDlet's life cycle and general
display model, we can start to look deeper into the lcdui package. We
will start with another subclass of Screen: Alert. Then we
will discuss some simple Items like StringItem and
ImageItem. We will explain the use of more advanced Items such
as TextField and ChoiceGroup by creating a simple
TeleTransfer example application. As we introduce new MIDP high-level
UI capabilities like other Screen subclasses, we will extend the
TeleTransfer sample step by step.
Alerts
You already know the Form class from the first example. The simplest
subclass of Screen is Alert. Alert provides a
mechanism to show a dialog for a limited period of time. It consists of a label,
text, and an optional Image. Furthermore, it is possible to set a
period of time the Alert will be displayed before another
Screen is shown. Alternatively, an Alert can be shown until
the user confirms it. If the Alert does not fit on the screen and
scrolling is necessary to view it entire contents, the time limit is disabled
automatically.
The following code snippet creates an Alert with the title
"HelloAlert" and displays it until it is confirmed by the user:
Alert alert = new Alert ("HelloAlert");
alert.setTimeout (Alert.FOREVER);
display.setCurrent (alert);
Forms and Items
The most important subclass of Screen is the class Form. A
Form can hold any number of Items such as
StringItems, TextFields, and ChoiceGroups.
Items can be added to the Form using the append()
method.
The Item class itself is an abstract base class that cannot be
instantiated. It provides a label that is a common property of all subclasses.
The label can be set and queried using the setLabel()and
getLabel() methods, respectively. The label is optional, and a
null value indicates that the item does not have a label. However,
several widgets switch to separate screens for user interaction, where the label
is used as the title of the screen. In order to allow the user to keep track of
the program state, it is recommended that you provide a label at least for
interactive items.
Items can neither be placed freely nor can their size be set
explicitly. Unfortunately, it is not possible to implement Item
subclasses with a custom appearance. The Form handles layout and
scrolling automatically. Table 3.1 provides an overview of all Items
available in MIDP.
Table 3.1 All Subclasses of Item
|
Item
|
Description
|
|
ChoiceGroup
|
Enables the selection of elements in group.
|
|
DateField
|
Used for editing date and time information.
|
|
Gauge
|
Displays a bar graph for integer values.
|
|
ImageItem
|
Used to control the layout of an Image.
|
|
StringItem
|
Used for read-only text elements.
|
|
TextField
|
Holds a single-line input field.
|
StringItem
StringItems are simple read-only text elements that are initialized
with the label and a text String parameter only. The following code
snippet shows the creation of a simple version label. After creation, the label
is added to the main form in the constructor of the HelloMidp
application:
public HelloMidp () {
mainForm = new Form ("HelloMidp");
StringItem versionItem = new StringItem ("Version: ", "1.0");
mainForm.append (versionItem);
}
The label of the StringItem can be accessed using the
setLabel() and getLabel() methods inherited from
Item. To access the text, you can use the methods setText()
and getText().
ImageItem
Similar to the StringItem, the ImageItem is a plain
non-interactive Item. In addition to the label, the ImageItem
constructor takes an Image object, a layout parameter, and an
alternative text string that is displayed when the device is not able to display
the image. The image given to the constructor must be non-mutable. All images
loaded from the MIDlet suite's JAR file are not mutable. (Details
about adding resources to a JAR file are explained in Chapter 2, "The
Connected Limited Device Configuration.")
The difference between mutable and non-mutable Images is described
in more detail in the section about Images in the "Low Level
API" section of this chapter. For now, we will treat the Image
class as a "black box" that has a string constructor that denotes the
location of the image in the JAR file. Please note that Image
construction from a JAR file throws an IOException if the image cannot
be loaded for some reason. The layout parameter is one of the integer constants
listed in Table 3.2, where the newline constants can be combined with the
horizontal alignment constants.
Table 3.2 ImageItem Layout Constants
|
Constant
|
Value
|
|
LAYOUT_CENTER
|
The image is centered horizontally.
|
|
LAYOUT_DEFAULT
|
A device-dependent default formatting is applied to the image.
|
|
LAYOUT_LEFT
|
The image is left-aligned.
|
|
LAYOUT_NEWLINE_AFTER
|
A new line will be started after the image is drawn.
|
|
LAYOUT_NEWLINE_BEFORE
|
A new line will be started before the image is drawn.
|
|
LAYOUT_RIGHT
|
The image is aligned to the right.
|
The following code snippet shows how a center aligned
ImageItem is added to the HelloMidp sample MIDlet:
public HelloMidp () {
display = Display.getDisplay (this);
mainForm = new Form ("HelloMidp");
try {
ImageItem logo = new ImageItem
("Copyright: ", Image.createImage ("/mcp.png"),
ImageItem.LAYOUT_CENTER | ImageItem.LAYOUT_NEWLINE_BEFORE
| ImageItem.LAYOUT_NEWLINE_AFTER, "Macmillian USA");
mainForm.append (logo);
}
catch (IOException e) {
mainForm.append (new StringItem
("Copyright", "Sams Publishing; Image not available:" + e));
}
}
By forcing a new line before and after the image, you ensure that the image
is centered in its own line. Figure 3.3 shows
the corresponding display on the device. If the image cannot be loaded and an
exception is thrown, a simple StringItem is appended to the form instead
of the image.
Figure 3.3 The HelloMidp
application showing an ImageItem.
Handling Textual Input in
TextFields
As shown in Table 3.1, textual input is handled by the class
TextField. The constructor of TextField takes four values: a
label, initial text, a maximum text size, and constraints that indicate the type
of input allowed. In addition to avoiding input of illegal characters, the
constraints may also influence the keyboard mode. Several MIDP devices have a
numeric keyboard only, and the constraints allow the application manager to
switch the key assignments accordingly. The constants listed in Table 3.3,
declared in the class TextField, are valid constraint values.
Table 3.3 TextField Constraint Constant Values
|
Constant
|
Value
|
|
ANY
|
Allows any text to be added.
|
|
EMAILADDR
|
Adds a valid e-mail address, for instance myemail@mydomain.com.
|
|
NUMERIC
|
Allows integer values.
|
|
PASSWORD
|
Lets the user enter a password, where the entered text is masked.
|
|
PHONENUMBER
|
Lets the user enter a phone number.
|
|
URL
|
Allows a valid URL.
|
We will now show the usage of TextFields by creating a
simple example Form for bank transfers. A bank transfer form contains
at least the amount of money to be transferred and the name of the receiver.
To start the implementation of the TeleTransfer MIDlet, you first
need to import the two packages containing the midlet and
lcdui classes:
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
Every MID application is derived from MIDlet, so you need to extend
the MIDlet class, too:
public class TeleTransfer extends MIDlet {
Because you want to create a Form that contains Items for
entering the transfer information, you need a corresponding member variable
mainForm. You can already initialize the variable at its declaration
because it has no dependencies from constructor parameters:
Form mainForm = new Form ("TeleTransfer");
In order to let the user enter the transfer information, add
TextFields for the name of the receiver for entering the amount to be
transferred. Because of the lack of floating-point values in the CLDC, the
numeric TextFields in MIDP can hold integer values only. So you need to
split the amount into separate fields for dollars and cents. An alternative
would be to use an alphanumeric field and parse the string into two separate
values. However, this may result in switching the keyboard to alpha mode on cell
phones, making numeric input unnecessarily complicated. In this case,
you'll limit the size of possible values to five digits for the whole
dollar part and two digits for the fractional cent part. Again, you initialize
the variables where they are declared:
TextField receiverName = new TextField
("Receiver Name", "", 20, TextField.ANY);
TextField receiverAccount = new TextField
("Receiver Account#", "", 12, TextField.NUMERIC);
TextField amountWhole = new TextField ("Dollar", "", 6, TextField.NUMERIC);
TextField amountFraction = new TextField ("Cent", "", 2, TextField.NUMERIC);
Finally, you add a variable storing the Display instance for your
application:
Display display = Display.getDisplay (this);
Now you can add the constructor to your application where you added the
previous TextFields to the main form:
public TeleTransfer () {
mainForm.append (receiverName);
mainForm.append (receiverAccount);
mainForm.append (amountWhole);
mainForm.append (amountFraction);
}
When the application is started, you request the display to show your money
transfer form by calling setCurrent(). As explained in the
"MIDlets" section, the application manager notifies you about the
application start by calling the startApp() method. So you implement
this method accordingly:
public void startApp () {
display.setCurrent (mainForm);
}
Please note that startApp() is called also when the MIDlet resumes
from the paused state, so you cannot move the initialization code from the
constructor to this method.
Both pauseApp() and destroyApp() are declared as abstract
in the MIDlet class, so you need to implement these methods in your
application, even if you do not have real content for them. You just provide
empty implementations, like in the HelloMidp example in the first
section:
public void pauseApp () {
}
public void destroyApp (boolean unconditional) {
}
Selecting Elements Using ChoiceGroups
In the previous section, you created a simple Form to enter
information for transferring money between two accounts. Now you will extend the
application to allow the user to select different currencies. For this purpose,
you will now add a ChoiceGroup to your application.
The ChoiceGroup is an MIDP UI widget enabling the user to choose
between different elements in a Form. These elements consist of simple
Strings, but can display an optional image per element as well.
ChoiceGroups can be of two different types. Corresponding type
constants are defined in the Choice interface. These constants are used
in the List class as well; the List class allows an additional
third type. The three type constants are listed in Table 3.4.
Table 3.4 Choice Type Constants
|
Constant
|
Value
|
|
EXCLUSIVE
|
Specifies a ChoiceGroup or List having only one element
selected at the same time.
|
|
IMPLICIT
|
Valid for Lists only. It lets the List send
Commands to indicate state changes.
|
|
MULTIPLE
|
In contrast to EXPLICIT, MULTIPLE allows the selection of
multiple elements.
|
The ChoiceGroup constructor requires at least a label
and a type value. Additionally, a String array and an Image
array containing the elements can be passed to the constructor. Elements can
also be added dynamically using the append() method. The
append() method has two parameters, a String for the label and
an Image. In both cases, the image parameter may be null if no
images are desired.
In order to add a ChoiceGroup to the TeleTransfer
application, you introduce a new variable currency of type
ChoiceGroup. By setting the type to EXCLUSIVE, you get a
ChoiceGroup where only one item can be selected at a time. You directly
add elements for the United States (USD), the European Union (EUR), and Japan
(JPY) by passing a String array created inline. The
ChoiceGroup enables the user to choose between three currencies that
are represented textually by the abbreviations specified in the String
array. The last parameter of the constructor is set to null because you
do not want Images to be displayed at this time:
ChoiceGroup currency = new ChoiceGroup
("Currency", Choice.EXCLUSIVE,
new String[] {"USD", "EUR", "JPY"}, null);
You still need to add the currency ChoiceGroup to your main
Form. As for the text fields, this is done via the append()
method of Form:
mainForm.append (currency);
Figure 3.4 shows the TeleTransfer
application extended to choose a currency using a ChoiceGroup.
Figure 3.4 The TeleTransfer
MIDlet extended to enable the user to choose a currency.