C H A P T E R  4

Creating a MIDlet and MIDlet Suite

This section of the tutorial shows you how to create a currency converter application using the tools available to you through the Java Studio Mobility IDE. The chapter takes you through the tasks necessary to build the J2ME, MIDP/CLDC application, Currency Converter. The sections in this chapter are:

As you go through the tutorial, keep in mind that the Java Studio Mobility often has more than one way to perform a particular function. The tutorial illustrates one way to perform a function, but there are often other ways to accomplish the same function. For example, functions from the drop-down menus can usually be accessed by right-clicking on an entity and then selecting from its contextual menu. As you grow more familiar with the tool, you will find the operational mode with which you are most comfortable.


Initial Setup

Before you create the Currency Converter MIDlet, you need to select a directory (filesystem) on your system, and mount it into the IDE. (Mounting is explained in Mounting a Filesystem.) Then you'll create a package, myconverter, to contain the Currency Converter files.

This tutorial will use a directory in the default Java Studio Mobility user directory for a user named JavaCoder on the Windows platform:

c:\Documents and Settings\JavaCoder\jstudio_6me_user\examples.

If the examples filesystem is already mounted, you can skip to Step 4.

To mount a filesystem and create the package:

1. From the File menu of the IDE, choose Mount Filesystem.

This opens a wizard from which you choose the template for the filesystem.

2. Select the Local Directory and click Next.

3. Use the wizard to navigate to the examples directory. Select this directory and click Finish to complete the mount process.

The examples filesystem appears in the Filesystems tab of the Explorer pane.

4. Right-click on the examples filesystem, then choose Newright arrowJava Package.

This opens the New Java Package wizard.

5. Name the package myconverter. Click Finish.

A package myconverter is created inside the mounted filesystem examples.

 [ D ] 


Creating the MIDlet Suite

While you can work with individual MIDlets for developing and testing purposes, it is best to create MIDlets within a MIDlet suite. The MIDlet suite helps you to package your MIDlet application and prepare it for deployment.

MIDlet suites give you more control over your MIDP applications. A MIDlet suite organizes the source files and attribute files for a MIDP application. When you build a MIDlet suite, the tool automatically creates the necessary JAR file that contains the application files. The Java Studio Mobility IDE also creates the Java Application Descriptor file, or JAD file, that is required for deployment.

To create a MIDlet Suite:

1. In the Filesystems window, right-click the myconverter package. Choose New right arrow MIDlet Suite from the contextual menu.

The MIDlet Suite wizard takes you through the steps to create a MIDlet suite.

2. In the MIDlet Suite wizard, type the name for the new MIDlet suite. Then click Next.

Name the new MIDlet suite converter.

3. In the Add MIDlet page, do the following to create a new MIDlet within the suite:

a. Select the Create New MIDlet option.

b. Enter ConverterMIDlet as the Package and Class Name.

Notice that you need to capitalize the "C" in the name.

c. To select a MIDlet Template, click the arrow in the dropdown list and choose MIDlet.

d. Click Next.

4. In the MIDlet Properties page, change the MIDlet Displayable Name to Currency Converter. Click Finish.

The displayable name is the name a mobile device user will see when using the application on a mobile device.

The code for the MIDlet is displayed in the Source Editor window. Notice that the ConverterMIDlet icon in the Explorer tab has a set of small red x's and 0's next to it. This badge signifies that the MIDlet needs to be compiled.

 [ D ] 

In the following steps, you will add code to complete the Currency Converter application.


Coding the MIDlet

You can write the code for a MIDlet in one of two ways: either by directly entering code in the Source Editor or by using the tool functions to add methods, fields, constructors, initializers, classes, and interfaces. Typically, you use the tool to add new fields and methods to a class, or modify existing fields and methods, and then later fine-tune the code directly in the Source Editor.

The following procedure shows you how to use the tool and the Source Editor to enter or change code. However, to save time and effort, you can also copy the converter code from the example you installed in Chapter 2.

1. In the Source Editor, add the following import statements to ConverterMIDlet:

import java.io.*;
import javax.microedition.rms.*;

2. In the Filesystem tab window, expand the converterMIDlet node, right-click the ConverterMIDlet class and choose Addright arrow Field.

This next step will use the Add New Field dialog box to add the field storedDataStr to the MIDlet. The storedDataStr string contains the name of the RMS stored record.

3. Complete the Add New Field dialog box:

a. Enter the name of the new field, storedDataStr, in the Name box and select its type, String, from the Type combo box.

b. In the Modifiers box, select the type of access for the field, private, from the Access combo box.

c. Check the other modifiers for the field, which in this case is static.

d. Set the initial value for storedDataStr to "ConverterData".

e. Click OK to close the dialog box.

The field is added to the code in the Source Editor window.

 [ D ] 

4. Add the following fields to the MIDlet code using the Source Editor.



Tip - You can use the Add Field dialog box, copy the text from this page, or from the installed Currency Converter application, and paste it in the Source Editor. Be careful, however, not to change the package name from myconverter.



public String[] currencies = new String[] { "US $", "Yen \u00a5", "Euro \u20ac" };
    public boolean[] selected = new boolean[] { true, true, true, true };
    public long[][] rates =  {{   1000000, 117580000,    911079 },
                              {      8504,   1000000,      7749 },
                              {   1097600, 129056000,   1000000 }};
    private RecordStore   storedData;

5. Add the following code to the method startApp():

 try {
            storedData = RecordStore.openRecordStore(storedDataStr, true);
            if (storedData.getNumRecords() > 0) {
                DataInputStream in = new DataInputStream(new ByteArrayInputStream(storedData.getRecord(1)));
                try {
                    int size = in.readInt();
                    currencies = new String[size];
                    selected = new boolean[size];
                    rates = new long[size][];
                    for (int i=0; i<size; i++) {
                        currencies[i] = in.readUTF();
                        selected[i] = in.readBoolean();
                        rates[i] = new long[size];
                        for (int j=0; j<size; j++) {
                            rates[i][j] = in.readLong();
                        }
                    }
                    in.close();
                } catch (IOException ioe) {
                }
            }
        } catch (RecordStoreException e) {
        }
        notifySettingsChanged();
    }

This method is called when the application is started. It loads all the data (currencies selected currencies, and exchange rates) from persistent storage and initially displays the Converter form.

6. Add the following code to complete the method destroyApp():

 try {
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            DataOutputStream out = new DataOutputStream(bytes);
            try {
                out.writeInt(currencies.length);
                for (int i=0; i<currencies.length; i++) {
                    out.writeUTF(currencies[i]);
                    out.writeBoolean(selected[i]);
                    for (int j=0; j<currencies.length; j++) {
                        out.writeLong(rates[i][j]);
                    }
                }
                out.close();
                if (storedData.getNumRecords() > 0)
                    storedData.setRecord(1, bytes.toByteArray(), 0, bytes.size());
                else
                    storedData.addRecord(bytes.toByteArray(), 0, bytes.size());
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        } catch (RecordStoreException e) {
            e.printStackTrace();
        }
        notifyDestroyed();
}

The destroyapp() method is called when the application is finished, or destroyed.

7. Add the following three new methods:

a. showSettings()

public void showSettings() {
Display.getDisplay(this).setCurrent(new CurrenciesSelector(this));}

This method creates and displays the CurrenciesSelector list.

b. notifySettingsChanged()

 public void notifySettingsChanged() {
        Display.getDisplay(this).setCurrent(new Converter(this));}

This method displays a new Converter form after the settings are changed.

c. longconvert()

public long convert(long frval, int fridx, int toidx) {
        return (frval * rates[fridx][toidx]) / 1000000;

This method performs the currency conversion. The input value, frval, is multiplied by the exchange rate stored in the rates table and divided by 1,000,000. The fridx and toidx values are the indexes of the source and target currencies.

8. Save the ConverterMIDlet by choosing Fileright arrow Save.


Creating a MIDP Form

Now that you have completed the code for the MIDlet, you will create the application's graphical interface. A Form is a Java class that can contain an arbitrary mixture of items, including images, read-only and editable text fields, editable date fields, gauges, choice groups, and custom items. The form you create here will specify a text box for each selected currency and specify the ItemStateListener() method to monitor and reflect typed values and perform conversions.

1. In the Filesystems window, right-click the myconverter package. Choose Newright arrowAll Templates.

The New Template wizard opens.

2. Expand the MIDP node and select MIDP Form. Click Next.

3. In the Object name page, Enter Converter for the class name. Click Finish.

A MIDP form template is created and added to the myconverter package.

Screenshot of the Converter form node selected in the Explorer window and the code for template displayed in the Source Editor window.  

4. In the Source Editor, add the following fields to the code below the public class Converter declaration:

private ConverterMIDlet midlet;
private int[] translate;

5. Add the following code to replace the constructor:

 public Converter(ConverterMIDlet midlet) {
        super("Currency Converter");
        this.midlet = midlet;
        this.translate = new int[midlet.currencies.length];
        int current = 0;
        for (int i=0; i<translate.length; i++) {
            if (midlet.selected[i]) {
                translate[current++] = i;
                append(new TextField(midlet.currencies[i], "", 12, TextField.NUMERIC));
            }
        }
        try {
            // Set up this form to listen to command events
            setCommandListener(this);
            // Set up this form to listen to changes in the internal state of its interactive items
            setItemStateListener(this);
            // Add the Currencies command
            addCommand(new Command("Currencies", Command.OK, 1));
            // Add the Exit command
            addCommand(new Command("Exit", Command.EXIT, 1));
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

6. Add the following code to complete the method commandAction():

 if (command.getCommandType() == Command.EXIT) {
            midlet.destroyApp(true);
        } else if (command.getCommandType() == Command.OK) {
            midlet.showSettings();
        }

7. Add the following code to complete the itemStateChanged() method:

long value = Long.parseLong(((TextField)item).getString());
        int from = 0;
        while (get(from) != item) from++;
        from = translate[from];
        for (int i=0; i<size(); i++) {
            int to = translate[i];
            if (from != to) {
                ((TextField)get(i)).setString(String.valueOf(midlet.convert(value, from, to)));
            }

This completes the Converter.java form file.


Creating a MIDP list

The final piece of the Currency Converter application is the CurrenciesSelector.java list file, which defines the currencies that can be selected for display.

To create the list file:

1. In the Filesystems window, right-click the myconverter package. Choose Newright arrowAll Templates.

The New Template wizard opens.

2. Expand the MIDP node and select MIDP List. Click Next.

3. In the New Object Name page, Enter CurrenciesSelector for the class name. Click Finish.

A MIDP list template is created and added to the currencyconverter filesystem.

Screenshot of CurrenciesSelector list node selected in the Explorer window and the code for template displayed in the Source Editor window.  

4. Declare a field:

 private ConverterMIDlet midlet;

5. Add the following code to replace the constructor
public CurrenciesSelector(ConverterMIDlet midlet):

super("Select Currencies", List.MULTIPLE, midlet.currencies, null);
        this.midlet = midlet;
        setSelectedFlags(midlet.selected);
        try {
            // Set up this list to listen to command events
            setCommandListener(this);
            // Add the Save command
            addCommand(new Command("Save", Command.OK, 1));
        } catch(Exception e) {
            e.printStackTrace();
        }

6. Add the following code to complete the commandAction method:

 if (command.getCommandType() == Command.OK) {
            getSelectedFlags(midlet.selected);
            midlet.notifySettingsChanged();
        }

7. To save the list, Select File from the main menu and choose Save.

This completes the CurrenciesSelector.java List file.


Packaging the Currency Converter Application

When you created the converter MIDlet suite, you created the essential package for the Currency Converter application. Now you should check to ensure that the two additional files you created, Converter.java and CurrenciesSelector.java have been added to the MIDlet suite. To do this, you use the Suite Editor.

To check the contents of the suite:

1. Right-click on the converter MIDlet suite and choose Edit Suite from the contextual menu.

The Suite Editor dialog opens. Notice that the Editor has several tabs: MIDlets, JAD Manifest, Push Registry, API Permissions, Signing, and Jar Contents.

 [ D ] 

2. Select the Jar Contents Tab.

The Jar contents tab displays, showing you the mounted file systems available, and the current contents of converter.jar. The current contents are marked with a check in the check box.

 [ D ] 

3. Expand the examples filesystem node.

4. Expand the myconverter folder.

Notice that the MIDlets are already selected. They were automatically added to the MIDlet Suite by the IDE.

If you left the "Include Whole Folder" option checked when you created the converter MIDlet in the New MIDlet Suite wizard (see Step 3 in Creating the MIDlet Suite), the converter example application, which also resides in the examples folder, is also included in the contents.

Screenshot of the Jar Contents tab of the Suite Editor.[ D ] 

5. Make sure the converter folder is unchecked.

6. Click OK to close the dialog.

Now the suite is ready to be compiled and executed in the same way you compiled the MIDlet in Compiling and Running the Application.

The next chapter will illustrate how to debug a MIDlet suite with the Java Studio Mobility IDE.