转自:http://120.132.134.205/cmdn/bbs/viewthread.php?tid=24603 由于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 == '/n') { if (rowLength > 0) { v.addElement(text.substring(rowIndex, i)); rowLength = 0; } else v.addElement(""); i++; rowIndex = i; continue; } charWidth = font.charWidth(chars); 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 >= 'A' && chars <= '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 == '/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())); } }