网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  使用低级ui制作图解应用程序     
  文章作者:未知  文章来源:水木森林  
  查看:112次  录入:管理员--2007-11-17  
 

♦ 介绍

        在上一讲中讲述了如何利用高级api制作简单的应用程序。在这讲中,我们将讲述如何利用低级api进行图解应用程序的开发。

♦ 低级api

     在上一讲中所叙述的高级api具有很高的移植性,由于不能仅限于使用被定义的部分,因此,制作成具有很大的制约限制的ui是相当困难的。但是,在本讲中将要学习的低级api,由于不同机种的显示屏的尺寸和按键的数量也不一样,所以即使移植性降低,也能完全按照自己的意图制作ui,还可以直接访问输入装置。

    canvas类和graphics类实现了低级api。canvas类是displayable类的子类、用于图形和事件操作。一个canvas组件表示一个可绘画的屏幕区域,一个grafics类为描绘canvas组件提供图片,文本和形状。

♦ 3-1 canvas类

     canvas类是displayable的子类,提供描绘和处理低级事件的方法。另外,canvas类是抽象类,因此必须在应用中创建继承canvas类的单独的类。

     canvas类中有一个名为paint(graphics g)的抽象方法。用paint方法中去实现需要的图片,文本以及图形。所以我们要跳过这个方式来讲解。

code example 1

运用canvas类,在paint(graphics)方法中,可以进行图片和文本的制作。

class mycanvas extends canvas{
   void paint(graphics g){
        .
        .
        .
   }
}

♦ 3-1-1 获取手机终端的画面尺寸

     与pc画面相比,手机终端的画面尺寸较小,有必要在其中创建用户接口,所以设置是非常重要的。为此,使用canvas描绘画像、text、图形时有必要知道画面的具体尺寸。根据手机终端不同,能够在画面上描绘的范围大小也各不相同,在canvas类中有获取画面尺寸的方法:

     • int getwidth()

     • int getwidth()

不用预先知道具体硬件画面的尺寸,使用getwidth(),getheight()灵活地获取,具有较高重用性。

♦ 3-2 graphics类

     graphics类具有2d的绘画功能、与j2se的java.awt.graphics非常的相似。定义了描绘text、画像、图形等等各种各样的方法。

♦ 3-2-1 图形的描绘

♦ 3-2-1-1 线的描绘

(x1,y1)是线的起点;(x2,y2)是线的终点。

能够用void drawline(int x1,int y1,int x2, int y2); 描绘线。

♦ 3-2-1-2 四边形的描绘

使用以下的方式进行四边形的描绘。此时的(x,y)被指定为想要描绘的四边形左上方顶点的坐标。

    • void drawrect(int x,int y,int width,int height)

    • void drawrect(int x,int y,int width,int height)

用drawrect方法描绘四边形。用fillrect描绘中间全被涂抹的四边形。另外,graphics图形的描绘方式中有draw的方法和fill的方法。draw只是单指图形的描画。而fill~则是指中间被涂抹的图形的描画。

此外,利用下面的方法,能够描绘出圆角的四角形。

   • void drawroundrect(int x,int y,int width,int height.int arcwidth,int archeight)

   • void fill roundrect(int x,int y,int width,int height.int arcwidth,int archeight)

图1所示,是方法中参数的定义和描述。图2中是示例。

使用低级ui制作图解应用程序(图一)
figure 1
使用低级ui制作图解应用程序(图二)
figure 2

♦ 3-2-1-3 圆的描绘

利用以下方式进行圆的描绘。

    • void drawarc(int x,int y,int width,int height,int startangle,int arcangle)

    • void fillarc(int x,int y,int width,int height,int startangle,int arcangle)

此时,坐标(x,y)是高为height、宽为width的长方形左上方角的顶点坐标。若是height和width的值相等则可以描绘出圆的弧线。startangle,arcangle分别设定各自的角度(单位:°)。图3所示的是各自的变量;图4所示的是表示例。

使用低级ui制作图解应用程序(图三)
figure 3
使用低级ui制作图解应用程序(图四)
figure 4

♦ 3-2-1-4 色彩的描绘

     运用graphics类指定颜色给描绘的图形和文本。如果先定义好颜色,那就能按照预先的设定颜色显示。用如下方法进行颜色设定。

    • void setcolor(int rgb)
    • void setcolor(int red, int green , int blue)
    • void setgrayscale(int value)

用16进制指定色彩的情况下,则要在rgb中指定16进制的数值。此时要显示16进制的状况就要在数头附加「0x」。用10进制指定的情况下,分别用3个不同的[0-255]的数值指定red,green,blue。使用标尺的情况下,在10进制[0-255]的范围中指定色彩的浓淡。

若要更改北景的色彩时,首先在setcolor方式中指定色彩,随后在fillrect方式中描绘填充的四边形。

    //背景呈黑色
    g.setcolor(0x000000);
    g.fillrect(0,0,getwidth(),getheight());

根据以下的方法能够获取现在已经设定的色彩值。

    • int getcolor()
    • int getbluecomponent()
    • int getgreencomponent()
    • int getredcomponent()
    • int getgrayscale()

getcolor方法下能够获取设定完成的rgb16进制数值。getbluecomponent,getgreencomponent,getredcomponent下的青、蓝、红的数值能够获取在10进制的[0-255]的范围内的数值。

♦ 3-2-1-5 线型

     graphics类中准备了描绘线时的2个式样:dotted和solid。draw方法下,线型的指定是有效的。fill方法中线型的设定是无效的。 利用以下方法进行设定。

    • void setstrokestyle(int style)

线型的样式中有dotted(点线)和solid(实线),若要指定dotted时, graphics类的参数就是graphics.dotted,指定solid时,graphics类的参数就是graphics.solid。(图5)

使用低级ui制作图解应用程序(图五)
figure 5

♦ 3-2-2 text的描绘

使用以下方法描绘canvas上的文本

    • void drawchar(char character,int x,int y,int anchor)
    • void drawchar(char[] data,int offset,int length,int x,int y,int anchor)
    • void drawstring(string string,int x,int y,int anchor)
    • void drawsubstring(string str,int offset,int length,int x,int y,int anchor)

♦ 3-2-2-1 text字体的设定

     在应用中描绘text时,并不只是默认的文字,应该也有必要描绘粗体字和下划线文字吧?midp的api中有表示字体的font类。和graphics的对象一样,可以定义一个font的对象去更改文本的字体。按照以下的方法获取font对象:

    • static font getfont(int face,int style,int size)

font中有face,style,size3个属性。以下图表中表示的是能够指定的值。

 属性  face style size
 能够指定的值 face_monospace face_proportional

 style_bold style_italic

 size_largesize_medium size_small
  face_system style_plain style_underlined size_small

运用逻辑操作符号“|“可以同时使用多个属性。
为使获取的font能在graphics中设定,则要使用
    • void setfont(font font)

请看下面的范例。
font font=font.getfont(font.face_system,font.style_italic|font.style_bold,
        font.size_large);
g.setfont(font);

code example 2

另外,请按照如下方式获取字体的各种信息:

    • int charswidth(char[] ch,int offset,int length)
    • int charwidth(char ch)
    • int getbaselineposition()
    • int getheight()
    • int stringwidth(string str)
    • int substringwidth(string str,int offset,int len)

♦ 3-2-2-2 定位点

     像text和画像那样在canvas上配置子类时位置决定是必要的情况下,指定被称为定位点的基点,将定位点作为描绘的基准进行描绘。

在定位点中有如下的内容。

 horizontal  vertical

 left

 hcenter

 right

 top

 baseline

 vcenter

 bottom

定义定位点时,使用使用逻辑运算符[|],有必要分别指定横方向和纵方向。其中能够在画像描绘的定位点上指定垂直方向,但是应该注意,在text描绘的定位点上不能够指定垂直方向。

drawstring("string",x,y,width,height, graphics.left | graphics.top);

code example 3

如上所示指定的定位点的坐标和文字关系显示状况如下图所示。

使用低级ui制作图解应用程序(图六)
figure 6

另外,按照如下所示的方法指定定位点时就会出现图7。

drawstring("string",x,y,width,height,graphics. hcenter | graphics.bottom);
使用低级ui制作图解应用程序(图七)
figure 7

♦ 3-2-3 图像的描绘

用graphics类中的方法描绘画像。

    • void drawimage(image img, int x, int y, int anchor)

定位点的指定与text的描绘一样。

♦ 3-3 事件和事件的处理

     canvas类实现了低级用户接口api、主要处理用户输入的按键事件。高级api要求实现listener接口中的事件手柄。用低级api,所有的低级事件都可以传送给canvas类,因此,应用程序就必须重载一些事件处理的方法。以下是canvas类的事件处理方法。

    • shownotify()
    • hidenotify()
    • keypressed()
    • keyrepeated()
    • keyreleased()
    • paint()

这些方法被midp的线程按顺序调用。当一个事件处理的方法正在被执行时,其它的事件是不能被执行的。因此,这些方法中必须返回当前状态值。

♦ 3-3-1 show事件和hide事件

     在画面显示canvas之前,canvas表示的就是show事件。而且,canvas在系统画面中被消除后,hide事件就会产生。这些事件可调用以下的方法:

    • void shownotify()
    • void hidenotify()

这些方式,防止描绘卡通时的画面闪烁的对缓冲工作时,利用off screen缓冲(表示前在里面进行描绘的缓冲)可以解决画面闪烁问题。详细情况将在动画的讲解中详细说明。

♦ 3-3-2 按键事件

     当用户按下键盘的键时,canvas接受按键事件。每一个按键都有键代码。每一个键值和相应数值的asii值相等。以下是每个按键和其编码。

 按键 按键代码  按键代码的数值
 0 key_num0 48
 1 key_num1 49
 2 key_num2 50
 3 key_num3 51
 4 key_num4 52
 5 key_num5 53
 6 key_num6 54
 7 key_num7 55
 8 key_num8 56
 9 key_num9 57
 * key_star 42
 # key_pound 35

另外,要从按键代码中获取按键名应使用以下canvas的getkeyname()方法。

以下3种方式可以处理按键事件。

    • void keypressed(int keycode)
    • void keyreleased(int keycode)
    • void keyrepeated(int keycode)

keypressed方法是按键时的处理; keyreleased方法是释放键时的处理。keyrepeated方法记述了短时间内同一键被按多次时的处理。

♦ 3-3-2-1 游戏的响应

     一些应用程序,比如游戏,可能需要方向键的事件。canva类中定义了一般游戏的响应。一个游戏响应可能关系到多个按键。以下所示的是n800的机型中游戏响应的常量和按键的对应值关系。

 游戏动作 按键代码  按键代码的数值
 up  -1
 down  -2
 left  -3
 right  -4
 fire  -5
 game_a key_num7 55
 game_b key_num9 57
 game_c key_star 42
 game_d key_pound 35

由于游戏动作的按键代码的mapping因机种而异,所以要想制作成能在n800以外的机种上也能正常工作的midp应用程序,就必须要提高移植性。为此,利用getgameaction()方式,将按键代码变换成游戏动作来使用。

♦ 3-4 重绘的显示

     screen的情况下,画面上的任意更改都会立刻自动反映到画面中。canvas的情况下,即使在canvas上加上更改到再描绘处理中也不会改变画面。以下是这个画面在描绘的方式。

    • void repaint()
    • void repaint(int x,int y,int width,int height)

调用上面的方法进行屏幕的更新。在repaint()中,画面整体都会被更新,而在repaint(int x,int y,int width,int height)中只有在指定范围内的画面才可能被更新。

制作应用程序

现在我们想利用低级api来制作应用程序。在上一讲中,我们讲述如何利用高级api来制作计算器的应用程序,在本讲中我们再讲述一下如何利用低级api来制作计算器的应用程序。

♦ 3-1 计算器应用程序的设计

本讲中所讲的计算器应用程序就是在按键上输入数字和运算符号。所以有必要获取按键事件。

如下是应用程序的类结构。

   • n800calculator2 (midlet main class)
   • calculatorcanvas (actual screen)

如下是画面结构:

   • title screen
   • calculator screen

主题画面中无论按住哪一个键,都会转至计算器的画面。

♦ 3-2 介绍状态变量

在本讲的应用程序中有主题画面和计算器画面。主题画面中无论按哪一个键,都会转至计算器的画面。在计算器画面中,用按键输入数字和运算符号进行计算,在屏幕中显示出结果。由于要将主题画面和计算器画面的不同的功能都在同一画面中管理,所以在本讲中的应用程序,使用表示现在画面的状态的状态变量。

状态变量在calculatorcanvas类中有以下定义。

     private final int state_title = 0; //主题画面
     private final int state_main = 1; //计算器画面
     private int state; //状态

code example 4

在状态变量state中用calculatorcanvas类定义了state_title,state_main的2个常量。 由if语句判断应用程序的状态,如下所示:

     if(state == state_title){// 主题画面
        记述处理
     }else if(state==state_main){// 计算器画面
        记述处理
     }

code example 5

而且,即使是正在进行计算器画面表示时,其中仍会有状态。

计算器在开始的显示画面中显示为[0]。然后输入数字[3],屏幕中就会出现[3],再输入数字[4]屏幕上显示出[34]。再输入[5]后就成了[345]了。继续键入数字后,数字文字列就会突然终止,这些情况我们应该是知道的。但是,第一次按[+]后在输入数字[6],则在显示屏中并不显示成[3456],而只表示成[6]。

   • 持续输入数字,到一定程度就会出现键入终止,所以必须先清除这些数字,之后再键入新的数字。
   • 前者是数字的连续键入中,后者是运算符号的选择后,其他是所表示的数字是[0]的时候。

为能实现这样的处理,本讲中的应用程序就要使用名为clearflag的boolean型变数。输入运算符号后直接将clearflag变为true。输入数字时要检查clearflag,true的话,清除表示中的数字表示所输入的数值。而false,则要终止表示数字的数字文字列。

//输入数字时的处理
if (keycode >= 48 && keycode <= 57) {
    if (clearflag) {
        numstring = "";
    if (keycode == 48) {
        clearflag = true;
    } else {
        clearflag = false;
        }
    }
    numstring += getkeyname(keycode);
}

code example 6

♦ 3-3 制作各个画面

依次制作主题画面、计算器画面。

描绘处理是关键,在calculatorcanvas的paint方法中进行处理。

♦ 3-3-1 描绘画面背景

用如下的pait方法去实现背景颜色的设置:

    // //设定背景
    g.setcolor(237, 237, 211);
    g.fillrect(0, 0, getwidth(), getheight());

code example 7

♦ 3-3-2 制作主题画面

在主画面上显示图片和提示信息"press any key",代码如下:(图8)

if(state == state_title){

    //表示主题画面
    g.drawimage(titleimg, 0, 0, graphics.left | graphics.top);

    //表示信息
    g.setcolor(0, 0, 0);
    g.drawstring("press any key!!",30,140,graphics.left | graphics.top);
}

code example 8

使用低级ui制作图解应用程序(图八)

figure 8

♦ 3-3-3 制作计算器画面

下面要讲的就是我们所需要的计算器画面了。能够显示出表示计算结果的显示屏和输入数字和运算符号的按键。

if(state==state_main){//当是计算屏幕时

    //显示图片
    g.drawimage(keyimg, 0, 35, graphics.left | graphics.top);

    // 显示数字
    g.setcolor(0, 0, 0);
    g.drawrect(11, 10, 140, 20);
    g.setcolor(255, 255, 255);
    g.fillrect(11, 10, 140, 20);

    // 写数字
    g.setcolor(0, 0, 0);
    g.drawstring(numstring, 150, 30, graphics.right | graphics.bottom);

    // 写操作
    g.drawstring(operatorstring,160,35,graphics.right | graphics.bottom);
}

code example 9

在本讲中准备了表示按键 配置的画像,目的是让用户知道每个图片按钮的功能对应的相应按键。用drawimage方式在空白处描绘出按键的画像。 另外,在数字的描绘、运算符号的描绘中使用变量(分别numstring,operatorstring)。按住按键时就会改变这些变量,也会反映在画面中。

使用低级ui制作图解应用程序(图九)

figure 9

♦ 3-4 实现事件处理

♦ 3-4-1 命令事件

为了要结束应用程序和初始化计算器的数值,要使用命令事件。

if (command == clear) { // 当清除命令时

    //初始化
    tmp = 0;
    numstring = "0";
    operatorstring = "";
    clearflag = true;
    repaint();
}
if (command == exit) { // 当停止命令时

    // 停止执行
    try {
        ((n800calculator2) midlet).destroyapp(true);
        } catch (exception e) {
    }
    ((n800calculator2) midlet).notifydestroyed();
}

code example 10

按exit命令后就会结束应用程序。调用n800calculator2类(应用程序的主类)的destroyapp方法去实现这个功能。

♦ 3-4-2 按键事件

在主题画面中按键事件发生后,无论按哪个键都会转到计算器画面。在计算器画面中,按数字键就可以更新画面上的数字,按方向键上的运算符号后可以进行计算,并且再一次更新画面。

public void keypressed(int keycode) {

    // 根据状态去选择
    if (state == state_title) {// 显示title

    // change the state
        state = state_main;
    } else { // 主画面

        switch (getgameaction(keycode)) {
            case canvas.down : //除
                calculate();
                operator = 3;
                operatorstring = "/";
                clearflag = true;
                break;
            case canvas.up : // 乘
                calculate();
                operator = 2;
                operatorstring = "*";
                clearflag = true;
                break;
            case canvas.left : // 加
                calculate();
                operator = 0;
                operatorstring = "+";
                clearflag = true;
                break;
            case canvas.right : // 减
                calculate();
                operator = 1;
                operatorstring = "-";
                clearflag = true;
                break;
            case canvas.fire :
                calculate();
                operator = 4;
                operatorstring = "";
                clearflag = true;
                break;
                default :
                break;
        }
    }

//值得清除
if (keycode >= 48 && keycode <= 57) {
    if (clearflag) {

        numstring = "";//清空值
            if (keycode == 48) {
                clearflag = true;
            } else {
                clearflag = false;
            }
        }
    numstring += getkeyname(keycode);
    }
    repaint();
}

code example 11

发生按键事件后会有画面显示的变化,因此要更新画面。在这些方法的最后调用repaint方法,进行画面的再描绘。

♦ 3-5 计算器的计算处理

用calculate方法处理计算逻辑。这个方法根据运算符号进行计算,运算结果的数字用numstring字符串显示出来。

public void calculate() {
    try {
        int num = integer.parseint(numstring); // gets entered value

        // and performs calculation
        switch (operator) {
            case 0 : // 加法
                tmp = tmp + num;
                break;
            case 1 : // 减法
                tmp = tmp - num;
                break;
            case 2 : //乘法
                tmp = tmp * num;
                break;
            case 3 : // 除法
                tmp = tmp / num;
                break;
            default : // when "=" is selected
                tmp = num; //照原样输入所输入的数值
                break;
        }
    } catch (exception e) {//发生异常时
        tmp = 0;
        e.printstacktrace();
    }
    numstring = string.valueof(tmp);
}

code example 12

♦ 3-6 完成

如下是完成后的源码。 (n800calculator2.zip)

在此范例程序中,为要清楚结构,只实际实现了有限的功能。以此为基础,可以进行制作真正计算器程序的挑战。

♦ 3-7 执行计算器程序

下面我们来执行已经制作完成的程序。

使用低级ui制作图解应用程序(图八) 使用低级ui制作图解应用程序(图九)
1.主题画面 2.计算器画面
使用低级ui制作图解应用程序(图十) 使用低级ui制作图解应用程序(图十)
3.输入[234]4.输入[+]
使用低级ui制作图解应用程序(图十) 使用低级ui制作图解应用程序(图十二)
5.输入[356]后再输入[=],显示出结果6.选择命令清除键,清除数值

♦ 总结

在本讲的讲述中我们了解到利用低级api能够开发应用程序。由于使用的是低级api,所以能够在画面上进行各种各样的描绘,因此,我们制作应用程序的范围又加大了。我们在第2讲、第3讲中一并介绍了创建用户接口api的问题。在下一讲中,我们将主要介绍利用时间类制作含有动画的应用程序。

向n800中传送应用程序

到本讲为止,制作完应用程序后在模拟器上进行执行确认。但是我们并没有在n800的实际机器上进行测试。因此,使用传送工具从pc向n800传送midlet应用程序。下面讲一下实际的操作方法。

顺序如下所示

1.编码
2.制作jar文件
3.制作jad文件
4.使用传送工具传送
5.   真机操作

1. 编译

使用「nec n800/n810/e530 application emulator」将制作完成的java程序进行编译。

2. 制作jar文件

下面我们来制作jar文件。在模拟器上进行操作确认也几乎没有什么变化。若不能顺利传送时,为了要在真机操作必须在参数「midlet-description」的输入平台上的「midlet list」中重新记述「midlet-description」。(图10)

使用低级ui制作图解应用程序(图十三)
figure 10
3.制作jad文件
以下介绍怎样制作jad文件。参数的设定没必要特意更改模拟器上的test时。(图11)
使用低级ui制作图解应用程序(图十四)
figure 11
4. 现在我们讲述使用传送工具进行传送的内容。
将n800和pc用数据线连接。随后就会出现「java tool」。在「jad file」平台上设定jad文件的路径,而在「jar file」平台上设定jar文件。于是,调试pc与真机相连的部分,在「portnum」平台上设定端口号。按「writefile」键,显示出传送完成则表示已经成功了。(图12)
未传送成功的情况下,请尝试修改端口号。
使用低级ui制作图解应用程序(图十五)
figure 12
5.真机操作
传送完成之后就要进行真机操作了。插入电源,在“百宝箱”菜单中用上次传送的应用程序名(midlet-name)设定名字。在上述情况下,加上n800calculator2)的话,就会传送成功。一旦jar文件和jad文件不同,就会出现下载失败的信息。特别是,记述jad文件时千万不要忘记设定「midlet-description」。一旦必须输入参数不足,则会出现下载错误。
 
 
上一篇: 如何制作动画程序    下一篇: 使用高级ui制作简单计算程序
  相关文档
effective java学习笔记7:改写equals的时候遵守约定 11-17
信息系统中用java访问sqlserver 11-16
用javamail显示复合邮件的内容 11-16
使用数组 11-16
java 关于中文乱码问题的解决方案与经验 (2) 11-17
深入理解:全面认识java 11-17
使用jwsdp完成web service在java的入门(四) 11-17
用java实现html文件代替数据库存储数据 11-16
sun力推jds数据库计划 开拓数据库疆土 11-17
java文萃:世界各地开发高手谈java(下) 11-16
ejb3.0开发指南之实体bean的继承 11-16
易混淆的几个java术语(转贴) 11-17
isrootfolder 属性 11-16
java进阶--详细解读hibernate包的作用 11-16
jdbc2.0扩展api(1) 11-17
vector还是arraylist这是个问题 11-17
java中类似于c语言中sizeof功能实现(二) 11-17
j2ee综合--java语言不一定就跨平台 03-03
最大化j2ee和数据库交互操作的性能 11-16
java中使用directdraw 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息