×
Namespaces

Variants
Actions
Revision as of 12:11, 8 June 2009 by tanjaluodes (Talk | contribs)

Scrollable Text in Java ME

From Nokia Developer Wiki
Jump to: navigation, search


Here is a J2ME example showing how scrollable text can be implemented. (Will post full midlet source code soon)

Scrollable text screenshot.png

This is a sample midlet showing the following code in action: Media:ScrollableTextField.zip‎, that you can try also with the emulator on this page

We start defining some customizable variables, to define the layout of our text element:

static final int SCROLL_STEP = 25;
 
int scrollbarWidth = 4;
int scrollbarHeight = 0;
int scrollbarTop = 0;
int scrollbarColor = 0x0000ff;
 
int borderWidth = 1;
int borderColor = 0x000000;
int bgColor = 0xffffff;
 
Font textFont = Font.getDefaultFont();
int textColor = 0x000000;
 
int padding = 1;
int interline = 2;

The we define some variable that will be used internally:

static final String VOID_STRING = "";
static final char SPACE_CHAR = ' ';
 
int width = 0;
int height = 0;
int innerWidth = 0;
int innerHeight = 0;
 
int currentY = 0;
int textHeight = 0;
 
String[] textRows = null;

Now, let's define a simple constructor that accept a width and a height as parameters:

public ScrollableTextFieldExt(int width, int height)
{
this.width = width;
this.height = height;
 
this.innerWidth = width - 2 * borderWidth - 2 * padding - scrollbarWidth;
this.innerHeight = height - 2 * borderWidth - 2 * padding;
}

Now, it's time to set some text into this element, don't you think? Here is the method:

public void setText(String text)
{
this.textRows = getTextRows(text, textFont, innerWidth);
 
this.textHeight = textRows.length * (interline + textFont.getHeight());
 
scrollbarHeight = Math.min(innerHeight, innerHeight * innerHeight / textHeight);
 
scrollbarTop = 0;
 
currentY = 0;
}

And let's manage the scrolling of this element, with these methods:

public void scrollDown()
{
scroll(SCROLL_STEP);
}
public void scrollUp()
{
scroll(- SCROLL_STEP);
}
private void scroll(int delta)
{
currentY += delta;
 
if(currentY < 0)
{
currentY = 0;
}
else if(currentY > textHeight - innerHeight)
{
currentY = Math.max(0, textHeight - innerHeight);
}
 
scrollbarTop = innerHeight * currentY / textHeight;
}

The getTextRows() method will return the text rows, splitted accordingly to given Font and width. A possible implementation is the following (note that this implementation will not split single words, even if wider than the given maximum width):

public static String[] getTextRows(String text, Font font, int width) {
char spaceChar = ' ';
 
//will contain text rows
Vector rowsVector = new Vector();
 
//will contain current row text
StringBuffer currentRowText = new StringBuffer();
 
//indexes used to split text words
int prevIndex = 0;
int currIndex = text.indexOf(spaceChar);
 
if(currIndex == -1)
currIndex = text.length();
 
//will hold widths of current row and token
int rowWidth = 0;
int tokenWidth = 0;
 
//width of a single whitespace
int whitespaceWidth = font.stringWidth(" ");
 
//current text token
String currentToken = null;
 
while (currIndex != -1) {
//get the current token
currentToken = text.substring(prevIndex, currIndex);
 
//get the width of current token..
tokenWidth = font.stringWidth(currentToken);
 
//..and update row width
rowWidth += tokenWidth;
 
//if row is not empty, add the whitespace width too
if (currentRowText.length() > 0) {
rowWidth += whitespaceWidth;
}
 
//if new row width is bigger than max width, and previous row is not empty
if (currentRowText.length() > 0 && rowWidth > width) {
//add current row text to rows Vector
rowsVector.addElement(currentRowText.toString());
 
//reinitialize current row with current token
currentRowText.setLength(0);
currentRowText.append(currentToken);
 
//and update current row width
rowWidth = tokenWidth;
} else {
//if current row is not empty, add a whitespace
if (currentRowText.length() > 0)
currentRowText.append(spaceChar);
 
//and then add current token
currentRowText.append(currentToken);
}
 
//check if text is ended
if (currIndex == text.length())
break;
 
//update indexes
prevIndex = currIndex + 1;
 
currIndex = text.indexOf(spaceChar, prevIndex);
 
if (currIndex == -1)
currIndex = text.length();
}
 
//finally append current row, if not empty
if (currentRowText.length() > 0) {
rowsVector.addElement(currentRowText.toString());
}
 
//Convert our rows vector to a String array
String[] rowsArray = new String[rowsVector.size()];
 
rowsVector.copyInto(rowsArray);
 
return rowsArray;
}

And, finally, we should paint this element :)

public void paint(Graphics g)
{
g.setColor(borderColor);
g.fillRect(0, 0, width, height);
 
g.setColor(bgColor);
g.fillRect(borderWidth, borderWidth, width - 2 * borderWidth, height - 2 * borderWidth);
 
g.setColor(textColor);
g.setFont(textFont);
 
g.translate(borderWidth + padding, borderWidth + padding);
 
g.setClip(0, 0, innerWidth, innerHeight);
 
if(textRows != null)
{
for(int i = 0; i < textRows.length; i++)
{
g.drawString(textRows[i], 0, i * (textFont.getHeight() + interline) - currentY, Graphics.TOP | Graphics.LEFT);
}
}
 
g.setClip(0, 0, width, height);
 
g.setColor(scrollbarColor);
g.fillRect(innerWidth, scrollbarTop, scrollbarWidth, scrollbarHeight);
 
g.translate(- (borderWidth + padding), - (borderWidth + padding));
}
136 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×