FileDocCategorySizeDatePackage
CustomItem.javaAPI DocJ2ME MIDP 2.065834Thu Nov 07 12:02:28 GMT 2002javax.microedition.lcdui

CustomItem

public abstract class CustomItem extends Item
A CustomItem is customizable by subclassing to introduce new visual and interactive elements into Forms. Subclasses are responsible for their visual appearance including sizing and rendering and choice of colors, fonts and graphics. Subclasses are responsible for the user interaction mode by responding to events generated by keys, pointer actions, and traversal actions. Finally, subclasses are responsible for calling {@link Item#notifyStateChanged} to trigger notification of listeners that the CustomItem's value has changed.

Like other Items, CustomItems have the concept of minimum and preferred sizes. These pertain to the total area of the Item, which includes space for the content, label, borders, etc. See Item Sizes for a full discussion of the areas and sizes of Items.

CustomItem subclasses also have the concept of the content size, which is the size of only the content area of the CustomItem. The content area is a rectangular area inside the total area occupied by the CustomItem. The content area is the area within which the CustomItem subclass paints and receives input events. It does not include space consumed by labels and borders. The implementation is responsible for laying out, painting, and handling input events within the area of the Item that is outside the content area.

All coordinates passed between the implementation and the CustomItem subclass are relative to the item's content area, with the upper-left corner of this area being located at (0,0). Size information passed between the implementation and the CustomItem subclass with the {@link #getMinContentHeight getMinContentHeight}, {@link #getMinContentWidth getMinContentWidth}, {@link #getPrefContentHeight getPrefContentHeight}, {@link #getPrefContentWidth getPrefContentWidth}, and {@link #sizeChanged sizeChanged} methods all refer to the size of the content area. The implementation is responsible for computing and maintaining the difference between the size of the content area and the size of the total area of the Item as reported by the Item size methods {@link Item#getMinimumHeight Item.getMinimumHeight}, {@link Item#getMinimumWidth Item.getMinimumWidth}, {@link Item#getPreferredHeight Item.getPreferredHeight}, and {@link Item#getPreferredWidth Item.getPreferredWidth}.

The implementation may disregard sizing information returned from a CustomItem if it exceeds limits imposed by the implementation's user interface policy. In this case, the implementation must always report the actual size granted to the CustomItem via the {@link #sizeChanged sizeChanged} and the {@link #paint paint} methods. For example, this situation may occur if the implementation prohibits an Item from becoming wider than the screen. If the CustomItem subclass code returns a value from getMinContentWidth that would result in the CustomItem being wider than the screen, the implementation may assign a width smaller than the minimum width returned by getMinContentWidth.

The implementation is allowed to call the CustomItem's content size methods {@link #getMinContentHeight getMinContentHeight}, {@link #getMinContentWidth getMinContentWidth}, {@link #getPrefContentHeight getPrefContentHeight}, and {@link #getPrefContentWidth getPrefContentWidth}, in any order with respect to other CustomItem methods. For all of these methods, the CustomItem subclass code must return values that are consistent with the current contents of the CustomItem. If the contents changes, it is not sufficient for the CustomItem subclass code simply to begin returning different values from the content size methods. Instead, the subclass code must call the {@link #invalidate invalidate} method whenever its contents changes. This indicates to the implementation that it may need to perform its layout computation, which will call the content size methods to get new values based on the CustomItem's new contents.

Interaction Modes

The CustomItem class is intended to allow edit-in-place on many items, but it does not allow every conceivable interaction. Desire for flexibility has been balanced against a requirement that these APIs be simple enough to master easily, along with a need to allow for platform-specific variations in look-and-feel, all without sacrificing interoperability.

The general idea is that there are multiple interaction "modes" and that the Form implementation can convey which ones it supports. The CustomItem can then choose to support one or more interaction modes. There is no requirement for a CustomItem to implement all combinations of all interaction modes. Typically, a CustomItem will implement an approach (such as the separate editing screen technique discussed below) that works on all platforms, in addition to a highly interactive approach that relies on a particular interaction mode. At run time, the CustomItem code can query the system to determine whether this interaction mode is supported. If it is, the CustomItem can use it; otherwise, it will fall back to the approach that works on all platforms.

CustomItem can always use item commands to invoke a separate editing screen, although components with a small number of discrete states could simply respond by changing the state and then causing an notifyStateChanged notification. A technique for using a separate editing screen would be to load the value into another Displayable object (such as a List) and then to call {@link Display#setCurrent(Displayable)} on it. When the user issues a command (such as "OK") to indicate that editing of this value is complete, the listener can retrieve the value from that Displayable object and then call {@link Display#setCurrentItem(Item)} to return to this item.

Keypad Input

The implementation may optionally support delivery of keypad events to the CustomItem. The implementation indicates the level of support by setting the KEY_PRESS, KEY_RELEASE, and KEY_REPEAT bits in the value returned by getInteractionModes. Events corresponding to these bits are delivered through calls to the keyPressed(), keyReleased(), and keyRepeated() methods, respectively. If an implementation supports KEY_RELEASE events, it must also support KEY_PRESS events. If an implementation supports KEY_REPEAT events, it must also support KEY_PRESS and KEY_RELEASE events. If supported, KEY_RELEASE events will generally occur after a corresponding KEY_PRESS event is received, and KEY_REPEAT events will generally occur between KEY_PRESS and KEY_RELEASE events. However, it is possible for the CustomItem to receive KEY_RELEASE or KEY_REPEAT events without a corresponding KEY_PRESS if a key is down when the CustomItem becomes visible.

Key event methods are passed the keyCode indicating the key on which the event occurred. Implementations must provide means for the user to generate events with key codes Canvas.KEY_NUM0 through Canvas.KEY_NUM9, Canvas.KEY_STAR, and Canvas.KEY_POUND. Implementations may also deliver key events for other keys, include device-specific keys. The set of keys available to a CustomItem may differ depending upon whether commands have been added to it.

The application may map key codes to game actions through use of the getGameAction method. If the implementation supports key events on CustomItems, the implementation must provide a sufficient set of key codes and a mapping to game actions such that all game actions are available to CustomItems.

The set of keys and the key events available to a CustomItem may differ from what is available on a Canvas. In particular, on a system that supports traversal, the system might use directional keys for traversal and elect not to deliver these keys to CustomItems. The mapping between key codes and game actions in a CustomItem may differ from the mapping in a Canvas. See Key Events and Game Actions on class Canvas for further information about key codes and game actions.

Pointer Input

The implementation may optionally support delivery of pointer events (such as taps with a stylus) to the CustomItem. The implementation indicates the level of support by setting the POINTER_PRESS, POINTER_RELEASE, and POINTER_DRAG bits in the value returned by getInteractionModes. Events corresponding to these bits are delivered through calls to the pointerPressed(), pointerReleased(), and pointerDragged() methods, respectively. If an implementation supports POINTER_RELEASE events, it must also support POINTER_PRESS events. If an implementation supports POINTER_DRAG events, it must also support POINTER_PRESS and POINTER_RELEASE events. If supported, POINTER_RELEASE events will generally occur after a corresponding POINTER_PRESS event is received, and POINTER_DRAG events will generally occur between POINTER_PRESS and POINTER_RELEASE events. However, it is possible for the CustomItem to receive POINTER_RELEASE or POINTER_DRAG events without a corresponding POINTER_PRESS if the pointer is down when the CustomItem becomes visible.

The (x,y) location of the pointer event is reported with every pointer event. This location is expressed in the coordinate system of the CustomItem, where (0,0) is the upper-left corner of the CustomItem. Under certain circumstances, pointer events may occur outside the bounds of the item.

Traversal

An implementation may support traversal internal to a CustomItem, that is, the implementation may temporarily delegate the responsibility for traversal to the item itself. Even if there is only one traversal location inside the CustomItem, the item may want support the internal traversal protocol so that it can perform specialized highlighting, animation, etc. when the user has traversed into it.

The implementation indicates its support for traversal internal to a CustomItem by setting one or both of the TRAVERSE_HORIZONTAL or TRAVERSE_VERTICAL bits in the value returned by getInteractionModes(). If neither of these bits is set, the implementation is unwilling to let CustomItems traverse internally, or the implementation does not support traversal at all. If the implementation does support traversal but has declined to permit traversal internal to CustomItems, the implementation will supply its own highlighting outside the CustomItem's content area.

The CustomItem need not support internal traversal at all. It can do this by returning false to the initial call to the traverse method. (This is the default behavior if this method hasn't been overridden by the CustomItem.) If this occurs, the system must arrange for the user to be able to traverse onto and past this item. The system must also arrange for proper scrolling to take place, particularly if the item exceeds the height of the screen, regardless of whether internal traversal is occurring.

An implementation may provide support for delivering keypad or pointer events to CustomItems even if it has declined to support delivering traverse events to CustomItems. If an implementation provides support for delivering keypad or pointer events to CustomItems, it must provide a means to do so for every CustomItem, even for those that have refused internal traversal by returning false to the initial traverse() call. This implies that such implementations must still support some notion of focus for an item, even if that item is not supporting internal traversal.

See the documentation for the {@link #traverse traverse} method for a full specification of the behavior and responsibilities required for the item to perform internal traversal.

Item Appearance

The visual appearance of each item consists of a label (handled by the implementation) and its contents (handled by the subclass).

Labels are the responsibility of the implementation, not the item. The screen area that is allocated to the CustomItem for its contents is separate from the area that the implementation uses to display the CustomItem's label. The implementation controls the rendering of the label and its layout with respect to the content area.

The CustomItem is responsible for painting its contents whenever the paint method is called.

The colors for foreground, background, highlighted foreground, highlighted background, border, and highlighted border should be retrieved from {@link Display#getColor}. This will allow CustomItems to match the color scheme of other items provided with the device. The CustomItem is responsible for keeping track of its own highlighted and unhighlighted state.

The fonts used should be retrieved from {@link Font#getFont}. This will allow them to match the fonts used by other items on the device for a consistent visual appearance.

since
MIDP 2.0

Fields Summary
protected static final int
TRAVERSE_HORIZONTAL
Interaction mode bit indicating support of horizontal traversal internal to the CustomItem.

TRAVERSE_HORIZONTAL has the value 1.

protected static final int
TRAVERSE_VERTICAL
Interaction mode bit indicating support for vertical traversal internal to the CustomItem.

TRAVERSE_VERTICAL has the value 2.

protected static final int
KEY_PRESS
Interaction mode bit indicating support for key pressed events.

KEY_PRESS has the value 4.

protected static final int
KEY_RELEASE
Interaction mode bit indicating support for key released events.

KEY_RELEASE has the value 8.

protected static final int
KEY_REPEAT
Interaction mode bit indicating support for key repeated events.

KEY_REPEAT has the value 0x10.

protected static final int
POINTER_PRESS
Interaction mode bit indicating support for point pressed events.

POINTER_PRESS has the value 0x20.

protected static final int
POINTER_RELEASE
Interaction mode bit indicating support for point released events.

POINTER_RELEASE has the value 0x40.

protected static final int
POINTER_DRAG
Interaction mode bit indicating support for point dragged events.

POINTER_DRAG has the value 0x80.

protected static final int
NONE
A value for traversal direction that indicates that traversal has entered or has changed location within this item, but that no specific direction is associated with this traversal event.

NONE has the value 0.

private int
labelHeight
labelHeight caches the height of the label for this CustomItem, as it is not included when reporting dimensions to the subclass
Constructors Summary
protected CustomItem(String label)
Superclass constructor, provided so that the CustomItem subclass can specify its label.

param
label the CustomItem's label


                          
        
        super(label);
    
Methods Summary
intcallGetLayout()
Called to determine the effective layout directive.

return
the CustomItem's layout directive

        int l = LAYOUT_TOP | LAYOUT_LEFT;
        try {
            // SYNC NOTE: We lock on calloutLock around any calls
            // into application code
            synchronized (Display.calloutLock) {
                l = this.getLayout();
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
        return l;
    
voidcallHideNotify()
Called by the system to notify this Item it is being hidden

The default implementation of this method does nothing.

        super.callHideNotify();

        try {
            synchronized (Display.calloutLock) {
                this.hideNotify();
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
    
voidcallKeyPressed(int keyCode)
Called by the system to signal a key press

param
keyCode the key code of the key that has been pressed
see
#getInteractionModes


        ItemCommandListener cl = null;
	Command defaultCmd = null;

        synchronized (Display.LCDUILock) {
            cl = commandListener;
	    defaultCmd = defaultCommand;
        } // synchronized


        // SYNC NOTE: The call to the listener must occur outside
        // of the lock

	try {
	    // SYNC NOTE: We lock on calloutLock around any calls
	    // into application code
	    synchronized (Display.calloutLock) {

		if ((cl != null)
                    && (defaultCmd != null)
                    && (keyCode == Display.KEYCODE_SELECT)) {
		    cl.commandAction(defaultCmd, this);
		} else {
		  this.keyPressed(keyCode);
		}
	    }
	} catch (Throwable thr) {
	    Display.handleThrowable(thr);
	}

    
voidcallKeyReleased(int keyCode)
Called by the system to signal a key release

param
keyCode the key code of the key that has been released
see
#getInteractionModes

        try {
            synchronized (Display.calloutLock) {
                this.keyReleased(keyCode);
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
    
voidcallKeyRepeated(int keyCode)
Called by the system to signal a key repeat

param
keyCode the key code of the key that has been repeated
see
#getInteractionModes

        try {
            synchronized (Display.calloutLock) {
                this.keyRepeated(keyCode);
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
    
intcallMinimumHeight()
Get the minimum height of this Item, including the minimum content height and room for the label. This is the callback for Item's public getMinimumHeight() method.

return
the minimum height

        try {
            synchronized (Display.calloutLock) {
                return this.getMinContentHeight() + getLabelHeight(-1);
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
        return -1;
    
intcallMinimumWidth()
Get the minimum width of this Item, including the minimum content width and room for the label. This is the callback for Item's public getMinimumWidth() method.

return
the minimum width

        try {
            synchronized (Display.calloutLock) {
                return this.getMinContentWidth();
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
        return -1;
    
voidcallPaint(Graphics g, int w, int h)
Called to paint this CustomItem

param
g the Graphics object to be used for rendering the item
param
w current width of the item in pixels
param
h current height of the item in pixels

        // We need to check the clip to determine if
        // the label needs painting
        super.paintLabel(g, w);
        g.clipRect(0, labelHeight, w, h - labelHeight);
        g.translate(0, labelHeight);

        try {
            synchronized (Display.calloutLock) {
                this.paint(g, w, h - labelHeight);
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }

        g.translate(0, -labelHeight);
    
voidcallPointerDragged(int x, int y)
Called by the system to signal a pointer drag

param
x the x coordinate of the pointer drag
param
y the x coordinate of the pointer drag
see
#getInteractionModes

        try {
            synchronized (Display.calloutLock) {
                this.pointerDragged(x, y - labelHeight);
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
    
voidcallPointerPressed(int x, int y)
Called by the system to signal a pointer press

param
x the x coordinate of the pointer down
param
y the y coordinate of the pointer down
see
#getInteractionModes

        try {
            synchronized (Display.calloutLock) {
                this.pointerPressed(x, y - labelHeight);
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
    
voidcallPointerReleased(int x, int y)
Called by the system to signal a pointer release

param
x the x coordinate of the pointer up
param
y the x coordinate of the pointer up
see
#getInteractionModes

        try {
            synchronized (Display.calloutLock) {
                this.pointerReleased(x, y - labelHeight);
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
    
intcallPreferredHeight(int w)
Get the preferred height of this Item, including the preferred content height and room for the label. This is the callback for Item's public getPreferredHeight() method.

param
w the width to base the height size on
return
the preferred height

        try {
            synchronized (Display.calloutLock) {
                return this.getPrefContentHeight(w) + getLabelHeight(w);
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
        return -1;
    
intcallPreferredWidth(int h)
Get the preferred width of this Item, including the preferred content width and room for the label. This is the callback for Item's public getPreferredWidth() method.

param
h the height to base the width size on
return
the preferred width

        try {
            synchronized (Display.calloutLock) {
                return this.getPrefContentWidth(h);
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
        return -1;
    
voidcallShowNotify()
Called by the system to notify this Item it is being shown

The default implementation of this method does nothing.

        super.callShowNotify();

        try {
            synchronized (Display.calloutLock) {
                this.showNotify();
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
    
voidcallSizeChanged(int w, int h)
Called by the system to indicate the size available to this Item has changed

param
w the new width of the item's content area
param
h the new height of the item's content area

        labelHeight = getLabelHeight(w);
        try {
            synchronized (Display.calloutLock) {
                this.sizeChanged(w, h - labelHeight);
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
    
booleancallTraverse(int dir, int viewportWidth, int viewportHeight, int[] visRect_inout)
Traverse this CustomItem

param
dir the direction of traversal
param
viewportWidth the width of the container's viewport
param
viewportHeight the height of the container's viewport
param
visRect_inout passes the visible rectangle into the method, and returns the updated traversal rectangle from the method
return
true if internal traversal had occurred, false if traversal should proceed out


        super.callTraverse(dir, viewportWidth, viewportHeight, visRect_inout);

        try {
            synchronized (Display.calloutLock) {
                // We shave off the label height from the overall
                // item viewport
                visRect_inout[HEIGHT] -= labelHeight;
                boolean t = this.traverse(dir, viewportWidth,
                                          viewportHeight - labelHeight,
                                          visRect_inout);
                // We shift the return value from the item's traverse
                // by the label height to give the real location
                visRect_inout[Y] += labelHeight;
                return t;
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
        return false;
    
voidcallTraverseOut()
Called by the system to indicate traversal has left this Item

see
#getInteractionModes
see
#traverse
see
#TRAVERSE_HORIZONTAL
see
#TRAVERSE_VERTICAL

        super.callTraverseOut();

        try {
            synchronized (Display.calloutLock) {
                this.traverseOut();
            }
        } catch (Throwable thr) {
            Display.handleThrowable(thr);
        }
    
public intgetGameAction(int keyCode)
Gets the game action associated with the given key code of the device. Returns zero if no game action is associated with this key code. See the Game Actions section of class Canvas for further discussion of game actions.

The mapping of key codes to game actions may differ between CustomItem and Canvas.

param
keyCode the key code
return
the game action corresponding to this key, or 0 if none
throws
IllegalArgumentException if keyCode is not a valid key code

        int n = Display.getGameAction(keyCode);

        if (n == -1) {
            throw new IllegalArgumentException();
        }

        return n;
    
protected final intgetInteractionModes()
Gets the available interaction modes. This method is intended to be called by CustomItem subclass code in order for it to determine what kinds of input are available from this device. The modes available may be dependent upon several factors: the hardware keys on the actual device, which of these keys are needed for the system to do proper navigation, the presence of a pointing device, etc. See Interaction Modes for further discussion. If this method returns 0, the only interaction available is through item commands.

return
a bitmask of the available interaction modes

 
        return (TRAVERSE_HORIZONTAL | TRAVERSE_VERTICAL | 
                KEY_PRESS | KEY_RELEASE | KEY_REPEAT |
	        POINTER_PRESS | POINTER_RELEASE | POINTER_DRAG);
    
protected abstract intgetMinContentHeight()
Implemented by the subclass to return the minimum height of the content area, in pixels. This method is called by the implementation as part of its layout algorithm. The actual height granted is reported in the {@link #sizeChanged sizeChanged} and {@link #paint paint} methods.

return
the minimum content height in pixels

protected abstract intgetMinContentWidth()
Implemented by the subclass to return the minimum width of the content area, in pixels. This method is called by the implementation as part of its layout algorithm. The actual width granted is reported in the {@link #sizeChanged sizeChanged} and {@link #paint paint} methods.

return
the minimum content width in pixels

protected abstract intgetPrefContentHeight(int width)
Implemented by the subclass to return the preferred height of the content area, in pixels. This method is called by the implementation as part of its layout algorithm.

The width parameter is the tentative width assigned to the content area. The subclass code may use this value in its computation of the preferred height. The width parameter will be -1 if the implementation has not assigned a tentative value for the width. Otherwise, width will have a specific value if the application has locked the width of the CustomItem or if the container's layout algorithm has already computed a tentative width at the time of this call. The subclass must not assume that the tentative width passed or the preferred height returned will be granted. The actual size granted is reported in the {@link #sizeChanged sizeChanged} and {@link #paint paint} methods.

param
width the tentative content width in pixels, or -1 if a tentative width has not been computed
return
the preferred content height in pixels

protected abstract intgetPrefContentWidth(int height)
Implemented by the subclass to return the preferred width of the content area, in pixels. This method is called by the implementation as part of its layout algorithm.

The height parameter is the tentative height assigned to the content area. The subclass code may use this value in its computation of the preferred width. The height parameter will be -1 if the implementation has not assigned a tentative value for the height. Otherwise, height will have a specific value if the application has locked the height of the CustomItem or if the container's layout algorithm has already computed a tentative height at the time of this call. The subclass must not assume that the tentative height passed or the preferred width returned will be granted. The actual size granted is reported in the {@link #sizeChanged sizeChanged} and {@link #paint paint} methods.

param
height the tentative content height in pixels, or -1 if a tentative height has not been computed
return
the preferred content width in pixels

protected voidhideNotify()
Called by the system to notify the item that it is now completely invisible, when it previously had been at least partially visible. No further paint() calls will be made on this item until after a showNotify() has been called again.

The default implementation of this method does nothing.

 
protected final voidinvalidate()
Signals that the CustomItem's size and traversal location need to be updated. This method is intended to be called by CustomItem subclass code to inform the implementation that the size of the CustomItem's content area or the internal traversal location might need to change. This often occurs if the contents of the CustomItem are modified. A call to this method will return immediately, and it will cause the container's layout algorithm to run at some point in the future, possibly resulting in calls to {@link #getMinContentHeight getMinContentHeight}, {@link #getMinContentWidth getMinContentWidth}, {@link #getPrefContentHeight getPrefContentHeight}, {@link #getPrefContentWidth getPrefContentWidth}, {@link #sizeChanged sizeChanged}, or {@link #traverse traverse}. The {@link #paint paint} method may also be called if repainting is necessary as a result of the layout operation. If the content size is invalidated while the CustomItem is not visible, the layout operation may be deferred. The traverse method will be called if the CustomItem contains the current traversal location at the time invalidate is called.

        super.invalidate();
    
protected voidkeyPressed(int keyCode)
Called by the system when a key is pressed. The implementation indicates support for delivery of key press events by setting the KEY_PRESS bit in the value returned by the getInteractionModes method.

param
keyCode the key code of the key that has been pressed
see
#getInteractionModes

 
protected voidkeyReleased(int keyCode)
Called by the system when a key is released. The implementation indicates support for delivery of key release events by setting the KEY_RELEASE bit in the value returned by the getInteractionModes method.

param
keyCode the key code of the key that has been released
see
#getInteractionModes

 
protected voidkeyRepeated(int keyCode)
Called by the system when a key is repeated. The implementation indicates support for delivery of key repeat events by setting the KEY_REPEAT bit in the value returned by the getInteractionModes method.

param
keyCode the key code of the key that has been repeated
see
#getInteractionModes

 
protected abstract voidpaint(Graphics g, int w, int h)
Implemented by the subclass to render the item within its container. At the time of the call, the Graphics context's destination is the content area of this CustomItem (or back buffer for it). The Translation is set so that the upper left corner of the content area is at (0,0), and the clip is set to the area to be painted. The application must paint every pixel within the given clip area. The item is allowed to modify the clip area, but the system must not allow any modification to result in drawing outside the bounds of the item's content area. The w and h passed in are the width and height of the content area of the item. These values will always be equal to the values passed with the most recent call to sizeChanged(); they are passed here as well for convenience.

Other values of the Graphics object are as follows:

  • the current color is black;
  • the font is the same as the font returned by {@link Font#getDefaultFont() Font.getDefaultFont()};
  • the stroke style is {@link Graphics#SOLID SOLID};

The paint() method will be called only after showNotify() call on this item and before a subsequent hideNotify() call on this item, in other words, only when at least a portion of the item is actually visible on the display. In addition, the paint() method will be called only if the item's width and height are both greater than zero.

param
g the Graphics object to be used for rendering the item
param
w current width of the item in pixels
param
h current height of the item in pixels

protected voidpointerDragged(int x, int y)
Called by the system when a pointer drag action (for example, pen motion after a press but before a release) has occurred within the item. The (x,y) coordinates are relative to the origin of the item. Implementations should deliver pointer drag events to an item even if the pointer is being moved outside the item. In this case the (x,y) coordinates may indicate a location outside the bounds of the item. The implementation indicates support for delivery of pointer release events by setting the POINTER_DRAG bit in the value returned by the getInteractionModes method.

param
x the x coordinate of the pointer drag
param
y the x coordinate of the pointer drag
see
#getInteractionModes

 
protected voidpointerPressed(int x, int y)
Called by the system when a pointer down action (for example, a pen tap) has occurred within the item. The (x,y) coordinates are relative to the origin of the item, and they will always indicate a location within the item. The implementation indicates support for delivery of pointer press events by setting the POINTER_PRESS bit in the value returned by the getInteractionModes method.

param
x the x coordinate of the pointer down
param
y the y coordinate of the pointer down
see
#getInteractionModes

 
protected voidpointerReleased(int x, int y)
Called by the system when a pointer up action (for example, a pen lift) has occurred after a pointer down action had occurred within the item. The (x,y) coordinates are relative to the origin of the item. Implementations should deliver a pointer release event to an item even if the pointer has moved outside the item when the release occurs. In this case the (x,y) coordinates may indicate a location outside the bounds of the item. The implementation indicates support for delivery of pointer release events by setting the POINTER_RELEASE bit in the value returned by the getInteractionModes method.

param
x the x coordinate of the pointer up
param
y the x coordinate of the pointer up
see
#getInteractionModes

 
protected final voidrepaint()
Called by subclass code to request that the item be repainted. If this item is visible on the display, this will result in a call to paint() the next time the CustomItem is to be displayed. The CustomItem subclass should call this method when the item's internal state has been updated such that its visual representation needs to be updated.

        try {
            // We prune off the label area when doing a complete repaint
            super.repaint(0, labelHeight,
                          bounds[WIDTH], bounds[HEIGHT] - labelHeight);
        } catch (Exception e) {
            Display.handleThrowable(e);
        }
    
protected final voidrepaint(int x, int y, int w, int h)
Called by subclass code to request that the specified rectangular area of the item be repainted. If that area is visible on the display, this will result in call to paint with graphics set to include the specified rectangular area. The area is specified relative to the CustomItem's content area. The CustomItem should call this method when the item's internal state has been updated and only part of the visual representation needs to be updated.

param
x the x coordinate of the rectangular area to be updated
param
y the y coordinate of the rectangular area to be updated
param
w the width of the rectangular area to be updated
param
h the height of the rectangular area to be updated

        try {
            // We only allow the CustomItem to repaint within its
            // content area
            if (x > bounds[WIDTH]) {
                return;
            }
            if (x < 0) {
                x = 0;
            }
            if (y < 0) {
                y = 0;
            }
            // We offset the Item's coordinate space by the label
            y += labelHeight;
            if (y > bounds[HEIGHT]) {
                return;
            }
            if (x + w > bounds[WIDTH]) {
                w = bounds[WIDTH] - x;
            }
            if (y + h > bounds[HEIGHT]) {
                h = bounds[HEIGHT] - y;
            }
            super.repaint(x, y, w, h);
        } catch (Exception e) {
            Display.handleThrowable(e);
        }
    
protected voidshowNotify()
Called by the system to notify the item that it is now at least partially visible, when it previously had been completely invisible. The item may receive paint() calls after showNotify() has been called.

The default implementation of this method does nothing.

 
protected voidsizeChanged(int w, int h)
Implemented by the subclass in order to handle size change events. This method is called by the system when the size of the content area of this CustomItem has changed.

If the size of a CustomItem changes while it is visible on the display, it may trigger an automatic repaint request. If this occurs, the call to sizeChanged will occur prior to the call to paint. If the CustomItem has become smaller, the implementation may choose not to trigger a repaint request if the remaining contents of the CustomItem have been preserved. Similarly, if the CustomItem has become larger, the implementation may choose to trigger a repaint only for the new region. In both cases, the preserved contents must remain stationary with respect to the origin of the CustomItem. If the size change is significant to the contents of the CustomItem, the application must explicitly issue a repaint request for the changed areas. Note that the application's repaint request should not cause multiple repaints, since it can be coalesced with repaint requests that are already pending.

If the size of the item's content area changes while it is not visible, calls to this method may be deferred. If the size had changed while the item was not visible, sizeChanged will be called at least once before the item becomes visible once again.

The default implementation of this method does nothing.

param
w the new width of the item's content area
param
h the new height of the item's content area

 
protected booleantraverse(int dir, int viewportWidth, int viewportHeight, int[] visRect_inout)
Called by the system when traversal has entered the item or has occurred within the item. The direction of traversal and the item's visible rectangle are passed into the method. The method must do one of the following: it must either update its state information pertaining to its internal traversal location, set the return rectangle to indicate a region associated with this location, and return true; or, it must return false to indicate that this item does not support internal traversal, or that that internal traversal has reached the edge of the item and that traversal should proceed to the next item if possible.

The implementation indicates support for internal traversal within a CustomItem by setting one or both of the TRAVERSE_HORIZONTAL or TRAVERSE_VERTICAL bits in the value returned by the getInteractionModes method. The dir parameter indicates the direction of traversal by using Canvas game actions Canvas.UP, Canvas.DOWN, Canvas.LEFT, and Canvas.RIGHT, or the value NONE, which indicates that there is no specific direction associated with this traversal event. If the TRAVERSE_HORIZONTAL bit is set, this indicates that the Canvas.LEFT and Canvas.RIGHT values will be used to indicate the traversal direction. If the TRAVERSE_VERTICAL bit is set, this indicates that the Canvas.UP and Canvas.DOWN values will be used to indicate the traversal direction. If both bits are set, all four direction values may be used for the traversal direction, indicating that the item should perform two-dimensional traversal. The dir parameter may have the value NONE under any combination of the TRAVERSE_VERTICAL and TRAVERSE_HORIZONTAL bits.

Although Canvas game actions are used to indicate the traversal direction, this does not imply that the keys mapped to these game actions are being used for traversal, nor that that keys are being used for traversal at all.

The viewportWidth and viewportHeight parameters indicate the size of the viewable area the item's container has granted to its items. This represents the largest area of the item that is likely to be visible at any given time.

The visRect_inout parameter is used both for passing information into this method and for returning information from this method. It must be an int[4] array. The information in this array is a rectangle of the form [x,y,w,h] where (x,y) is the location of the upper-left corner of the rectangle relative to the item's origin, and (w,h) are the width and height of the rectangle. The return values placed into this array are significant only when the traverse() method returns true. The values are ignored if the traverse() method returns false.

When this method is called, the visRect_inout array contains a rectangle representing the region of the item that is currently visible. This region might have zero area if no part of the item is visible, for example, if it is scrolled offscreen. The semantics of the rectangle returned are discussed below.

The CustomItem must maintain state that tracks whether traversal is within this item, and if it is, it must also record the current internal location. Initially, traversal is outside the item. The first call to the traverse() method indicates that traversal has entered the item. Subsequent calls to this method indicate that traversal is occurring within this item. Traversal remains within the item until the traverseOut method is called. The CustomItem must keep track of its traversal state so that it can distinguish traversal entering the item from traversal within the item.

When traversal enters the item, the traversal code should initialize its internal traversal location to the "first" location appropriate for the item's structure and the traversal direction. As an example of the latter policy, if the traversal direction is DOWN, the initial location should be the topmost internal element of the item. Similarly, if the traversal direction is UP, the initial location should be the bottommost element of the item. The CustomItem should still choose the "first" location appropriately even if its primary axis is orthogonal to the axis of traversal. For example, suppose the traversal mode supported is TRAVERSE_VERTICAL but the CustomItem is structured as a horizontal row of elements. If the initial traversal direction is DOWN, the initial location might be the leftmost element, and if the initial traversal direction is UP, the initial location might be the rightmost element.

Traversal may enter the item without any specific direction, in which case the traversal direction will be NONE. This may occur if the user selects the item directly (e.g., with a pointing device), or if the item gains the focus because its containing Form has become current. The CustomItem should choose a default traversal location. If the CustomItem had been traversed to previously, and if it is appropriate for the user interface of the CustomItem, the previous traversal location should be restored.

When traversal occurs within the item, the internal traversal location must be moved to the next appropriate region in the direction of traversal. The item must report its updated internal traversal location in the visRect_inout return parameter as described below and return true. The item will typically provide a highlight to display the internal traversal location to the user. Thus, the item will typically also request repaints of the old and new traversal locations after each traversal event. There is no requirement that the area the item requests to be repainted is the same as the area returned in the visRect_inout rectangle. The system will combine any repaint requests with any additional repainting that may occur as a result of scrolling.

The traverse() method may be called with a direction of NONE when the traversal is already within the CustomItem. This will occur in response to the CustomItem subclass code having called the invalidate() method. In this case, the CustomItem should simply return its current notion of the traversal location. This mechanism is useful if the CustomItem needs to update the traversal location spontaneously (that is, not in response to a traversal event), for example, because of a change in its contents.

If the internal traversal location is such that the traversal event would logically cause traversal to proceed out of the item, the item should return false from the traverse() method. For example, if the current traversal location is the bottommost internal element of the item, and the traversal direction is DOWN, the traverse() method should simply return false. In this case the method need not update the values in the visRect_inout array. The item must leave its internal traversal location unchanged, and it should not request a repaint to update its highlighting. It should defer these actions until the traverseOut() method is called. The system will call the traverseOut() method when traversal actually leaves the item. The system might not call the traverseOut() method, even if traverse() has returned false, if this item is at the edge of the Form or there is no other item beyond to accept the traversal. Even if the traverse() method returns false, the traversal location is still within this item. It remains within this item until traverseOut() is called.

Note the subtle distinction here between the initial traverse() call signifying entry into the item and subsequent calls signifying traversal within the item. A return value of false to the initial call indicates that this item performs no internal traversal at all, whereas a return of false to subsequent calls indicates that traversal is within this item and may now exit.

The width and height of the rectangle returned in the visRect_inout array are used by the Form for scrolling and painting purposes. The Form must always position the item so that the upper left corner of this rectangle, as specified by the (x,y) position, is visible. In addition, the item may also specify a width and height, in which case the Form will attempt to position the item so that as much of this rectangle as possible is visible. If the width and height are larger than the size of the viewport, the bottom and right portions of this rectangle will most likely not be visible to the user. The rectangle thus returned will typically denote the size and location of one of the item's internal elements, and it will also typically (though not necessarily) correspond to where the element's highlight will be painted. Width and height values of zero are legal and are not treated specially. Negative values of width and height are treated as if they were zero.

There is no requirement on the location of the rectangle returned in the visRect_inout array with respect to the traversal direction. For example, if the CustomItem implements internal scrolling, a traversal direction of DOWN may cause the item's contents to scroll upwards far enough so that the rectangle returned may be above its old location. CustomItem subclasses must ensure that continued traversal in one direction will eventually reach the edge of the item and then traverse out by returning false from this method. CustomItems must not implement "wraparound" behavior (for example, traversing downwards from the bottommost element moves the traversal location to the topmost element) because this will trap the traversal within the item.

If the CustomItem consists of internal elements that are smaller than the container's viewport, the rectangle returned should be the same size as one of these elements. However, the CustomItem might have contents whose elements are larger than the viewport, or it might have contents having no internal structure. In either of these cases, the item should return a rectangle that best represents its idea of the content area that is important for the user to see. When traversal occurs, the item should move its traversal location by an amount based on the viewport size. For example, if the viewport is 80 pixels high, and traversal occurs downwards, the item might move its traversal location down by 70 pixels in order to display the next screenful of content, with 10 pixels overlap for context.

All internal traversal locations must be reachable regardless of which traversal modes are provided by the implementation. This implies that, if the implementation provides one-dimensional traversal, the CustomItem must linearize its internal locations. For example, suppose the traversal mode is TRAVERSE_VERTICAL and the CustomItem consists of a horizontal row of elements. If the traversal direction is DOWN the internal traversal location should move to the right, and if the traversal direction is UP the internal traversal location should move to the left. (The foregoing convention is appropriate for languages that use left-to-right text. The opposite convention should be used for languages that use right-to-left text.) Consider a similar example where the traversal mode is TRAVERSE_VERTICAL and the CustomItem consists of a grid of elements. A traversal direction of DOWN might proceed leftwards across each row, moving to the next row downwards when the location reaches the rightmost element in a row.

If the implementation provides two-dimensional traversal but the CustomItem is one-dimensional, a traversal direction along the item's axis should traverse within the item, and a traversal direction orthogonal to the item's axis should cause immediate traversal out of the item by returning false from this method. For example, suppose a CustomItem is implementing a vertical stack of elements and traversal is already inside the item. If a traverse event is received with direction UP or DOWN, the traverse() method should move to the next element and return true. On the other hand, if a traverse event is received with direction RIGHT or LEFT, the traverse() method should always return false so that traversal exits the item immediately. An item that implements internal traversal should always accept entry - that is, the initial call to traverse() should return true - regardless of the axis of the traversal direction.

If the traverse() method returns false when traversal is entering the item, this indicates to the system that the item does not support internal traversal. In this case, the item should not perform any of its own highlighting, and the system will perform highlighting appropriate for the platform, external to the item.

The default implementation of the traverse() method always returns false.

param
dir the direction of traversal, one of {@link Canvas#UP Canvas.UP}, {@link Canvas#DOWN Canvas.DOWN}, {@link Canvas#LEFT Canvas.LEFT}, {@link Canvas#RIGHT Canvas.RIGHT}, or {@link #NONE NONE}.
param
viewportWidth the width of the container's viewport
param
viewportHeight the height of the container's viewport
param
visRect_inout passes the visible rectangle into the method, and returns the updated traversal rectangle from the method
return
true if internal traversal had occurred, false if traversal should proceed out
see
#getInteractionModes
see
#traverseOut
see
#TRAVERSE_HORIZONTAL
see
#TRAVERSE_VERTICAL

        return false;
    
protected voidtraverseOut()
Called by the system when traversal has occurred out of the item. This may occur in response to the CustomItem having returned false to a previous call to traverse(), if the user has begun interacting with another item, or if Form containing this item is no longer current. If the CustomItem is using highlighting to indicate internal traversal, the CustomItem should set its state to be unhighlighted and request a repaint. (Note that painting will not occur if the item is no longer visible.)

see
#getInteractionModes
see
#traverse
see
#TRAVERSE_HORIZONTAL
see
#TRAVERSE_VERTICAL