Java ME User Interfaces


You should read this in conjunction with the introductory Java ME notes from EWT, here. In EWT, you have already seen how to get a Java ME application up and running and how to add commands to your application and respond to those commands.

General operation of a Java ME application

Java ME applications typically consist of several screens, which you navigate between through the use of commands (which you've already met in EWT). For instance:

A typical Java ME application will include a commandAction() method which reacts differently depending on the type of Command the user selected and the current item displayed on the screen. For instance, in the login application from EWT, the OK command brings up the password text box if the currently-displayed item is the username box, but it validates the username and password if the currently-displayed item is the password box.

Lists

The most important user interface element in a Java ME application is probably the list. A list represents a selectable choice of items: essentially, a menu. So how do you create a list in Java ME?

Reacting to events from the list

We need to add code to react to the list in our commandAction method. Remember the form of the commandAction method:

public void commandAction(Command c,Displayable s)
The first parameter, Command c represents the Command which generated this event. This would normally be one of our Command objects such as our ok or quit commands. However when a List item is selected, the Command sent is an inbuilt Command called List.SELECT_COMMAND. So to test for the list item being selected, you would use code such as this:
public void commandAction(Command c, Displayable s)
{
    if (c==List.SELECT_COMMAND)
    {
        // act upon a list item being selected 
    }
    else if (c.getCommandType()==Command.OK)
    {
        // act upon OK being selected
    }
    else if (c.getCommandType()==Command.EXIT)
    {
        // act upon Exit being selected
    }
}

Retrieving the selected item from the list

Retrieving the item the user selected from the list is easy. All you need to do is call getSelectedIndex on the List object that produced the command. Here is a code example:

public void commandAction(Command c, Displayable s)
{
    if(c==List.SELECT_COMMAND)
    {
        // Get the List which produced the Command
        List list = (List)s;
        System.out.println("You selected list option number : " + 
                                list.getSelectedIndex());
    }
}
Note how we have to cast the Displayable s to List to be able to treat it as a List.

Forms

Often we want to collect several user interface items on one screen. We do this with a Form. a Form is a Displayable (i.e. an object capable of occupying the main display of the screen) which can hold other objects.

A typical object that you might want to add to a Form is a TextField. A TextField is similar to a TextBox, but it does not occupy the whole screen, but just one line on a Form: it is equivalent to a JTextField in Swing or an ordinary input box in HTML. Here is an example of an application which creates two TextFields and adds them to a Form. The commands are attached to the Form (commands are always attached to Displayables, i.e. objects that occupy the whole screen) and the commandAction() method reads and validates the username and password entered in the two TextFields.

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

public class Project4 extends MIDlet implements CommandListener
{


    Form form;
    TextField username, password;

    // Stage 2 - add two Commands
    Command ok, exit;

    // Constructor for the class
    public Project4()
    {
        username = new TextField("Username","",50,TextField.ANY);
        password = new TextField("Password","",50,TextField.PASSWORD);
        

        // Create a form: "Login" is its title
        form = new Form("Login");
        form.append(username);
        form.append(password);

        exit = new Command("Exit",Command.EXIT,1);
        ok = new Command("Enter",Command.OK,1);
        
        // Associate the commands with the form, i.e. make the form 
        //respond to commands
        form.addCommand(ok);
        form.addCommand(exit);
    }

    // These are abstract so have to be overridden

    public void startApp()
    {
        Display display = Display.getDisplay(this);
        display.setCurrent(form);

        form.setCommandListener(this);
    }
    

    // Midlets must have this even if blank - code to handle pausing the a
    // application
    public void pauseApp()
    {
        
    }
    
    
    // Likewise midlets must have this even if blank - code to handle 
    // destroying the application
    public void destroyApp(boolean unconditional)
    {
    }    

    // Stage 2 - commandAction is the code to respond to commands
    public void commandAction(Command c, Displayable s)
    {
        // What command type is it?
        switch(c.getCommandType())
        {
            // if an exit command, quit the app
            case Command.EXIT: notifyDestroyed(); break;

            // if an OK command....
            case Command.OK: 
                String msg;
                if(s == form)
                {
                    if(username.getString().equals("michelle") &&
                       password.getString().equals("wtk123"))
                    {
                        msg="Correct!";
                    }
                    else
                    {
                        msg="Incorrect!";
                    }
                    Alert a = new Alert(msg,msg,null,AlertType.INFO);
                    Display.getDisplay(this).setCurrent(a);
                }
                break;
        }
    }
}

Note how the commandAction reads in what the user entered in the two text fields and validates the correct username and password.

Radio buttons

Another useful user interface element is the set of radio buttons, i.e. a group of selectable options where you can only select one of the set of options. There are actually two ways in which you can create radio buttons in Java ME:

Here is an example of radio buttons as a ChoiceGroup. The user has to select their favourite programming language. Note how we create an array of Strings, representing the individual choices, and pass them into the ChoiceGroup in the constructor. Note also how we use getSelectedIndex() once again to get the index of the radio button that the user selected, and then use the index to look up the corresponding language in the array of languages to work out which language the user selected.

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

public class Project4 extends MIDlet implements CommandListener
{


    Form form;
    TextField username, password;
    ChoiceGroup choices;
    String[] languages =  { "Java", "PHP", "C++" }; 

    // Stage 2 - add two Commands
    Command ok, exit;

    // Constructor for the class
    public Project4()
    {
        form = new Form("Favourite programming language");

        choices=new ChoiceGroup("Favourite programming language?",
            Choice.EXCLUSIVE,languages,null);        
        form.append(choices);

        /* Project4: Set up two commands. The first parameter will be the text 
        of the command, the second
        will be the command type. */
        exit = new Command("Exit",Command.EXIT,1);
        ok = new Command("Enter",Command.OK,2);
        
        // Associate the commands with the textbox, i.e. make the textbox 
        //respond to commands
        form.addCommand(ok);
        form.addCommand(exit);
    }

    public void startApp()
    {
        Display display = Display.getDisplay(this);
        display.setCurrent(form);

        form.setCommandListener(this);
    }
    

    // Midlets must have this even if blank - code to handle pausing the a
    // application
    public void pauseApp()
    {
        
    }
    
    
    // Likewise midlets must have this even if blank - code to handle 
    // destroying the application
    public void destroyApp(boolean unconditional)
    {
    }    

    // Stage 2 - commandAction is the code to respond to commands
    public void commandAction(Command c, Displayable s)
    {
        // What command type is it?
        switch(c.getCommandType())
        {
            // if an exit command, quit the app
            case Command.EXIT: notifyDestroyed(); break;

            // if an OK command....
            case Command.OK: 
                String msg;
                if(s == form)
                {
                    msg="Your favourite language is " +
                            languages[choices.getSelectedIndex()];
                    Alert a = new Alert("Favourite language",
                            msg,null,AlertType.INFO);
                    Display.getDisplay(this).setCurrent(a);
                }
                break;
        }
    }
}

Checkboxes

Checkboxes differ from radio buttons in that a user can select more than one at a time. To create a group of checkboxes, you again create a ChoiceGroup but specify Choice.MULTIPLE rather than Choice.EXCLUSIVE. You can then query the set of checkboxes by using the getSelectedFlags() method of ChoiceGroup. This takes an array of booleans as a parameter and fills it in with the current state of the ChoiceGroup. For instance if a user selects checkbox 1 and checkbox 3 out of a set of four checkboxes (0 to 3), the array will contain the values false, true, false, true. For example:

// Create an array of booleans of sufficient capacity to hold all the
// values; the size() method of a ChoiceGroup gives the number of
// elements
boolean[] isSelected = new boolean[checkboxes.size()];

// Fill the array with true/false values for each checkbox
checkboxes.getSelectedFlags(isSelected);

// isSelected[0] will be true if the first checkbox was selected, isSelected[1]
// will be true if the second was selected, etc.

Summary of Java ME user interface elements

The Canvas

A final user interface element is the Canvas. A Canvas is an element which you can draw on; it inherits from Displayable and therefore can act as a user interface element which occupies the whole screen, and can have Commands attached to it. Canvas is an abstract class with an abstract paint() method, meaning that you must subclass Canvas and provide your own paint method. The paint() method works similarly to the AWT paint() method; it takes a parameter of type Graphics which you use to actually do the drawing. Here is an example which fills the canvas with cyan and draws red text:

public class MyCanvas extends Canvas
{
    public void paint (Graphics g)
    {
        // Set the colour to cyan (hex code 0x00ffff)
        g.setColor(0x00ffff);

        // Fill a rectangle covering the whole screen
        g.fillRect(0,0,getWidth(),getHeight());

        // Set the colour to red (hex code 0xff0000)
        g.setColor(0xff0000);

        // Get a font (system font, plain rather than bold/italic, and 
        // medium size) 
        Font f = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_PLAIN,    
                Font.SIZE_MEDIUM);

        // Set the font of the graphics to the font just specified
        g.setFont(f);

        // draw some text
        g.drawString("Hello!", 10, 10, Graphics.TOP | Graphics.LEFT);
    }
}

Most of this should be self-explanatory. The main points:

Using an anonymous class for your Canvas

Rather than having to provide a named subclass of Canvas, you can simply create a single-instance anonymous class with an overridden paint() method. For example:

canvas = new Canvas()
{
    public void paint (Graphics g)
    {
        // Set the colour to cyan (hex code 0x00ffff)
        g.setColor(0x00ffff);

        // Fill a rectangle covering the whole screen
        g.fillRect(0,0,getWidth(),getHeight());

        // Set the colour to red (hex code 0xff0000)
        g.setColor(0xff0000);

        // Get a font (system font, plain rather than bold/italic, and 
        // medium size) 
        Font f = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_PLAIN,    
                Font.SIZE_MEDIUM);

        // Set the font of the graphics to the font just specified
        g.setFont(f);

        // draw some text
        g.drawString("Hello!", 10, 10, Graphics.TOP | Graphics.LEFT);
    }
};

Exercises

Make sure you complete the EWT exercises, here first!

  1. Create a List with three options, Red, Green and Blue. Make the List the main Displayable element on the screen. Write an application which displays the list option that the user selected in an Alert as soon as they select one of the three options. Hint: store the values "Red", "Green" and "Blue" in an array.
  2. Extend your previous answer so that it displays a Canvas filled in with the user's selected colour as soon as they select one of the three options. Hint: store the hex codes 0xff0000 (red), 0x00ff00 (green) and 0x0000ff (blue) in an array.
  3. Add a Back command to the Canvas (a Command of type Command.BACK). If the user selects Back while the Canvas is displayed, it should take them back to the List.
  4. Create a new application which acts similarly to the previous example but uses a Form instead: Once the user selects OK, a Canvas should be displayed, containing the user's chosen text at position (10,10), in a medium sized font, and with the user's chosen background and foreground colours.
  5. Write a pizza ordering application. Create a form with two fields, one for name and one for address, and a set of radio buttons to allow the user to choose the pizza flavour. The pizza flavours should be as follows:
    Flavour Price
    Cheese and Tomato 4.99
    Pepperoni 5.99
    Seafood 6.99
    When the user selects OK, display the user's name and address and the price of the pizza they ordered in an Alert. Hint: store the pizza prices in an array.
  6. Add a set of checkboxes to allow the user to optionally select garlic bread, coke or both. The price of garlic bread is 1.50; the price of coke is 1.00. Work out which the user selected (either or both) and add the price of the extras to the price of the pizza.