Posts Tagged ‘tutorial’

How to build a Canvas based List in J2ME

Friday, September 12th, 2008

Quite a bit of time is passed since the last Java ME tutorial.. so It’s time for something new, don’t you think?

Today we’ll see how it is possible to implement a simple Canvas based List, with the following features:

  • customizable style (colors, margins, font)
  • vertical scrolling
  • image and text support (as for standard Java ME Lists)

Java ME Canvas based List screenshot

It is possible to see this code in action on the emulator page.

Writing the code

First thing you should define some style-related properties, that will be used to paint the List items. Name of single properties is self-explaining.

int linePadding = 2;
int margin = 2;
int padding = 2;
Font font = Font.getDefaultFont();
 
int bgColor = 0xffffff;
 
int foreColor = 0x000000;
int foreSelectedColor = 0xffffff;
int backColor = 0xffffff;
int backSelectedColor = 0x0000ff;
 
int borderWidth = 3;
int borderColor = 0x000000;
int borderSelectedColor = 0xff0000;

Now, here are some internal properties, that will be used to handle list items content and positioning.

// will contain item splitted lines
String[][] itemLines = null;
// will hold items image parts
Image[] images = null;
// will hold selected item index
public int selectedItem = 0;
 
// these will hold item graphical properties
int[] itemsTop = null;
int[] itemsHeight = null;
 
// these will hold List vertical scrolling
int scrollTop = 0;
final int SCROLL_STEP = 40;

Now, here is the CanvasList constructor. Its arguments are (similarly to javax.microedition.lcdui.List constructor):
* the screen’s title
* set of strings specifying the string parts of the List elements
* set of images specifying the image parts of the List elements
This article will not cover the handling of different types of Lists (e.g.: exclusive, multiple, ..).

public CanvasList(String title, String[] items, Image[] imageElements)
{
	setTitle(title);
 
	this.images = imageElements;
 
	itemLines = new String[items.length][];
 
	itemsTop = new int[itemLines.length];
	itemsHeight = new int[itemLines.length];
 
	for(int i = 0; i < itemLines.length; i++)
	{
		// get image part of this item, if available
		Image imagePart = getImage(i);
 
		// get avaiable width for text
		int w = getItemWidth() - (imagePart != null ? imagePart.getWidth() + padding : 0);
 
		// and split item text into text rows, to fit available width
		itemLines[i] = getTextRows((String) items[i], font, w);
	}
}

Here are the 2 utility methods found in the CanvasList constructor:

public int getItemWidth()
{
	return getWidth() - 2 * borderWidth - 2 * padding - 2 * margin;
}
Image getImage(int index)
{
	return images != null && images.length > index ? images[index] : null;
}

Now, here is the paint() method:

protected void paint(Graphics g)
{
	// paint List background
	g.setColor(bgColor);
	g.fillRect(0, 0, getWidth(), getHeight());
 
	// translate accordingly to current List vertical scroll
	g.translate(0, - scrollTop);
 
	int top = 0;
 
	g.setFont(font);
 
	// loop List items
	for(int i = 0; i < itemLines.length; i++)
	{
		int itemRows = itemLines[i].length;
 
		Image imagePart = getImage(i);
 
		int itemHeight = itemRows * font.getHeight() + linePadding * (itemRows - 1);
 
		itemsTop[i] = top;
		itemsHeight[i] = itemHeight;
 
		// is image part higher than the text part?
		if(imagePart != null && imagePart.getHeight() > itemHeight)
		{
			itemHeight = imagePart.getHeight();
		}
		itemHeight += 2 * padding + 2 * borderWidth;
 
		g.translate(0, top);
 
		if(borderWidth > 0)
		{
			// paint item border
			g.setColor(i == selectedItem ? borderSelectedColor : borderColor);
			g.fillRect(margin, margin, getWidth() - 2 * margin, itemHeight);
		}
 
		// paint item background
		g.setColor(i == selectedItem ? backSelectedColor : backColor);
		g.fillRect(margin + borderWidth, margin + borderWidth, getWidth() - 2 * margin - 2 * borderWidth, itemHeight - 2 * borderWidth);
 
		// has this item an image part?
		if(imagePart != null)
		{
			g.drawImage(imagePart, margin + borderWidth + padding, margin + borderWidth + padding, Graphics.TOP | Graphics.LEFT);
		}
 
		// paint item text rows
		g.setColor(i == selectedItem ? foreSelectedColor : foreColor);
 
		int textLeft = margin + borderWidth + padding + (imagePart != null ? imagePart.getWidth() + padding : 0);
 
		for(int j = 0; j < itemRows; j++)
		{
			g.drawString(itemLines[i][j], textLeft, margin + borderWidth + padding + j * (linePadding + font.getHeight()), Graphics.TOP | Graphics.LEFT);
		}
 
		g.translate(0, - top);
 
		top += itemHeight + 2 * margin;
	}
	// finally, translate back
	g.translate(0, scrollTop);
}

And finally, to handle user key events, here is the keyPressed() event:

protected void keyPressed(int key)
{
	int keyCode = getGameAction(key);
 
	// is there 1 item at least?
	if(itemLines.length > 0)
	{
		// going up
		if(keyCode == Canvas.UP)
		{
			// current item is clipped on top, so can scroll up
			if(itemsTop[selectedItem] < scrollTop)
			{
				scrollTop -= SCROLL_STEP;
 
				repaint();
			}
			// is there a previous item?
			else if(selectedItem > 0)
			{
				selectedItem--;
 
				repaint();
			}
		}
		//going down
		else if(keyCode == Canvas.DOWN)
		{
			// current item is clipped on bottom, so can scroll down
			if(itemsTop[selectedItem] + itemsHeight[selectedItem] >= scrollTop + getHeight())
			{
				scrollTop += SCROLL_STEP;
 
				repaint();
			}
			// is there a following item?
			else if(selectedItem < itemLines.length - 1)
			{
				selectedItem++;
 
				repaint();
			}
		}
	}
}

About the getTextRows() method, you can grab an implementation (but you could find a lot of other ones on the Web) on this other article written some time ago: J2ME Scrollable Text.

How to use CanvasList class

Here is a sample usage of CanvasList class, that will display a list (without image parts):

String[] items = new String[]{"Item 1", "Item 2", "Item 3"};
 
CanvasList myCanvas = new CanvasList("Test canvas", items, null);

To add images to your items, it’s necessary to instantiate an Image array, and pass it to CanvasList constructor as its third argument:

Image[] images = null;
try
{
	images = new Image[]{
		Image.createImage("/item1.png"),
		Image.createImage("/item2.png"),
		Image.createImage("/item3.png")
	};
}
catch(Exception e)
{
	e.printStackTrace();
}
String[] items = new String[]{"Item 1", "Item 2", "Item 3"};
 
CanvasList myCanvas = new CanvasList("Test canvas", items, images);

Related resources

You can download full CanvasList source code here: CanvasList.java

Collapsible trees with J2ME

Tuesday, April 15th, 2008

Trees are not often used within j2me applications, but since it’s quite always a mess to deal with them, here’s a ready to use component for managing and drawing collapsible/scrollable trees :)
j2me collapsible trees

As usual, you can go to Forum Nokia Wiki for the full source code: J2me Collapsible Trees, or go to the emulator page to have a first look at a sample midlet using this component.

Customizing game sprites with J2ME

Monday, April 14th, 2008

You know, my great passion are games, and here’s a first game-related tutorial :)

Often in games a nice feature to give to users it the possibility to customize their own character, for example changing colors of the different parts (hairs, eyes, shirt, and so on).

To support this features there are 2 possibilities:

  • Include a different image for each color of each different part
  • Replace colors by code

The second options will save you the effort to create these multiple images, and will strip down your JAR size. Also, it will allow you to support a lot more colors.

You can see a simple midlet showing how this can be done with simple code on the emulator page

For the full source code you can visit the Forum Nokia Wiki page: J2ME Customizing Game Sprites Color

Building a J2ME vertical scrollable text component

Thursday, April 10th, 2008

Everyone needs scrollable text, soon or late :)

This is the reason why I’ve posted a simple tutorial on how vertical scrollable text can be implemented with J2ME.

Scrollable text screenshot

You can find it on Forum Nokia Wiki: J2me Scrollable Text tutorial

Comments are welcome!

Forum Nokia Wiki.. my first article!

Wednesday, April 9th, 2008

Forum Nokia Wiki

Yeah, I’ve finally done it!

Forum Nokia Wiki is a precious source for any kind of mobile related problems or questions, and now I’m really happy to have found the time to post my first article, that is…

How to implement custom Text Fields with J2ME!

Hope you’ll find it useful :)

EDIT: you can now test the custom Text Field component with the web emulator here.