J2ME Polish
J2ME Polish 2.4 Documentation
Enough Software

CustomItem

You can integrate custom items to J2ME Polish by extending the javax.microedition.lcdui.CustomItem class.

Design

Use the following attributes to design your CustomItem:

Programming

Initialization

J2ME Polish calls the getPrefContentWidth()-method first with an undefined height (-1). Then the getPrefContentHeight()-method is called with the actual granted width. When the width had to be adjusted, the custom item will be notified again with the setSize(width. height)-method.

Please note that the Display.getColor( int ) and Font.getFont( int ) are only available on MIDP/2.0 devices. Such calls should be surrounded by #ifdef-directives:

//#ifdef polish.midp2
	Font font = Font.getFont( Font.FONT_STATIC_TEXT );
//#else
	//# Font font = Font.getDefaultFont();
//#endif

Interaction Modes

The J2ME Polish implementation supports the interaction modes KEY_PRESS, KEY_RELEASE, KEY_REPEAT, POINTER_PRESS, POINTER_RELEASE, TRAVERSE_HORIZONTAL and TRAVERSE_VERTICAL.
By default every CustomItem is deemed interactive, unless you specify set customitem-inactive to true in polish.css:

.myitem {
	customitem-inactive: true;
	background-color: blue;
}

Traversal

When the custom item gains the focus for the first time, the traverse-method will be called with the CustomItem.NONE direction. Subsequent calls will include the direction (either Canvas.UP, DOWN, LEFT or RIGHT).

Handling User Input

If you want to process user input you need to override protected void keyPressed(int keyCode), protected void keyReleased(int keyCode), etc.
In J2ME Polish user events are processd hierarchially - first they are forwarded to the currently focused item. If they are not processed they will be moved downwards until there is a item or screen that feels responsible for these events. For realizing this, J2ME Polish internally uses protected boolean handleKeyPressed( int keyCode, int gameAction ), protected boolean handleKeyReleased( int keyCode, int gameAction ), etc.
For indicating that a user input event has been handled by a CustomItem following options exist:

  • invalidate(): Call invalidate() to indicate that the change of the item has been changed - this should not be used merely to indicate that an event has been handled, since all parent components will also be invalidated.
  • repaint(): Call repaint() or repaint(x,y,w,h) for indicating that the event has been processed. Since processed user input events result in a repaint of the complete screen anyhow, this might result in a small overhead.
  • UiAccess.setEventHandled(CustomItem item): Call UiAccess.setEventHandled(CustomItem item) to indicate that the event has been processed. This method results in no overhead and is, therefore, recommended.
  • handleKeyPressed(int keycode, int gameAction): You can also override the J2ME Polish specific methods protected boolean handleKeyPressed( int keyCode, int gameAction ), protected boolean handleKeyReleased( int keyCode, int gameAction ), etc:
    //#if polish.usePolishGui
    protected boolean handleKeyPressed( int keyCode, int gameAction ) {
    	boolean handled = false;
    	if ( keyCode == Canvas.KEY_NUM6) {
    		doSomeStuff();
    		handled = true;
    	}
    	if (!handled) {
    		//# handled = super.handleKeyPressed( keyCode, gameAction );
    	}
    	return handled;
    }
    //#endif
    

Using CSS for Designing the CustomItem

When the CSS-styles should be used for designing the CustomItem, please make sure that the project-classpath contains the "enough-j2mepolish-client.jar", which can be found in the "import" folder of the J2ME Polish installation directory.

When the J2ME Polish GUI is used, the preprocessing-symbol "polish.usePolishGui" is defined. This can be used when the CustomItem should be used in the J2ME Polish GUI as well in a plain MIDP 2.0 based UI:

//#if polish.usePolishGui
	import de.enough.polish.ui.*;
//#endif

There are several ways to integrate a CSS-style into the CustomItem:

  1. Defining a static style before the super-constructor is called:
    public MyItem( String label ) {
      //#style myitem
      super( label );
    }
    
  2. Allowing the setting of the style in a second constructor:
    //#if polish.usePolishGui
      public MyItem( String label, Style style ) {
        super( label, style );
      }
    //#endif
    
  3. Specifying the name of the dynamic style:
    //#if polish.useDynamicStyles
    	protected String createCssSelector() {
    	  return "myitem";
    	}
    //#endif
    
  4. Apply a style when adding the item to a Form:
    MyItem coolItem = new MyItem( label );
    //#style coolStyle
    this.form.append( coolItem );
    

The last variant is the most flexible one and you do not need to change the source code, so this is the best way to apply a style.

For reading the specific style settings, the method setStyle( Style ) needs to be overridden:

//#if polish.usePolishGui
  public void setStyle( Style style ) {
  	// hide the super call from the IDE:
  	//#if true
		//# super.setStyle( style );
	//#endif
	this.font = style.font;
	this.fontColor = style.fontColor;
	// now read specific attributes:
	//#ifdef polish.css.myitem-color
		Color colorObj = style.getColorProperty( "myitem-color" );
		if (colorObj != null) {
			this.color = colorObj.getColor(); // returns an ARGB int
		}
	//#endif
  }
//#endif

The setStyle() method will be called before the preferred content width and height is requested, when the CustomItem has a style associated with it.

Please note that the variable needs to be called "style" or needs to end with "style", so that J2ME Polish can process all styles correctly. This is required, since instead of string-based attribute names, numerical values of type short will be used in the actual code. This approach significantly reduces the runtime performance and minimizes the heap usage.

There are 5 different ways to retrieve a property from a style:

  • style.getProperty( String name ) returns either a String representing that value or null when the property is not defined.
  • style.getBooleanProperty( String name ) returns either a Boolean representing that value or null when the property is not defined. You can use this method only when you have registered the corresponding attribute in the file "custom-css-attributes.xml". The attribute-type needs to be "boolean".
  • style.getColorProperty( String name ) returns either a Color representing that value or null when the property is not defined. You can use this method only when you have registered the corresponding attribute in the file "custom-css-attributes.xml". The attribute-type needs to be "color".
  • style.getIntProperty( String name ) returns either an Integer representing that value or null when the property is not defined. You can use this method only when you have registered the corresponding attribute in the file "custom-css-attributes.xml". The attribute-type needs to be either "integer" or "color".
  • style.getObjectProperty( String name ) returns an Object that you can cast. You can use this method only when you have registered the corresponding attribute in the file "custom-css-attributes.xml". The attribute-type needs to be "object" or "style".

In the above code example we are accessing a color object, so the definition looks like this in custom-css-attributes.xml:

<attribute
	name="myitem-color"
	type="color"
	appliesTo="com.company.ui.MyCustomItem"
	description="The color of a custom item part."
	default="blue"
/>

Background and Borders

Background and border settings will be enforced by J2ME Polish, the CustomItem merely needs to paint its contents. It is advisable, therefore, that a background is only painted, when the J2ME Polish-GUI is not used:

//#if !polish.usePolishGui
	// draw default background:
	g.setColor( this.backgroundColor );
	g.fillRect( 0, 0, this.width, this.height );
//#endif

JavaDoc

back to top