×
Namespaces

Variants
Actions
Revision as of 09:58, 8 August 2013 by hamishwillee (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Scrollable Text in Java ME

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata
Code ExampleArticle
Created: jappit (10 Apr 2008)
Last edited: hamishwillee (08 Aug 2013)

Here is a J2ME example showing how scrollable text can be implemented.

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
ArrayList rowsVector = new ArrayList();
 
//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 ArrayList
rowsVector.add(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.add(currentRowText.toString());
}
 
//Convert our rows vector to a String array
String[] rowsArray = (String[])rowsVector.toArray(new String[rowsVector.size()]);
 
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));
}

Source code

Full source code of a sample MIDlet showing the Scrollable Text component in action is available here: Media:JavaME ScrollableText.zip

This page was last modified on 8 August 2013, at 09:58.
148 page views in the last 30 days.
×