October 20, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

MIDP Programming with J2ME

  • December 26, 2002
  • By Sams Publishing
  • Send Email »
  • More Articles »

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.

Figure 3.7 The new CurrencyList.

The TextBox Class

Beneath Alert, List, and Form, there is only one further subclass of Screen: the TextBox. The TextBox allows the user to enter multi-line text on a separate screen. The constructor parameters and the constraint constants are identical to those of TextField.

As for the currency list, you can also add a new screen enabling the user to enter a transfer reason if desired. Similar to the CurrencyList, you implement a new class handling the commands related to the new screen. However, this time it is derived from the TextBox. Again, you implement the CommandListener interface:

public class TransferReason extends TextBox implements CommandListener {

In the TextBox, you provide two commands, okCommand for applying the entered text and clearCommand for clearing the text:

static final Command okCommand = new Command ("OK", Command.BACK, 1);
static final Command clearCommand = new Command ("Clear", Command.SCREEN, 2);

Again, you store a reference back to the TeleTransfer MIDlet in the TransferReason TextBox:

TeleTransfer teleTransfer;

The constructor gets the reference back to TeleTransfer MIDlet and stores it in the variable declared previously. You also add the commands to the TextBox, and register it as CommandListener:

public TransferReason (TeleTransfer teleTransfer) {
  super ("Transfer Reason", "", 50, TextField.ANY);
  this.teleTransfer = teleTransfer;

  addCommand (okCommand);
  addCommand (clearCommand);
  setCommandListener (this);
}

Your commandAction() implementation clears the text or returns to the main screen, depending on the Command selected:

  public void commandAction (Command c, Displayable d) {
    if (c == clearCommand) {
      setString ("");
    }
    else if (c == okCommand) {
      teleTransfer.back ();
    }
  }
}

Figure 3.8 shows the TransferReason TextBox.

Figure 3.8 The TransferReason TextBox showing a sample transfer reason text.

TeleTransfer with Multiple Screens

Now you have created two additional screens, but you still need to integrate them in your main application. To do so, you need to change the TeleTransfer implementation somewhat. Since the TeleTransfer's ChoiceGroup for selecting the currency is replaced by the CurrencyList, you do not need the ItemStateListener for detecting item changes any more. So you remove the listener and also the corresponding callback method itemStateChanged(). To display the two new Screens CurrencyList and TransferReason, you implement the two commands currencyCommand and reasonCommand. The new commands are added to the MIDlet in the constructor using the addCommand() method. In the clear() method, the new TextBox is also cleared by calling the corresponding setString() method. Finally you add the back() method to the TeleTransfer application; this method is called from the new Screens to return to the main form. The commandAction() method is extended to handle the new commands, displaying the new Screens. Listing 3.1 shows the complete source code of the final version of the TeleTransfer application.

Listing 3.1 TeleTransfer.java—The Complete TeleTransfer Sample Source Code

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

class CurrencyList extends List implements CommandListener {
  
  TeleTransfer teleTransfer;
  static final String [] CURRENCY_NAMES = {"Dollar", "Euro", "Yen"};
  static final String [] CURRENCY_FRACTIONS = {"Cent", "Cent", "Sen"};

  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);
  }

  
  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 ();
    }
  }
}


class TransferReason extends TextBox implements CommandListener {
  
  static final Command okCommand = new Command ("OK", Command.BACK, 1);
  static final Command clearCommand = new Command 
    ("Clear", Command.SCREEN, 2);

  TeleTransfer teleTransfer;
 
  public TransferReason (TeleTransfer teleTransfer) {
    super ("Transfer Reason", "", 50, TextField.ANY);
    this.teleTransfer = teleTransfer;

    addCommand (okCommand);
    addCommand (clearCommand);
    setCommandListener (this);
  }

  public void commandAction (Command c, Displayable d) {
    if (c == clearCommand) {
      setString ("");
    }
    else if (c == okCommand) {
      teleTransfer.back ();
    }
  }
}

public class TeleTransfer extends MIDlet implements CommandListener {

  static final Command sendCommand = new Command ("Send", Command.SCREEN, 2);  
  static final Command clearCommand = new Command 
    ("Clear", Command.SCREEN, 2);
  static final Command exitCommand = new Command ("Exit", Command.SCREEN, 1);
  static final Command currencyCommand = new Command 
    ("Currency", Command.SCREEN, 2);
  static final Command reasonCommand = new Command 
    ("Reason", Command.SCREEN, 2);

  Form mainForm = new Form ("TeleTransfer");

  TextField receiverName = new TextField 
    ("Receiver Name", "", 20, TextField.ANY); 
  TextField receiverAccount = new TextField 
    ("Receiver Account#", "", 8, TextField.NUMERIC);
  TextField amountWhole = new TextField ("Dollar", "", 6, TextField.NUMERIC);
  TextField amountFraction = new TextField 
                    ("Cent", "", 2, TextField.NUMERIC);

  CurrencyList currencyList = new CurrencyList (this);
  TransferReason transferReason = new TransferReason (this);
  Display display;
  
  public TeleTransfer () {
    mainForm.append (receiverName);
    mainForm.append (receiverAccount);
    mainForm.append (amountWhole);
    mainForm.append (amountFraction); 

    mainForm.addCommand (currencyCommand);
    mainForm.addCommand (reasonCommand);
    mainForm.addCommand (sendCommand);
    mainForm.addCommand (exitCommand);
    mainForm.setCommandListener (this);
  }

  public void startApp () {
    display = Display.getDisplay (this);
    display.setCurrent (mainForm);
  }
  
  public void clear () {
    receiverName.setString ("");
    receiverAccount.setString ("");
    amountWhole.setString ("");
    amountFraction.setString ("");
    transferReason.setString ("");
  }
   
  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 ();
  }
  
  public void pauseApp () {
  }
  
  public void destroyApp (boolean unconditional) {
  }

  public void back () {
    display.setCurrent (mainForm);
  }

  public void commandAction (Command c, Displayable d) {
    if (c == exitCommand) {
      notifyDestroyed();
    }
    else if (c == sendCommand) {
      sendTransferInformation ();
    }
    else if (c == clearCommand) {
      resetTransferInformation ();
    }
    else if (c == currencyCommand) {
      display.setCurrent (currencyList);
    }
    else if (c == reasonCommand) {
      display.setCurrent (transferReason);
    }
  }
}




Page 4 of 8



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel