由于lwuit的label中没有根据内容自动换行的设置,而项目中的TextArea的样式和Label样式的背景不同,不能使用TextArea展示内容,所以就重写了一个TextLabel的类,继承自TextArea类。实现了这个功能,其中大部分源码参考了http://j2me.cc43.com/100916/124.html中的代码。
import java.util.Vector;
import com.sun.lwuit.Display;
import com.sun.lwuit.Font;
import com.sun.lwuit.TextArea;
import com.sun.lwuit.geom.Dimension;
import com.sun.lwuit.plaf.Style;
/**
*
* @ description:实现展示内容自动根据屏幕宽度换行的功能
* @ company lingxun
* @ author Lancelothe
* @ date 2010-9-30
*/
public class TextLabel extends TextArea
{
private int autoWidth = 0;// 设置换行的宽度
private int maxRow = 0;// 最大行数
private boolean maxrowCode = false;// 是否设置了最大行数
private int fontCountW = 0;// 通过汉字个数计算的宽度
private final int fontFx = 14;// 字体的size,现用14个像索
private Vector rowStrings;
private int widthForRowCalculations = -1;
/** * 无参构造函数,默认宽度为屏幕宽度 */
public TextLabel()
{
this("", Display.getInstance().getDisplayWidth());
}
/**
* * 默认宽度为屏幕宽度 *
*
* @param text
*/
public TextLabel(String text)
{
this(text, Display.getInstance().getDisplayWidth());
}
public TextLabel(String text, int width)
{
super(text);
System.out.println("屏幕宽度:" + Display.getInstance().getDisplayWidth());
System.out.println("实际宽度:" + width);
this.setEditable(false);
// 不能编辑
this.setFocusable(false);
// 不能获得焦点
this.getStyle().setBorder(null);
// 没有边框
this.autoWidth = width;
this.setScrollSize(new Dimension(0, 0));
// 设置无滚动条
this.getStyle().setPadding(0, 0, 4, 15);
this.setPreferredW(this.autoWidth);
}
public TextLabel(String text, int width, int maxRow)
{
super(text);
this.setEditable(false);
// 不能编辑
this.setFocusable(false);
// 不能获得焦点
this.maxRow = maxRow;
if (this.maxRow > 0)
this.maxrowCode = true;
this.getStyle().setBorder(null);
// 没有边框
this.setScrollSize(new Dimension(0, 0));
// 设置无滚动条
this.getStyle().setPadding(0, 0, 4, 15);
this.autoWidth = width;
this.setPreferredW(this.autoWidth);
}
/**
* * 获取宽度 *
*
* @return
*/
public int getAutoWidth()
{
return autoWidth;
}
private Vector getRowStrings()
{
if (rowStrings == null
|| widthForRowCalculations != getWidth()
- getStyle().getPadding(false, RIGHT)
- getStyle().getPadding(false, LEFT))
{
this.initRowString();
setShouldCalcPreferredSize(true);
}
return rowStrings;
}
/**
* @ description:覆盖父类中的getLines方法 @ author Lancelothe @ parameter @ create_date
* 2010-9-30 @ update_date 2010-9-30
* @see com.sun.lwuit.TextArea#getLines()
*/
public int getLines()
{
int retVal;
Vector v = this.getRowStrings();
retVal = v.size();
return retVal;
}
/**
* * 覆盖TextArea的initRowString()方法,需修改源码<br/> *
*/
protected void initRowString()
{
rowStrings = new Vector();
widthForRowCalculations = getWidth();
if (isSingleLineTextArea())
{
rowStrings.addElement(getText());
return;
}
if (getText() == null || getText().equals(""))
{
return;
}
char[] text = preprocess(getText());
// 转化成字符数组
Style style = this.getStyle();
int textLabelWidth = this.autoWidth;
// 本身的宽度
if (textLabelWidth <= 0)
{
textLabelWidth = Display.getInstance().getDisplayWidth();
// 默认屏幕宽度
}
rowStrings = this.autoText(style.getFont(), getText(), textLabelWidth);
}
/**
* * 获得指定宽度每行的文本数组 *
*
* @param font *
* @param text *
* @param maxWidth
*/
private Vector autoText(Font font, String text, int maxWidth)
{
Vector v = new Vector();
int fcwCode = 0;
// 用于用汉字宽度计算时
int piontW = font.charWidth('.') * 3;
// 计算一个点的宽度
boolean lastCode = true;
// 全部显示出来时为true
int maxLength = maxWidth ;
int textLength = font.stringWidth(text);
if (textLength <= maxLength)
{// 如果一行容得下时
v.addElement(text);
return v;
}
else
{
// this.maxRow=textLength/maxLength+2;
System.out.println("maxRow=" + maxRow);
char[] chars = text.toCharArray();
// 转化成字符数组
int charWidth = 0;
// 字符宽度
int rowLength = 0;
// 每行的长度
int rowIndex = 0;
// 每行开始的index
boolean changeRow = false;
for (int i = 0; i < chars.length; i++)
{
if (chars[i] == '/n')
{
if (rowLength > 0)
{
v.addElement(text.substring(rowIndex, i));
rowLength = 0;
}
else
v.addElement("");
i++;
rowIndex = i;
continue;
}
charWidth = font.charWidth(chars[i]);
if (!changeRow)
fcwCode += charWidth;
else
changeRow = false;
rowLength += charWidth;
if (this.fontCountW > 0 && fcwCode > this.fontCountW)
{
int j = font.charWidth('.');
int w = rowLength - charWidth;
if (w > maxLength || (w + j) > maxLength
|| (w + 2 * j) > maxLength
|| (w + 3 * j) > maxLength)
{
v.addElement(text.substring(rowIndex, i));
// v.addElement(new String(chars,rowIndex,i-rowIndex));
v.addElement("...");
}
else
{
v.addElement(text.substring(rowIndex, i) + "...");
// v.addElement(new
// String(chars,rowIndex,i-rowIndex)+"...");
}
break;
}
if (rowLength > maxLength)
{
changeRow = true;
if (chars[i] >= 'A' && chars[i] <= 'z')
{
// 如果下行第一个为字母时
if (i > 0 && chars[i - 1] >= 'A' && chars[i - 1] <= 'z')
{
int enIndex = 0;
// 单词开始的index
for (int j = i; j > 0 && chars[j - 1] >= 'A'
&& chars[j - 1] <= 'z'; j--)
enIndex = j - 1;
if (enIndex > rowIndex)
{
v.addElement(text.substring(rowIndex, enIndex));
// v.addElement(new
// String(chars,rowIndex,enIndex-rowIndex));
// 把不是字母的放在一行中
rowIndex = enIndex;
// 下一行的开始位置
i = enIndex--;
rowLength = 0;
}
else
{
v.addElement(text.substring(rowIndex, i));
// v.addElement(new
// String(chars,rowIndex,i-rowIndex));
// 每行的文本
rowIndex = i;
// 下一行的开始位置
i--;
// 起点从下一行第一个开始
rowLength = 0;
}
}
}
else
{
v.addElement(text.substring(rowIndex, i));
// v.addElement(new String(chars,rowIndex,i-rowIndex));
// 每行的文本
rowIndex = i;
// 下一行的开始位置
i--;
// 起点从下一行第一个开始
rowLength = 0;
}
}
if (i < chars.length - 1)
lastCode = false;
if (this.maxrowCode && v.size() == this.maxRow)
break;
}
if (this.fontCountW <= 0)
{
if (rowIndex <= chars.length - 1)
{
// 最后一行不够文本时
boolean h = false;
if (maxRow > 0 && v.size() == this.maxRow)
{
String vLast = (String) v.lastElement();
if (!lastCode)
{
char[] chs = vLast.toCharArray();
int chsLength = 0;
if (null != chs)
chsLength = chs.length;
if (chsLength > 0)
{
if (font.charWidth(chs[chsLength - 1]) > piontW)
// vLast=(new
// String(chs,0,chsLength-1))+"...";
// 如果最后一个字符的宽度大于三个点的宽度时
vLast = vLast.substring(0, chsLength - 1);
else
{
if (chsLength > 1
&& font
.charWidth(chs[chsLength - 1])
+ font
.charWidth(chs[chsLength - 2]) > piontW)
// vLast=(new
// String(chs,0,chsLength-2))+"...";
// 如果最后两个字符的宽度都大于三个点的宽度时
vLast = vLast.substring(0,
chsLength - 2)
+ "...";
else
// vLast=(new
// String(chs,0,chsLength-3))+"...";
// 其它的按三个字符来算
vLast = vLast.substring(0,
chsLength - 3)
+ "...";
}
v.removeElementAt(v.size() - 1);
v.addElement(vLast);
}
}
}
else
{
// v.addElement(new
// String(chars,rowIndex,chars.length-rowIndex));
String vLast = text.substring(rowIndex, chars.length);
char[] chs = vLast.toCharArray();
int r = 0;
for (int i = 0; i < chs.length; i++)
{
if (chs[i] == '/n')
{
h = true;
v.addElement(vLast.substring(r, i));
i++;
r = i;
}
}
if (h)
{
v.addElement(vLast.substring(r, chs.length));
}
else
v.addElement(vLast);
}
}
}
}
System.out.println("list size=" + v.size());
System.out.println(v.elementAt(0));
System.out.println(v.elementAt(5));
return v;
}
/**
* @ description:覆盖父类中的getTextAt方法 @ author Lancelothe @ parameter @ create_date 2010-9-30 @ update_date
* 2010-9-30
* @see com.sun.lwuit.TextArea#getTextAt(int)
*/
public String getTextAt(int line)
{
Vector rowsV = this.getRowStrings();
return (String) rowsV.elementAt(line);
}
public int getMaxRow()
{
return maxRow;
}
public void setMaxRow(int maxRow)
{
this.maxRow = maxRow;
this.initRowString();
}
public int getFontCountW()
{
return fontCountW;
}
public void setFontCountW(int fontCount)
{
this.fontCountW = fontCount * this.fontFx;
this.initRowString();
this.setPreferredSize(new Dimension(this.autoWidth, calcPreferredSize()
.getHeight()));
}
}