正文

[转]第4章  MIDP低级UI的使用12006-08-05 08:59:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/sword2008/17268.html

分享到:

4.1    低级API与低级事件的联系

4.2    重绘事件及Graphics入门

4.2.1     坐标概念

4.2.2     颜色操作

4.2.3     绘图操作

4.3    Canvas与屏幕事件处理

4.4    键盘及触控屏幕事件的处理

4.5    Graphics相关类

4.5.1     Image

4.5.2     字体类

 


 

我们从javax.microedition.lcdui.Canvas开始了解我们的低级UI,我们要用到低级UI必须要继承Canvas这个抽象类,在 Canvas的核心是paint()这个方法,这个方法做是负责绘制屏幕上的画面,每当屏幕需要重新绘制时,就会产生重绘事件时,系统就会自动调用paint(),并传入一个Graphics对象。

 

任何时候我们都可以通过调用reapaint()方法来产生重绘事件,它有两个方法,一个需要四个参数,分别用来指示起始坐标(X,Y,长宽,另一个则不需要任何参数,代表整个画面重新绘制。

 

我们可以通过getWidth()getHeight() 方法获得Canvas的当前范围大小。每当Canvas 范围大小发生变化时,就会自动调用Canvas类的 sizeChanged()方法。

 

在低级UI里,我们可以直接把Graphics渲染到屏幕上,也可以在屏幕外合成到一个 Image中,已渲染的图形具体是合成Image还是显示到屏幕上,要看这个Graphics具体的来源而定,而渲染到屏幕上的Graphics对象将被送到paint()方法中来进行调度,这也是显示在屏幕上的唯一的途径,仅在paint()方法的执行期间这个应用程序可以对Graphics进行操作,至于要渲染到Image中的Graphics对象,当需要调用它的时候,可以通过Image.getGraphics()方法来取得相应的Graphics,它将可以被应用程序一直占有,在paint()方法运作的任何时候渲染到屏幕上,这也为我们在对不支持DoubleBuffered的手机开发提供了一些思路,可以通过Image来自行设计双缓冲区,避免图像出现所谓的撕裂现象。

         

4.1    低级API与低级事件的联系

与高级UI相比,低级UI就自由很多,任何时候我们可以调用repaint()产生重绘事件,调用完了repaint()会立刻返回,调用paint()回调函数则是由另一个专门的线程来完成。

 

底层事件大致可分为三类:Press Events(按键事件)Action Keys(动作按键,PointerEvents(触控事件)。

 

本节我们将围绕这三个主题来介绍一下这种事件的用法:

 

按键事件的几个核心方法为:keyPressed(),keyReleased(),keyRepeated(),当按键按下时会触发keyPressed(),当松开按键时,会触发keyReleased(),当长时间按住按键时会触发keyRepeated(),但是RepeatEvents不是JTWI要求强制支持的,所以使用之前要进行测试,看设备是否支持。在Canvas里面我们每按下一个按键都会触发keyPressed()函数,并传入相应位置的整数值,我们在MIDP规范中可以很容易的发现,KEY_NUM0——KEY——NUM9十个常数分别代表键盘上的0-9,还有两个功能键,KEY_STAR,KEY_POUND,如果我们传入的值小于0,代表我们传入了不合法的keycode,某些机器上还支持连续按键响应,但这并不是JTWI规定要支持的,所以我们在进行实际开发之前一定要用我们前面讲到的hasRepeatEvents()方法来进行判定。

 

动作按键主要针对游戏来设计的,在API中定义了一系列的动作事件:UP,DOWN,LEFT,RIGHT,GAME_A,GAME_B,GAME_C,GAME_D,当按下这些按键时会映射到我们自己为每个按键事件编写的方法,来完成一些动作。不过我们在MIDP2.0里我们已经有专门的游戏开发包了,所以我在这里就不重点介绍了。

 

触控事件主要面向高端设备,并非JTWI要求强制支持的,其核心方法为:pointerPressed(),pointerReleased(),pointerDragged(),分别对应我们通常所用的移动设备手写笔的点,击,拖拽几个动作,我们在这三个方法里可以定义相应的事件处理函数。在索爱P910C这样的高端手机上,支持屏幕的触控事件,我们在屏幕上点击,可以引发pointerPressed()函数,并传入当时位置的坐标,放开后,会引发pointerReleased()函数,同样也会传入坐标,具体的使用方法和keyPressed()以及keyReleased()大同小异,在后面的章节将会有对键盘及触控屏幕事件的详细叙述,同时大家可以参考一下WTK的说明文档获得比较详细的方法使用规则

 

4.2    重绘事件及Graphics入门

4.2.1   坐标概念

我们在MIDP程序设计中用到的坐标系和一般我们平时用到的坐标系不一样,可见下图:

 

 

这是我们在绘制图象时要注意的。

 

下面我们来讲一讲Graphics这个对象,我们可以把它当作一个白纸,只要调用这个方法,我们就可以运用自己的想象力在这张白纸上画出自己想要的图案。

 

4.2.2   颜色操作

我们可以在WTK的控制台看到下面这个程序运行以后显示其CanvasRGB值和灰度等参数,读者可以运行下面这个程序来获得对Graphics这个对象的初步了解。

下面我用一段简单的代码来说明一下这个Graphics对象的应用:

 

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

 

public class test extends Canvas

{

   public void paint(Graphics g)

   {

       g.setColor(255,255,0);

       g.fillRect(0,0,getWidth(),getHeight());

       int c=g.getColor();

       int dc=g.getDisplayColor(g.getColor());

       System.out.println("当前画面的颜色为:"+Integer.toHexString(c));

       System.out.println("当前画面的R值为:"+g.getRedComponent());

       System.out.println("当前画面的G值为:"+g.getGreenComponent());

       System.out.println("当前画面的B值为:"+g.getBlueComponent());

       System.out.println("当前画面的显示颜色为:"+Integer.toHexString(dc));

        System.out.println("当前画面的灰度为:"+g.getGrayScale());

   }

}

 

需要大家注意的是RGB的值只能在0——255之间,不可以超出这个范围,另外我们可以直接用0x00RRGGBB格式进行颜色的调配。

4.2.3   绘图操作

Graphics类提供的大量的绘图操作,这里给出了相关操作的方法列表供读者参考:

void

drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)

Draws the outline of a circular or elliptical arc covering the specified rectangle, using the current color and stroke style.

void

drawChar(char character, int x, int y, int anchor)

Draws the specified character using the current font and color.

void

drawChars(char[] data, int offset, int length, int x, int y, int anchor)

Draws the specified characters using the current font and color.

void

drawImage(Image img, int x, int y, int anchor)

Draws the specified image by using the anchor point.

void

drawLine(int x1, int y1, int x2, int y2)

Draws a line between the coordinates (x1,y1) and (x2,y2) using the current color and stroke style.

void

drawRect(int x, int y, int width, int height)

Draws the outline of the specified rectangle using the current color and stroke style.

void

drawRegion(Image src, int x_src, int y_src, int width, int height, int transform, int x_dest, int y_dest, int anchor)

Copies a region of the specified source image to a location within the destination, possibly transforming (rotating and reflecting) the image data using the chosen transform function.

void

drawRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height, boolean processAlpha)

Renders a series of device-independent RGB+transparency values in a specified region.

void

drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)

Draws the outline of the specified rounded corner rectangle using the current color and stroke style.

void

drawString(String str, int x, int y, int anchor)

Draws the specified String using the current font and color.

void

drawSubstring(String str, int offset, int len, int x, int y, int anchor)

Draws the specified String using the current font and color.

void

fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)

Fills a circular or elliptical arc covering the specified rectangle.

void

fillRect(int x, int y, int width, int height)

Fills the specified rectangle with the current color.

void

fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)

Fills the specified rounded corner rectangle with the current color.

void

fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3)

Fills the specified triangle will the current color.

主要是一组和绘画和填充的方法。请参考API的查看更多细节。

 

下面我们就来谈一谈如何用Graphics中线形的概念。如果我们需要绘制一条直线,我们可以调用drawLine()方法,需要定义其开始坐标和结束坐标,共四个参数,同时,Graphics提供两种形式的线条,一个是虚线,即Graphics.DOTTED,一个是实线,即Graphics.SOLID

 

同样我们给出一段代码供大家参考:

 

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

 

public class test2 extends Canvas

{

   public void paint(Graphics g)

   {

       g.setColor(255,255,255);

       g.fillRect(0,0,getWidth(),getHeight());

//在以后的实际开发当中会经常用到上面两行代码,它们的作用是进行画面的初

//

       g.setColor(255,0,0);

       g.drawLine(1,1,100,10);

       g.setStrokeStyle(Graphics.DOTTED);    //虚线

        g.setColor(125,125,125);

        g.drawLine(10,10,100,100);

        g.setStrokeStyle(Graphics.SOLID);      //实线

   }

}

 

用类似的方法,我们可以实现用GraphicsdrawRect()drawRoundRect()方法来绘制矩形和圆角矩形,我们也给出一段代码,让大家仔细观察一下两种矩形的区别:

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

public class test3 RectTestCanvas extends Canvas

{

        public void paint(Graphics g)

        {

                clear(g) ;

                g.setColor(255,0,0) ;

                g.drawRect(5,5,100,20);

                g.setColor(0,255,0) ;

                g.fillRect(5,30,100,20);//fillRect()drawRect()方法的区别在于一个填充

//一个不填充

                g.setColor(0,0,255) ;

                g.drawRoundRect(5,55,100,20,20,20);

                g.setColor(255,0,255) ;

                g.fillRoundRect(5,80,100,20,20,20);

        }

        public void clear(Graphics g)

        {

                //把屏幕清成白色

                g.setColor(255,255,255);

                g.fillRect(0,0,getWidth(),getHeight());

        }

}

}

 

 

4.3    Canvas与屏幕事件处理

Canvas本身有两种状态,一种是普通默认情况下的,一种是全屏状态,可以用setFullScreenMode()方法来对其设定,两者之间的区别在于当我们使用全屏幕状态的时候,TitleTicker以及我们的Command都无法在屏幕上显示。

 

当我们调用setFullScreenMode()的时候,不管是什么模式,都会调用seizeChanged()这个方法,并传入屏幕的高度和宽度作为其参数。

 

对于某些突发事件,比如说来电等等,屏幕会被系统画面所覆盖的时候,就会调用hideNotify()这个方法,当恢复原状时,就会调用我们原本的画面,那么系统就会同时调用showNotify()这个方法。在实际操作过程当中,应该覆写这两个方法,以便在可见性变化时,使程序做出相应的反应,Canvas会在它被显示的时候自动调用paint()方法,所以我们不必去调用repaint()方法。

 

 

 

阅读(2408) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册