06-13-2009 08:43 PM
I have a field in which I need to draw text in a given range and if the text is long, it should wrap around. I tried to use Graphics.drawText(text, x, y, DrawStyle.TOP|DrawStyle.Left, width) but it seems to simply chops text at end.
What's the best way of wrapping text? I do hope that I do not have to compute number of words and manually draw each line...
Thanks
Solved! Go to Solution.
06-13-2009 09:45 PM
02-15-2010 11:33 AM
I know this thread has been dead for a while but I just wanted to post this here in case anyone ever needs an algorithm for this... found this over on nokia's j2me boards, Ive modified it to work with BB api
private Vector wrap (String text, int width)
{
Vector result = new Vector ();
if (text ==null)
return result;
boolean hasMore = true;
// The current index of the cursor
int current = 0;
// The next line break index
int lineBreak = -1;
// The space after line break
int nextSpace = -1;
while (hasMore)
{
//Find the line break
while (true)
{
lineBreak = nextSpace;
if (lineBreak == text.length() - 1)
{
// We have reached the last line
hasMore = false;
break;
}
else
{
nextSpace = text.indexOf(' ', lineBreak+1);
if (nextSpace == -1)
nextSpace = text.length() -1;
int linewidth = this.getFont().getAdvance(text,current, nextSpace-current);
// If too long, break out of the find loop
if (linewidth > width)
break;
}
}
String line = text.substring(current, lineBreak + 1);
result.addElement(line);
current = lineBreak + 1;
}
return result;
}
public void drawListRow(ListField lf, Graphics g, int row, int y, int width) {
String sh = "whatever content you want";
Vector lines = wrap(sh, textwidth);
for (int i = 0; i < lines.size(); i++)
{
int liney = y + (i * this.getFont().getHeight());
g.drawText((String)lines.elementAt(i), 0 ,liney,TOP | LEFT | DrawStyle.ELLIPSIS, textwidth);
}
}
02-15-2010 05:21 PM
05-09-2010 02:54 AM
Thanks a lot man ! I was looking for this from a long time...works like a charm !
Thank you so much.
Afzal
05-09-2010 02:27 PM - edited 05-09-2010 02:29 PM
Oops I found one case where the above code does not work i.e. when there are no spaces in the text. I did something on my own and it seems to work (until now at least
)
private Vector wrap (String text, int width)
{
Vector result = new Vector ();
String remaining = text;
while (remaining.length()>=0)
{
int index = getSplitIndex(remaining, width);
if (index == -1)
break;
result.addElement(remaining.substring(0,index));
remaining = remaining.substring(index);
if (index == 0)
break;
}
return result;
}
private int getSplitIndex(String bigString, int width)
{
int index = -1;
int lastSpace = -1;
String smallString="";
boolean spaceEncountered = false;
boolean maxWidthFound = false;
for (int i=0; i<bigString.length(); i++)
{
char current = bigString.charAt(i);
smallString += current;
if (current == ' ')
{
lastSpace = i;
spaceEncountered = true;
}
int linewidth = this.getFont().getAdvance(smallString,0, smallString.length());
if(linewidth>width)
{
if (spaceEncountered)
index = lastSpace+1;
else
index = i;
maxWidthFound = true;
break;
}
}
if (!maxWidthFound)
index = bigString.length();
return index;
}
I am still testing it.
Afzal
05-09-2010 07:10 PM
public static Vector parseMessage(String message,Font fnt,int fontSize,int width){
Vector parsedStrings = new Vector();
int start = 0, stop = 0;
Font f = fnt.derive(Font.PLAIN, fontSize, Ui.UNITS_px);
int lineWidth = width;
int numChars = message.length();
boolean ok = false;
start = 0;
stop = 0;
Character space = new Character(' ');
Character nLine = new Character('\n');
Character comma = new Character(',');
Character period = new Character('.');
Character dash = new Character('-');
Character fslash = new Character('/');
Character bslash = new Character('\\');
while( (start < numChars) ){
int check = start;
int subLength = 0;
while( !ok ){
if( space.charValue() == message.charAt(check) ){
subLength = f.getAdvance( message.substring(start, check) );
if( subLength < lineWidth ) stop = check;
else ok = true;
} else
if( comma.charValue() == message.charAt(check) ){
subLength = f.getAdvance( message.substring(start, check) );
if( subLength < lineWidth ) stop = check;
else ok = true;
} else
if( period.charValue() == message.charAt(check) ){
subLength = f.getAdvance( message.substring(start, check) );
if( subLength < lineWidth ) stop = check;
else ok = true;
} else
if( dash.charValue() == message.charAt(check) ){
subLength = f.getAdvance( message.substring(start, check) );
if( subLength < lineWidth ) stop = check;
else ok = true;
} else
if( fslash.charValue() == message.charAt(check) ){
subLength = f.getAdvance( message.substring(start, check) );
if( subLength < lineWidth ) stop = check;
else ok = true;
} else
if( bslash.charValue() == message.charAt(check) ){
subLength = f.getAdvance( message.substring(start, check) );
if( subLength < lineWidth ) stop = check;
else ok = true;
} else
if( nLine.charValue() == message.charAt(check) ){
stop = check;
ok = true;
} else
if( f.getAdvance( message.substring(start, check) ) >= lineWidth ){
ok = true;
}
if( !ok ){
if( check == (numChars-1) ){
stop = check+1;
ok = true;
} else {
check = check + 1;
}
}
}
if( stop == numChars ){
parsedStrings.addElement( message.substring(start) );
}else{
parsedStrings.addElement( message.substring(start, stop) );
}
start = stop + 1;
stop = start;
ok = false;
}
return parsedStrings;
}
Just to put in my two cents, here is a routine that I came up with that allows you to adjust for the font size. You can add or remove any of the delimiter characters to break up the string where you want.
12-06-2010 04:10 AM
Hi Kylefowler,
thanks for the code, I am not sure if i made progress because the list displays but the text is blank and if a scrow down i see the blue background highlighter, so I can see if the text is wrapped or not.
-so i am not sure what i am doing wrong?
-first of, should the methods be in the ListCallBack class
Please everyone, I really need help on this
, its the only thing left to complete my project.
Thanks in advance. ![]()