YOU ARE HERE: Home > Tech > Java J2ME > Article

MIDP Programming (Part I)
By SAMS This article was not rated yet.
 
Printer Version Printer Friendly | Add As Favorite | Link to Article (Page 1 of 2)|1||2|Next

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.


    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 immediately?the 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."

    The MIDP GUI classes

    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.

    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.

    The TeleTransfer MIDlet extended to enable the user to choose a currency.

    Receiving Changes from Interactive UI Items

    If you run the new version of the TeleTransfer MIDlet, you can change the currency using the ChoiceGroup, but the TextField labels for Dollar and Cent are not changed accordingly. You need a way to notify the application if a selection is made in the currency ChoiceGroup.

    Receiving changes of interactive high-level UI items in MIDP is based on a listener model similar to AWT. Classes implementing the ItemStateListener interface are able to receive notifications for the following events:

  • State changes of a ChoiceGroup
  • Value adjustments of an interactive Gauge
  • TextField value changes
  • DateField changes


    The events are sent to the method itemStateChanged() of the ItemStateListener, where the item that has changed is given as a parameter. In order to actually receive these events, the ItemStateChangeListener must be registered using the setItemStateListener() method of the corresponding Form.

    Now that you know about item state change events, you can add the desired functionality to your TeleTransfer MIDlet. First, you need to add the ItemStateListener interface to the class declaration:


    ??public class TeleTransfer extends MIDlet implements ItemStateListener {

    You also need to implement a corresponding itemStateChanged() method. Since the itemStateChanged() method is called for changes of all Items in the Form, you need to check the item parameter indicating the event source first. If the source of the event is the currency ChoiceGroup, you set the labels of the amount and fraction TextFields correspondingly:

    ??public void itemStateChanged (Item item) {
    ?? if (item == currency) {
    ?? int index = currency.getSelectedIndex ();
    ?? switch (index) {
    ?? case 0: amountWhole.setLabel ("Dollar");
    ?? amountFraction.setLabel ("Cent");
    ?? break;
    ?? case 1: amountWhole.setLabel ("Euro");
    ?? amountFraction.setLabel ("Cent");
    ?? break;
    ?? case 2: amountWhole.setLabel ("Yen");
    ?? amountFraction.setLabel ("Sen");
    ?? }
    ?? }
    ?? }

    Just adding the interface and implementing the corresponding methods is not sufficient to enable the MIDlet to receive state changes. Additionally, you need to register your ItemStateListener at the Form containing the currency item. You do so by calling the setItemStateListener() method in the TeleTransfer constructor:

    ??public TeleTransfer () {
    ?? mainForm.append (senderAccount);
    ?? ...
    ?? mainForm.append (currency);
    ?? mainForm.setItemStateListener (this);
    ??}

    Figure 3.5 shows the new version of the TeleTransfer example, where the labels are changed depending on the state of the currency ChoiceGroup.

    The TeleTransfer MIDlet extended to change the labels depending on the state of the currency ChoiceGroup.

    Using Commands for User Interaction

    Now you can enter all the information required for a telegraphic transfer, but you have no means to initiate the actual transfer.

    In contrast to desktop computers, which have plenty of screen space for displaying buttons or menus, a different approach is necessary for mobile devices. Some devices provide so-called soft buttons, which are buttons without fixed functionality that are assigned dynamically depending on the application context. The number of soft buttons may vary if they are available. Other mobile devices do not even have space for soft buttons, but provide scrolling menus. MIDP needs to abstract from the concrete device and to provide a mechanism that is suitable for all devices, independent of the availability and number of soft buttons. Thus, the lcdui package does not provide buttons or menus, but an abstraction called Command.

    Commands can be added to all classes derived from the Displayable class. These classes are Screen and its subclasses such as Form, List, and TextBox for the high-level API and Canvas for the low-level API.

    No positioning or layout information is passed to the Command?the Displayable class itself is completely responsible for arranging the visible components corresponding to Commands on a concrete device. The only layout and display information that can be assigned to a Command except from the command label is semantic information. The semantic information consists of a type and a priority. The priority allows the device to decide which commands are displayed as soft buttons if the number of commands exceeds the number of soft buttons available. For additional commands not displayed as soft buttons, a separate menu is created automatically. The type information is an additional hint for the device about how to display the command. For example, if the Exit command is always assigned to the leftmost soft button in native applications of a certain device type, the MIDP implementation is able to make the same assignment. Thus, a consistent look and feel can be accomplished for a device.

    The available command type constants are listed in Table 3.5.






































    Constant Value
    Command.BACK Used for navigation commands that are used to return the user to the previous
    Screen.
    Command.CANCEL Needed to notify the screen that a negative answer occurred.
    Command.EXIT Used to specify a Command for exiting the application.
    Command.HELP Passed when the application requests a help screen.
    Command.ITEM A command type to tell the application that it is appended to an explicit
    item on the screen.
    Command.OK Needed to notify the screen that a positive answer occurred.
    Command.SCREEN A type that specifies a screen-specific Command of the application.
    Command.STOP Interrupts a procedure that is currently running.

    The Command constructor takes the label, the command type and the priority as input. The Command class provides read() methods for all these fields, but it is not possible to change the parameters after creation. Using the addCommand() method, commands can be added to a Form or any other subclass of Displayable.

    As in the case of receiving state changes of UI widgets, the MIDP uses a listener model for detecting command actions. For this purpose, the lcdui package contains the interface CommandListener. A CommandListener can be registered to any Displayable class using the setCommandListener method. After registration, the method commandAction() of the Commandlistener is invoked whenever the user issues a Command. In contrast to AWT, only one listener is allowed for each Displayable class. The commandAction() callback method provides the Displayable class where the command was issued and the corresponding Command object as parameters.

    With this information, you can extend your TeleTransfer application with the desired Commands. But before going into actual command implementation, you need to add some corresponding functionality. You'll add three commands: a Send command, a Clear command, and an Exit command. For Clear, you just add a method setting the content of the fields of your form to empty strings:


    ??public void clear () {
    ??receiverName.setString ("");
    ??receiverAccount.setString ("");
    ??amountWhole.setString ("");
    ??amountFraction.setString ("");
    ??}

    The Send command is a bit more difficult since you do not yet have the background to really submit information over the network. (Network connections will be handled in Chapter 6, "Networking: The Generic Connection Framework.") So you just display the content to be transmitted in an alert screen as a temporary replacement:

    ??public void send () {
    ?? Alert alert = new Alert ("Send");
    ?? alert.setString ("transfer " + amountWhole.getString ()
    ?? + "." + amountFraction.getString () + " "
    ?? + amountWhole.getLabel ()
    ?? + "\nto Acc#" + receiverAccount.getString ()
    ?? + "\nof " + receiverName.getString ());
    ?? alert.setTimeout (2000);
    ?? display.setCurrent (alert);
    ?? clear ();
    ??}

    For leaving the application, the MIDlet already provides the notifyDestroyed() method, so you do not need to add anything here.

    Now that you have implemented the corresponding functionality, the next step is to add the actual Command objects to your application class:


    ??static final Command sendCommand =
    ????new Command ("Send", Command.SCREEN, 1);
    ??static final Command clearCommand =
    ????new Command ("Clear", Command.SCREEN, 2);
    ??static final Command exitCommand =
    ????new Command ("Exit", Command.EXIT, 2);

    In order to enable the MIDlet to receive command actions, you need to implement the CommandListener interface, and the corresponding commandAction() method. Depending on the command received, you call send(), clear(), or notifyDestroyed():

    ??public class TeleTransfer extends MIDlet
    ?? implements ItemStateListener, CommandListener {

    ??public void commandAction (Command c, Displayable d) {
    ?? if (c == exitCommand) {
    ?? notifyDestroyed();
    ?? }
    ?? else if (c == sendCommand) {
    ?? send ();
    ?? }
    ?? else if (c == clearCommand) {
    ?? clear ();
    ?? }
    ??}


    With these modifications, your TeleTransfer MIDlet is able to handle the desired commands. You still need to add the Commands to the Form, and register the TeleTransfer MIDlet as a CommandListener in order to actually receive the commands:

    ??public TeleTransfer () {
    ?? ...
    ?? mainForm.addCommand (sendCommand);
    ?? mainForm.addCommand (clearCommand);
    ?? mainForm.addCommand (exitCommand);
    ?? mainForm.setCommandListener (this);
    ??}

    Figure 3.6 shows the Send Alert of the new version of your TeleTransfer application.

    The TeleTransfer MIDlet showing an alert that displays the transfer information as a summary before sending.

    Further Item Classes: Gauge and DateField

    Now you have used all the Item subclasses except Gauge and DateField. Both classes are specialized input elements, where the Gauge may also make sense as a pure read-only information item.

    The Gauge item visualizes an integer value by displaying a horizontal bar. It is initialized with a label, a flag indicating whether it is interactive, and a maximum and an initial value. If a Gauge is interactive, the user is allowed to change the value using a device-dependent input method. Changes to the gauge value will cause ItemEvents if a corresponding listener is registered to the form.

    The following code snippet shows the construction of a non-interactive Gauge labeled Progress that is initialized with a value of 0 and a maximum of 100:


    ??Gauge gauge = new Gauge ("Progress", false, 0, 100);

    If a Gauge is used to display progress of a process that takes a longer amount of time, you should also add a corresponding Stop command to the form to abort the progress.

    The current value of the Gauge can be set using the method setValue() and read using the method getValue(). Analogous setMaxValue() and getMaxValue() methods let you access the maximum value of the Gauge.

    The DateField is a specialized widget for entering date and time information in a simple way. It can be used to enter a date, a time, or both types of information at once. The appearance of the DateField is specified using three possible input mode constants in the constructor. Possible DateField mode constants are listed in Table 3.6.

    Table 3.6 DateField Mode Constants

















    Constant Value
    DATE Passed if the DateField should be used for entering a date
    only.
    DATE_TIME Used for creating a DateField to enter both date and time
    information.
    TIME Used to enter time information only.

    The DateField has two constructors in which a label and the mode can be specified. Using the second constructor, an additional TimeZone can be passed. The following code snippet shows how a DateField for entering the date of birth can be initialized:


    ??DateField dateOfBirth = new DateField("Date of birth:",
    ????DateField.DATE);

    After you enter the date into the DateField, it can be accessed using the getDate() method. The DateField offers some additional methods for getting information about the input mode and methods for setting the date and the input mode as well. The concrete usage of the DateField is shown in Chapter 9 in the Blood Sugar Logger application.

    Further Screen Classes: List and TextBox
    The current version of the TeleTransfer MIDlet shows how to use the Form and the corresponding items available in the lcdui package. The application consists of one main form that holds all application widgets. However, your main form is rather long now, so the question arises how to improve the usability of the application. This section shows how to structure the user interface by using multiple screens and introduces the List and TextBox classes.

    The List Class

    One possibility to clean up the user interface is to move the currency selection to a separate screen. It takes a lot of space and may need even more room if additional options are added. Also, you can assume that the currency is not changed very often.

    You could create a new Form and just move the ChoiceGroup there. However, lcdui provides a special List class inherited from Screen for this purpose. The advantage of the List class is that it provides the IMPLICIT mode that was already mentioned in the section "Selecting Elements Using ChoiceGroups." Using the IMPLICIT mode, the application gets immediate notification when an item is selected. Whenever an element in the List is selected, a Command of the type List.SELECT_COMMAND is issued. As in the ChoiceGroup, the elements consist of Strings and optional Images.

    For initializing the List, the lcdui packages offers constructors. The constructors work like the ChoiceGroup constructors. The first one creates an empty List with a given title and type only. The second one takes the title, the type, an array of Strings as initial amount of List elements, and an optional array of Images for each List element. In the implementation of the TeleTransfer application, you implement a new class CurrencyList extending List that will be used as your new currency selector. Since you will use the IMPLICIT mode, you need to implement a command listener, so you can already add the corresponding declaration:


    ??public class CurrencyList extends List implements CommandListener {

    To set the labels of the main form TextFields according to the index of the selected element in the CurrencyList, you create two String arrays, CURRENCY_NAMES and CURRENCY_FRACTIONS:

    ??static final String [] CURRENCY_NAMES = {"Dollar", "Euro", "Yen"};
    ??static final String [] CURRENCY_FRACTIONS = {"Cent", "Cent", "Sen"};

    In order to set the labels of the main forms TextFields for the whole and the fractional amount according to the selected currency in the CurrencyList, you need a reference back to the main TeleTransfer MIDlet. For this reason, you store the TeleTransfer reference in a variable called teleTransfer. The reference is set in the constructor of your CurrencyList:

    TeleTransfer teleTransfer;

    In the constructor, you also add currency symbol images to the list. You need to load them, but the call to the super constructor must be the first statement in a constructor. So you call the constructor of the super class by specifying the title and type only. Then you create the Images needed for each list element, which are stored in the MIDlet suite's JAR file. You also call setCommandListener() to register the currency list for handling commands that are issued:


    ??public CurrencyList (TeleTransfer teletransfer) {
    ?? super ("Select Currency", Choice.IMPLICIT);

    ?? this.teleTransfer = teletransfer;

    ?? try {
    ?? append ("USD", Image.createImage ("/Dollar.png"));
    ?? append ("EUR", Image.createImage ("/Euro.png"));
    ?? append ("JPY", Image.createImage ("/Yen.png"));
    ?? }
    ?? catch (java.io.IOException x) {
    ?? throw new RuntimeException ("Images not found");
    ?? }
    ?? setCommandListener (this);
    ??}


    The final step in creating the CurrencyList is to implement the commandAction() method of the CommandListener interface. As you already know, a List of IMPLICIT type issues a List.SELECT_COMMAND to the registered CommandListener whenever a new element is selected to indicate the selection change. In case of a selection change, you modify the labels of the main form TextFields. The actual labels are obtained from the String arrays CURRENCY_NAMES and CURRENCY_FRACTIONS. Using the teleTransfer reference, you can access the TextFields. Finally, you call the new method teleTransfer.back(), which sets the screen back to the main form (the back() method will be given at the end of this section):

     
    ??public void commandAction (Command c, Displayable d) {
    ?? if (c == List.SELECT_COMMAND) {
    ?? teleTransfer.amountWhole.setLabel
    ?? (CURRENCY_NAMES [getSelectedIndex ()]);
    ?? teleTransfer.amountFraction.setLabel
    ?? (CURRENCY_FRACTIONS [getSelectedIndex ()]);
    ?? teleTransfer.back ();
    ?? }
    ?? }
    ??}

    Figure 3.7 shows currency Images and abbreviations in the CurrencyList.

    The new CurrencyList

    The TextBox Class 

    Continue...

  • (Page 1 of 2)  |1||2|Next

    Was this article helpful to you?yesno

    Related Publications
     
    MIDP Programming (Part II)
    MIDP Programming (Part I)

    (Registered users can post questions/comments)

     
     TLINKS SEARCH
    Advanced Search
    Help
     Recommended Links
    Red Cross
    Responding to hurricane katrina relieve. Donate today. It's a Great Feeling to Help.
    http://www.redcross.org
    Getusjobs.com
    Getusjobs.com is the job site focused on American jobs. See the results that put us on top.
    http://www.getusjobs.com
    Database Tool
    TLinkSoft® tools empowers developers, integrators and DBAs to be more productive.
    http://www.cppunit.org/download.jsp
    USAnalyst.com
    USAnalyst.com provide a community for database analysts, business analysts, developer analysts and managers.
    http://www.cppunit.org/article

    Powered by Tlinks Systems