JavaME UI设计之低级界面文本控件

 
在做某些应用时,我们通常需要处理显示大量的文字,例如,要实现一个电子书阅读器,需要处理的文字非常多,这时我们应该会需要一系列的文本控件,比如:菜单,列表、文本显示等,这里我们主要分析实现一个用于文本显示的控件,他需要提供自动换行,翻页等功能,在网上看到很多人在询问如何实现这样的控件,并且网上提供的大多数是自动换行,没有实现翻页,并且实现的效率也不是很高,所以这里我们再次通过一个简单的算法来实现这样一个功能。
实现之前,我们首先需要分析该控件的功能,首先,需要显示任意数量的文本,需要对文本实现自动换行,翻页等功能。我们都知道在做JavaME应用程序时,程序员通常不能指定文字的大小等,因为文字的大小一般会根据不同的手机而不同,因此我们需要动态计算字体的大小,文本的长度等。
下面首先构建一个类StringLayout来实现对字符串的布局,主要包括一下一些成员变量:
public class StringLayout {
    public int layoutWidth, layoutHeight, layoutX, layoutY;  
    private int lineGap; //行高 
    private String text; //要处理的文本
    private int fontHeight; //字体的高度
    private int lineCount; //行数
    private Vector line; //存放拆分之后的字符串
    private Font font =Font.getDefaultFont();//Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN,Font.SIZE_SMALL); //字体
    private int currLine = 0; //当前行
    public boolean isChange = false;
    private int rgbcolor=0xffffff; //颜色
    public StringLayout() {}
    //省略部分...
}
首先考虑实现自动换行,要自动换行,就需要先需要对要处理的文本进行截取,截取的过程需要根据指定的文本显示区域来定,下面我们通过init函数来对字符串进行截取,代码如下:
/** 
 * 构造函数   
 * Str:布局中的字符串   
 * LayoutX:布局顶点X   
 * LayoutY:布局顶点Y   
 * LayoutWidth:布局宽度   
 * LayoutHeight:布局高度   
 * Gap:各行之间的空隙 
 */   
public void init(String Str, int LayoutX, int LayoutY, int LayoutWidth,   
       int LayoutHeight, int Gap) {
       //如果不加上最后一个字符则最后一个字符不会被截取
       text = Str+Str.charAt(Str.length() - 1);  
       layoutX = LayoutX;  
       layoutY = LayoutY;  
       layoutWidth = LayoutWidth;  
       layoutHeight = LayoutHeight;  
       lineGap = Gap;  
       int begin = 0;  
       fontHeight = font.getHeight();  
       lineCount = 0;  
       line = new Vector(5, 2);  
       for (int i = 0; i < text.length(); i++) {  
              char ch = text.charAt(i);  
              if (font.stringWidth(text.substring(begin, i + 1)) >= layoutWidth  
                     || i == text.length() - 1 || ch == '\n') {
                     line.addElement(text.substring(begin, i));
                            if (ch == '\n')  
                                   begin = i + 1;  
                            else  
                                   begin = i;  
                     lineCount++;  
              }  
       }  
}
截取的原理为截取一段字符串,然后比较该字符串的宽度是否超过了指定的文本显示区域的宽度,截取的索引为“i+1”,如果超出范围则将索引为“i”之前的字符串取出存放到一个准备好的Vector中,并且行数lineCount也随之加一,再进入下一个循环继续截取,当然如果遇到“\n”这样的换行符则直接换行,当然还有其他的一些自定义的换行符。该函数的第一行中,我们对每个字符串加上了一个他的最后一个字符,原因则是我们截取的长度索引都是“i+1”,因此避免最后一个字符丢失,因此在开始时就多加上了最后一个字符。现在所有的文本都按照指定的文本区域截取并存放到Vector中了。下面就需要开始绘制这些字符段了。绘制代码如下:
public void draw(Graphics g) {   
       if(text==null)return;  
       int i1 = g.getClipX();  
       int j1 = g.getClipY();  
       int k1 = g.getClipWidth();  
       int l1 = g.getClipHeight();  
       g.setColor(rgbcolor);  
       g.setClip(layoutX, layoutY, layoutWidth, layoutHeight);  
       g.setFont(font);  
       for (int i = currLine; i < line.size(); i++) {  
              String s = (String) line.elementAt(i);  
              g.drawString(s, layoutX, layoutY + (i - currLine) * (fontHeight + lineGap), 0);  
       }  
       g.setClip(i1, j1, k1, l1);  
       isChange = false; 
}
绘制过程,则非常简单,通过循环绘制Vector中的元素即可,并且需要先通过setClip设置好裁剪区域,循环需要从当前行数currLine开始,这样就有利于我们实现翻页操作。
下面,我们通过一段文字来测试该控件的使用,截取的字符串是否正确,代码如下:
mStringLayout = new StringLayout();
        String string = "自动换行 \n翻页,测试自\n动换行,翻页,abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,自动换行\n翻页,测试自\n动换行,翻页,abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ自动换行\n翻页,测试自\n动换行,翻页,abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        mStringLayout.init( string+string+string+string+string+string, 0, 0, 240, 320, 3);
在paint()函数中调用mStringLayout.draw(g);即可,绘制效果如图2-1所示。
如果需要加入翻页,则在StringLayout类中加入如下几个方法即可,分别为检测是否能够翻页,和执行翻页。
public boolean isNext() {   
       if (currLine < lineCount - 1)  
              return true;  
       else  
              return false;  
}   
public void next() {   
       if (currLine < lineCount - 1) {  
              currLine++;  
              isChange = true;  
       }  
}    
public boolean isPrev() {   
       if (currLine > 0)  
              return true;  
       else  
              return false;  
}   
public void prev() {   
       if (currLine > 0) {  
              currLine--;  
              isChange = true;  
       }  
}
当然了,使用也就很简单了,只需要在按键或者触摸函数中调用该控件的翻页函数即可。另外,该类还可以进行一些其他的扩展,比如设置字体的颜色setColor和字体setFont等,由于篇幅关系,我们就不一一贴出代码了,大家可以自行任意扩展。该类是通过低级界面实现了,因此,可以很容易用于游戏开发中的文字布局显示。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值