ColdFusion MX Professional Projects

Team-Fly

In the last chapter, you learned about MIDP's simpler screen classes. Now we're getting into deeper waters, with screens that show lists and screens with mixed types of controls.

Using Lists

After TextBox and Alert, the next simplest Screen is List, which allows the user to select items (called elements) from a list of choices. A text string or an image is used to represent each element in the list. List supports the selection of a single element or of multiple elements.

There are two main types of List, denoted by constants in the Choice interface:

Understanding List Types

For both MULTIPLE and EXCLUSIVE lists, selection and confirmation are separate steps. In fact, List does not handle confirmation for these types of lists-your MIDlet will need to provide some other mechanism (probably a Command) that allows users to confirm their choices. MULTIPLE lists allow users to select and deselect various elements before confirming the selection. EXCLUSIVE lists permit users to change their minds several times before confirming the selection.

Figure 6-1a shows an EXCLUSIVE list. The user navigates through the list using the arrow up and down keys. An element is selected by pressing the select button on the device. Figure 6-1b shows a MULTIPLE list. It works basically the same way as an EXCLUSIVE list, but multiple elements can be selected simultaneously. As before, the user moves through the list with the up and down arrow keys. The select key toggles the selection of a particular element.

Figure 6-1: List types: (a) EXCLUSIVE and (b) MULTIPLE lists

A further refinement of EXCLUSIVE also exists: IMPLICIT lists combine the steps of selection and confirmation. The IMPLICIT list acts just like a menu. Figure 6-2 shows an IMPLICIT list with images and text for each element. When the user hits the select key, the list immediately fires off an event, just like a Command. An IMPLICIT list is just like an EXCLUSIVE list in that the user can only select one of the list elements. But with IMPLICIT lists, there's no opportunity for the user to change his or her mind before confirming the selection.

Figure 6-2: IMPLICIT lists combine selection and confirmation.

Event Handling for IMPLICIT Lists

When the user makes a selection in an IMPLICIT List, the commandAction() method of the List's CommandListener is invoked. A special value is passed to commandAction() as the Command parameter:

public static final Command SELECT_COMMAND

For example, you can test the source of command events like this:

public void commandAction(Command c, Displayable s) { if (c == nextCommand) // ... else if (c == List.SELECT_COMMAND) // ... }

There's an example at the end of this chapter that demonstrates an IMPLICIT List.

Creating Lists

To create a List, specify a title and a list type. If you have the element names and images available ahead of time, you can pass them in the constructor:

public List(String title, int type) public List(String title, int type, String[] stringElements, Image[] imageElements)

The stringElements parameter cannot be null; however, stringElements or imageElements may contain null array elements. If both the string and image for a given list element are null, the element is displayed blank. If both the string and the image are defined, the element will display using the image and the string.

Some Lists will have more elements than can be displayed on the screen. Indeed, the actual number of elements that will fit varies from device to device. But don't worry: List implementations automatically handle scrolling up and down to show the full contents of the List.

About Images

Our romp through the List class yields a first look at images. Instances of the javax.microedition.lcdui.Image class represent images in the MIDP. The specification dictates that implementations be able to load images files in PNG format.[1] This format supports both a transparent color and animated images.

Image has no constructors, but the Image class offers four createImage() factory methods for obtaining Image instances. The first two are for loading images from PNG data.

public static Image createImage(String name) public static Image createImage(byte[] imagedata, int imageoffset, int imagelength)

The first method attempts to create an Image from the named file, which should be packaged inside the JAR that contains your MIDlet. You should use an absolute pathname or the image file may not be found. The second method creates an Image using data in the supplied array. The data starts at the given array offset, imageoffset, and is imagelength bytes long.

Images may be mutable or immutable. Mutable Images can be modified by calling getGraphics() and using the returned Graphics object to draw on the image. (For full details on Graphics, see Chapter 9.) If you try to call getGraphics() on an immutable Image, an IllegalStateException will be thrown.

The two createImage() methods described above return immutable Images. To create a mutable Image, use the following method:

public static Image createImage(int width, int height)

Typically you would create a mutable Image for off-screen drawing, perhaps for an animation or to reduce flicker if the device's display is not double buffered.

Any Image you pass to Alert, ChoiceGroup, ImageItem, or List should be immutable. To create an immutable Image from a mutable one, use the following method: public static Image createImage(Image image).

Editing a List

List provides methods for adding items, removing elements, and examining elements. Each element in the List has an index. The first element is at index 0, then next at index 1, and so forth. You can replace an element with setElement() or add an element to the end of the list with appendElement(). The insertElement() method adds a new element to the list at the given index; this bumps all elements at that position and higher up by one.

public void setElement(int index, String stringElement, Image imageElement) public void insertElement(int index, String stringElement, Image imageElement) public int appendElement(String stringElement, Image imageElement)

You can examine the string or image for a given element by supplying its index. Similarly, you can use deleteElement() to remove an element from the List.

public String getString(int index) public Image getImage(int index) public void deleteElement(int index)

Finally, the size() method returns the number of elements in the List.

public int size()

Working with List Selections

You can find out whether a particular element in a List is selected by supplying the element's index to the following method:

public boolean isSelected(int index)

For EXCLUSIVE and IMPLICIT lists, the index of the single selected element is returned from the following method:

public int getSelectedIndex()

If you call getSelectedIndex() on a MULTIPLE list, it will return−1.

To change the current selection programmatically, use setSelectedIndex().

public void setSelectedIndex(int index, boolean selected)

Finally, List allows you to set or get the selection state en masse with the following methods. The supplied arrays must have as many array elements as there are list elements.

public int getSelectedFlags(boolean[] selectedArray_return) public void setSelectedFlags(boolean[] selectedArray)

An Example

The example in Listing 6-1 shows a simple MIDlet that could be part of a travel reservation application. The user chooses what type of reservation to make. This example uses an IMPLICIT list, which is essentially a menu.

Listing 6-1: The TravelList source code.

import java.io.*; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class TravelList extends MIDlet { public void startApp() { final String[] stringElements = { "Airplane", "Car", "Hotel" }; Image[] imageElements = { loadImage("/airplane.png"), loadImage("/car.png"), loadImage("/hotel.png") }; final List list = new List("Reservation type", List.IMPLICIT, stringElements, imageElements); final Command nextCommand = new Command("Next", Command.SCREEN, 0); Command quitCommand = new Command("Quit", Command.SCREEN, 0); list.addCommand(nextCommand); list.addCommand(quitCommand); list.setCommandListener(new CommandListener() { public void commandAction(Command c, Displayable s) { if (c == nextCommand || c == List.SELECT_COMMAND) { int index = list.getSelectedIndex(); System.out.println("Your selection: " + stringElements[index]); // Move on to the next screen. Here, we just exit. notifyDestroyed(); } else notifyDestroyed(); } }); Display.getDisplay(this).setCurrent(list); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} private Image loadImage(String name) { Image image = null; try { image = Image.createImage(name); } catch (IOException ioe) { System.out.println(ioe); } return image; } }

To see images in this example, you'll need to either download the examples from the book's Web site or supply your own images. With the J2MEWTK, image files should go in the res directory of your J2MEWTK project directory. TravelList expects to find three images named airplane.png, car.png, and hotel.png.

Construction of the List itself is very straightforward. Our application also includes a Next command and a Quit command, which are both added to the List. An inner class is registered as the CommandListener for the List. If the Next command or the List's IMPLICIT command are fired off, we simply retrieve the selected item from the List and print it to the console.

The Next command, in fact, is not strictly necessary in this example since you can achieve the same result by clicking the select button on one of the elements in the List. Nevertheless, it might be a good idea to leave it there. Maybe all of the other screens in your application have a Next command, so you could keep it for user interface consistency. It never hurts to provide the user with more than one way of doing things, either.

The difference between EXCLUSIVE and IMPLICIT lists can be subtle. Try changing the List in this example to EXCLUSIVE to see how the user experience is different.

[1]MIDP implementations are not required to recognize all varieties of PNG files. The documentation for the Image class has the specifics.


Team-Fly

Категории