所谓混合字符串就是由中英文+各种标点符号+转义字符构成的字符串。我们在J2ME程序中,很多时候由于需要自己控制UI的风格,所以选择使用CANVAS而不使用FORM等高级界面。但在canvas中,长字符串的显示就需要我们自己根据显示的宽度来进行切割显示。而处理混合字符串就是其中比较复杂的情况。
首先我们要解决的是每行要绘制多少个字符,由于中文字符和英文字符,标点符号的宽度不同。如果我们固定每行显示的字符的个数,那如果中英文,符号混合在一起显示,出来的效果会出现每行显示出来的长度相差比较严重的情况,这样显示的效果不太美观。在处理这个问题上,我们确定每行绘制的最少字符数,因为中文的字宽是最长的,所以我们用显示的宽度除以中文字符的个数就能得到每行的最小字符个数,然后当我们取得最小字符个数后尝试增加后面一个字符,然后和宽度进行比较,如果大于宽度,我们就不添加这个字符,如果小于宽度,我们就继续尝试添加字符,直到大于显示宽度,这样就能保证每行放下最多的字符个数,保证每行都显示比较饱满。
接下来,我们要处理转义字符的问题。在转义字符上,主要处理/n转义字符。/n的处理主要是两种情况,一种是在每行中发现/n,这样我们就停止当行的截取,进入下一行的截取,这样就实现了换行的目的。还有一种情况就是在我们刚好截取好一行的字符串以后,后面的一个就是/n,如果这种情况,我们要抛掉/n不进行处理。
这两个功能我写在了一个方法中实现,代码如下:
/**
* 将获得的字符串切割成适合显示的字符串数组
* @param text 需要切割的字符串
* @param font 使用的字体
* @param width 显示的宽读
* @return 切割完成的字符串数组
*/
public String[] getSubInfo(String text, Font font, int width) {
boolean isFind = false;
// 字符最大的宽度
int max_width = font.charWidth('我');
// 每行放置的最小字符个数
int char_num = width / max_width;
Vector vector = new Vector();
while (text.length() > 0) {
int index = text.indexOf('/n');
int start_num = 0;
String info;
// 剩余的字符串小于每行的字符个数
if (text.length() < char_num) {
if (index != -1 && index < text.length()) {
info = text.substring(start_num, index + 1);
text = text.substring(index + 1);
vector.addElement(info);
continue;
}
info = text.substring(start_num);
vector.addElement(info);
break;
}
if (index != -1 && index < char_num) {
info = text.substring(start_num,
start_num = (start_num + index + 1));
text = text.substring(start_num);
vector.addElement(info);
continue;
}
info = text.substring(start_num, start_num = (start_num + char_num));
//尝试增加字符个数
while (font.stringWidth((info + text.substring(start_num,
start_num + 1))) < width) {
if (index == (start_num + 1)) {
start_num += 1;
isFind = true;
break;
}
info += text.substring(start_num, start_num = (start_num + 1));
if (info.length() >= text.length()) {
break;
}
}
if (!isFind && (start_num + 1) == index) {
start_num += 1;
}
text = text.substring(start_num);
vector.addElement(info);
}
String[] text_info = new String[vector.size()];
vector.copyInto(text_info);
return text_info;
}
关于其他转义字符,如/t,我们可以加上对它的检测,并做相关的转化处理就可以了
如果是英语单词在行末的处理这里暂未实现。