In the last chapter, you learned about Forms, the most flexible and powerful descendents of javax.microedition.lcdui.Screen. Forms are essentially collections of Items. The MIDP APIs include a complete toolbox of Item subclasses, everything from text and image display to interactive date fields and gauges.
MIDP 2.0 provides even more power, through the opportunity to define your own items. In this chapter, you'll learn how to create items that do their own drawing and respond to user input.
The class that makes custom items possible is appropriately named CustomItem. Like all items that live in a Form, it is a subclass of Item. To create your very own item, all you have to do is define a subclass of CustomItem by implementing five abstract methods. The first four, listed below, have to do with the size of the item's content area, which is the area for which your code has responsibility. The total area of the custom item includes a label and perhaps borders, but these are the responsibility of the implementation. Your CustomItem subclass is only responsible for the content area.
protected int getPrefContentWidth(int height) protected int getPrefContentHeight(int width) protected int getMinContentWidth() protected int getMinContentHeight()
The first two methods should return values that define how big your item wants to be. When the MIDP implementation lays out a Form containing your item, it may not be able to honor your preferred size, but it will try. The implementation passes a proposed height and width into these methods to give your item class an idea of what its dimensions might eventually be. For example, the implementation might call your item's getPrefContentWidth() method and pass a value of 18 for the height parameter. This is the implementation asking your item, "What width would you like to be if I make your height 18?"
The second pair of methods should return information about the minimum size of the item. This is the smallest size that your item believes it can tolerate.
The fifth method that must be defined by a concrete CustomItem subclass is the paint() method, which the implementation calls to render the item.
protected void paint(Graphics g, int w, int h)
The Graphics object can be used to draw lines, shapes, text, and images on the content area of the item. The Graphics class is fully covered in Chapter 10; for now, I'll just use a few simple methods to demonstrate how to draw custom items. The w and h parameters indicate the current width and height of the content area.
Armed with this knowledge, you can create a simple CustomItem by implementing the five abstract methods described above and providing a constructor. Listing 7-1 shows one such class, SimpleItem. This class returns hardcoded values for the minimum and preferred content dimensions and provides a paint() method that draws a simple pattern of triangles.
import javax.microedition.lcdui.*;
public class SimpleItem
extends CustomItem {
public SimpleItem(String title) { super(title); }
// CustomItem abstract methods.
public int getMinContentWidth() { return 100; }
public int getMinContentHeight() { return 60; }
public int getPrefContentWidth(int width) {
return getMinContentWidth();
}
public int getPrefContentHeight(int height) {
return getMinContentHeight();
}
public void paint(Graphics g, int w, int h) {
g.drawRect(0, 0, w - 1, h - 1);
g.setColor(0x000000ff);
int offset = 0;
for (int y = 4; y < h; y += 12) {
offset = (offset + 12) % 24;
for (int x = 4; x < w; x += 24) {
g.fillTriangle(x + offset, y,
x + offset - 3, y + 6,
x + offset + 3, y + 6);
}
}
}
}
I won't make you write your own MIDlet to see your new item. Listing 7-2 shows a MIDlet that uses SimpleItem:
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class SimpleItemMIDlet
extends MIDlet
implements CommandListener {
public void startApp() {
Form form = new Form("SimpleItemMIDlet");
form.append(new SimpleItem("SimpleItem"));
Command c = new Command("Exit", Command.EXIT, 0);
form.addCommand(c);
form.setCommandListener(this);
Display.getDisplay(this).setCurrent(form);
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void commandAction(Command c, Displayable s) {
if (c.getCommandType() == Command.EXIT)
notifyDestroyed();
}
}
Figure 7-1 shows this MIDlet in action.