Sun Java Solaris Communities My SDN Account Join SDN
 
Technical Articles and Tips

Using Custom Items in MIDP 2.0

 



An earlier J2ME Tech Tip, Developing Custom Components for the Mobile Information Device Profile, showed you how to develop custom user-interface components for the MIDP 1.0 environment. In that environment, you can use these custom components only with the low-level UP APIs, not their high-level counterparts. In other words, if you want your MIDP 1.0 application to use custom components, it must draw the entire screen contents itself. Custom components can be used only on canvases, not on forms.

Form-based custom components are available to MIDP 2.0 applications, however, through the CustomItem class, a new addition to the javax.microedition.lcdui package. Like all form items, CustomItem extends the Item class. Applications can't extend Item directly because it defines no public or protected constructors, but CustomItem is designed to be extended. In particular, it defines the event methods that custom components require, to draw themselves, and to process user input.

Defining a custom item is a matter of subclassing CustomItem and implementing five abstract methods:

import javax.microedition.lcdui.*;

// A minimal implementation of a MIDP 2.0
// custom item. Fills its content area with
// a white rectangle.

public class MinimalItem extends CustomItem {
    public MinimalItem( String label ){
        super( label );
    }

    // Returns the minimal height of the content
    // area.

    protected int getMinContentHeight(){
        return 40;
    }

    // Returns the minimal width of the content
    // area.

    protected int getMinContentWidth(){
        return 40;
    }

    // Returns the preferred height of the content
    // area. A tentative value for the opposite
    // dimension -- the width -- is passed to aid
    // in the height calculation. The tentative value
    // should be ignored if it is -1.

    protected int getPrefContentHeight( int width ){
        return getMinContentHeight();
    }

    // Returns the preferred width of the content
    // area. A tentative value for the opposite
    // dimension -- the height -- is passed to aid
    // in the width calculation. The tentative value
    // should be ignored if it is -1.

    protected int getPrefContentWidth( int height ){
        return getMinContentWidth();
    }

    // Draws the item's content area, whose dimensions
    // are given by the width and height parameters.

    protected void paint( Graphics g, int width, int height ){
        g.setColor( 255, 255, 255 );
        g.fillRect( 0, 0, width, height );
    }
}

This custom item fills its content area - the area for which it is solely responsible for drawing and processing input - with the color white, and does not respond to any input events. Not a very useful item, to be sure, but a complete implementation nonetheless, and enough to understand the basic features of a custom item.

First, like any other item, a custom item has an optional label, a string that identifies the item on the device's display. To ensure consistency, the drawing and positioning of the label is done by the system, not the application, outside the content area. You can omit the label by setting it to null. The actual dimensions of the item include space for the label as well as for any borders or other visual effects provided by the system - the content area is a subset of the item's total area.

Second, items in MIDP 2.0 have the concept of minimum and preferred content area dimensions. These are familiar concepts if you've ever written a component for the J2SE Abstract Windowing Toolkit (AWT). When performing layout calculations, the system can ask an item for the preferred dimensions of its content area - the optimal height and width for the item - by invoking getPrefContentHeight() and getPrefContentWidth(). To obtain the minimum dimensions of the content area, which should be less than or equal to the preferred dimensions, the system invokes getMinContentHeight() and getMinContentWidth(). Note that when the system queries an item for its preferred dimensions, it may already have calculated some preliminary layout information. Thus, when the system invokes getPrefContentHeight(), it passes a tentative value for the content area width (not the height). Similarly, it passes getPrefContentWidth() a tentative value for the content area height. The methods use these tentative values for the opposite dimension to compute the preferred values for the queried dimension. If no tentative value is available, the system passes -1 to the methods.

Third, custom items draw themselves by implementing a paint() method, very much the way canvases do. The custom item's paint() method, however, is passed height and width parameters along with the necessary Graphics object. These additional parameters are the current dimensions of the item's content area. All drawing is clipped to these dimensions. The drawing origin is the top left corner of the content area.

This MIDlet demonstrates the use of the MinimalItem class:

import java.io.*;
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

// A MIDP 2.0 MIDlet that displays an instance of the
// MinimalItem class, demonstrating how to use
// custom items.

public class MinimalItemTest extends MIDlet
                 implements CommandListener {

    private Display         display;

    public static final Command exitCommand =
                         new Command( "Exit",
                                      Command.EXIT, 1 ); 

    public MinimalItemTest(){
    }

    public void commandAction( Command c,
                               Displayable d ){
        if( c == exitCommand ){
            exitMIDlet();
        }
    }

    protected void destroyApp( boolean unconditional )
                       throws MIDletStateChangeException {
        exitMIDlet();
    }

    public void exitMIDlet(){
        notifyDestroyed();
    }

    public Display getDisplay(){ return display; }

    protected void initMIDlet(){
        // Create a custom item and set its layout
        // policy.

        MinimalItem mi = new MinimalItem( "label" );
        mi.setLayout( Item.LAYOUT_CENTER |
                      Item.LAYOUT_NEWLINE_BEFORE |
                      Item.LAYOUT_NEWLINE_AFTER );

        Form f = new Form( "MinimalItem Test" );
        f.append( "Before..." );
        f.append( mi );
        f.append( "... and after" );
        f.addCommand( exitCommand );
        f.setCommandListener( this );

        getDisplay().setCurrent( f );
    }

    protected void pauseApp(){
    }

    protected void startApp()
                      throws MIDletStateChangeException {
        if( display == null ){ 
            display = Display.getDisplay( this );
            initMIDlet();
        }
    }
}

To run MinimalItemTest you'll need to use the J2ME Wireless Toolkit 2.0 or the MIDP 2.0 reference implementation, both available from Mobile Information Device Profile (MIDP).

There's much more to writing custom items than is demonstrated here, of course. You'll want to dig into the documentation of CustomItem's notification methods, similar to those of the Canvas class, which applications use to convey keystroke, pointer, and other events to a custom item.



Back To Top