第5章低级用户界面.ppt

上传人:本田雅阁 文档编号:3430892 上传时间:2019-08-24 格式:PPT 页数:88 大小:1.52MB
返回 下载 相关 举报
第5章低级用户界面.ppt_第1页
第1页 / 共88页
第5章低级用户界面.ppt_第2页
第2页 / 共88页
第5章低级用户界面.ppt_第3页
第3页 / 共88页
第5章低级用户界面.ppt_第4页
第4页 / 共88页
第5章低级用户界面.ppt_第5页
第5页 / 共88页
点击查看更多>>
资源描述

《第5章低级用户界面.ppt》由会员分享,可在线阅读,更多相关《第5章低级用户界面.ppt(88页珍藏版)》请在三一文库上搜索。

1、Displayable的子类可以充满整个界面,其直接子类有两个: Screen:提供高级界面开发,界面效果都是由控件组成的; Canvas:提供低级界面开发, 界面效果都是通过编程,在画布上画出来的。,低级用户界面,本章授课内容,低级用户界面简介 Canvas类 Graphics类,低级用户界面,低级API包括两个部分: Canvas类:画布类,在其上可以进行图形操作,同时它也是低级事件的接收者; Graphics类:绘图类,可以用来提供文本和图像,并且能够实现绘制和填充图形。,低级用户界面,Canvas和Graphics关系图,Canvas类,Canvas 组件表示屏幕上一个空白矩形区域,应

2、用程序可以在该区域内绘图,或者可以从该区域捕获用户的输入事件。,Canvas类,public abstract class Canvas extends Displayable 应用程序必须为 Canvas 类创建子类,以获得有用的功能(如创建自定义组件)。 Canvas类中定义了一个抽象方法paint(), 它是Canvas最核心的方法,Canvas所有的子类都必须实现它。,在Canvas类中,有如下重要成员方法: 1: protected abstract void paint(Graphics g) 该方法是抽象方法,如果扩展了Canvas类,就必须对paint方法进行重写。 该方法指定

3、了如何在屏幕上绘制自定义图形,该函数里面可以包含画图的代码。 注意,该方法是在界面出现时自动调用的!,Canvas类,Canvas类,综上所述,画布开发的基本结构如下:,public class MIDlet1 extends MIDlet /画布类 class MyCanvas extends Canvas public void paint(Graphics g) /在画布上画图 private MyCanvas mc = new MyCanvas(); private Display dis; protected void startApp() throws MIDletStateCha

4、ngeException dis = Display.getDisplay(this); dis.setCurrent(mc); /其他代码 ,public final void repaint(int x, int y, int width, int height):重绘屏幕上指定的区域。 其中参数x和y是该矩形左上角的坐标,参数width和height分别指定了该矩形的宽度和高度。 public final void repaint():重绘整个屏幕。相当于:repaint(0, 0,getWidth(), getHeight(),Canvas类,Canvas类,注意: 这个方法是异步的,

5、即在repaint()方法执行后,paint()方法也可能不会立即被调用。 repaint()方法的发出者必须是当前显示的Canvas对象,否则任何重绘命令都是没有意义的。,Canvas类,public final void serviceRepaints() 另一个实现重绘的方法,该方法强制要求执行当前所有的重绘请求,并堵塞当前线程,直到重绘请求被执行。 如果当前没有任何重绘请求,该方法会被忽略掉,不过,这个方法一定要小心使用,必须保证在当前情况下不会因为paint()方法中的资源被占用而引起死锁。,Canvas类,Display类中有个方法: public void callSeriall

6、y(Runnable r): 该方法实现paint()和repaint()方法同步。 在MIDP中,所有与用户界面有关的调用都是顺序执行的,如果同时发生,就会放到一个队列里,执行完一个再执行另一个,当Display的对象调用callSerially(Runnable r)时,会调用r内部的run()方法,但是该方法会等到队列中的其他调用都返回后才执行。,Canvas类,public void setFullScreenMode(boolean mode) 该函数可以设置画布是否以全屏幕显示。如果为true,则全屏幕显示,此时Title,Ticker以及Command都无法在屏幕上显示。,Can

7、vas类,protected void showNotify():这个方法是保护型的,可以被重写。这个方法在画布放在界面最前端显示时自动调用。 protected void hideNotify():这个方法是保护型的,可以被重写。这个方法在画布隐藏时自动调用。,Canvas类,设置画布的标题: public void setTitle(String s) 为画布设置滚动条: public void setTicker(Ticker ticker) 得到画布的宽度: public int getWidth() 得到画布的高度 public int getHeight(),用Canvas开发简单

8、画图系统,paint方法: protected abstract void paint(Graphics g) paint函数参数是一个Graphics对象 Graphics类定义如下: public class Graphics extends Object 它直接继承java.lang.Object类。,Graphics类,Graphics类提供简单的绘制功能,主要有以下三类: 绘制文本:可以使用设备所支持的字体绘制指定的字符串 绘制二维几何图形:可以绘制包括直线,矩形,圆弧等简单的二维几何图形。 绘制图像:可以从图像文件中绘制不可变图像,也可以从缓存中绘制可变图像。,不变图像:可被存储于

9、持久存储器,网络或者内存中,一旦生成就不能更改。 可变图像:只能存在于内存中,并且可对可变图像进行修改。,Graphics类一般不用构造函数来实例化其对象,获得Graphics对象有两个方法: 用paint()方法传入参数 用Image类中的getGraphics()方法 得到Graphics对象。,用Canvas开发简单画图系统,Graphics坐标,一般的数学坐标原点在左下角,x轴数值往右递增,y轴数值往上递增。,Graphics坐标,而手机开发中屏幕坐标原点在右上角,x轴数值往右递增,y轴数值往下递增,正好与传统坐标相反。,画笔对象的重要功能有: 用RGB组合的方法设置画笔颜色: pub

10、lic void setColor(int RGB) 该函数可以设置画笔的颜色,传入的参数是一个16进制数,用0xRRGGBB表示,每个分量为00-FF之间。,设置画笔颜色,用RGB分量方法设置画笔颜色: public void setColor(int red, int green, int blue) 该函数传入红色、绿色和蓝色分量,值皆为0-255之间。,设置画笔颜色,获取画笔颜色分量,得到红色分量: public int getRedComponent() 得到绿色分量: public int getGreenComponent() 得到蓝色分量: public int getBlue

11、Component(),设置画笔线型,public void setStrokeStyle(int style) 该函数能够设置画线的线型,其参数可有两种选择: Graphics.SOLID:实线; Graphics.DOTTED:虚线。 public int getStrokeStyle():获取线型,用Canvas开发简单画图系统,Graphics常见的画图函数: 1:画线: public void drawLine(int x1, int y1, int x2, int y2) 该函数从坐标(x1,y1)到(x2,y2)画一条线。 界面上左上角的坐标为(0,0),越往右X越大,越往下Y越

12、大。,用Canvas开发简单画图系统,2:画矩形: public void drawRect(int x, int y, int width, int height) 该函数以(x,y)为左上角坐标,width为宽度,height为高度画一个矩形。,用Canvas开发简单画图系统,3:画圆角矩形: public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) 该函数画一个圆角矩形,以(x,y)为左上角坐标,width为宽度,height为高度,arcWidth为圆角水平直径

13、,arcHeight为圆角垂直直径。,用Canvas开发简单画图系统,arcWidth 为圆角水平直径,arcHeight 为圆角垂直直径。,arcHeight,arcWidth,4:画圆弧(椭圆弧): public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) 该函数画一段圆弧,在画图系统中,任何的圆或椭圆都可以包含在一个矩形内,因此,确定了矩形,就确定了圆弧。该函数中,圆弧所在的矩形以(x,y)为左上角坐标,width为宽度,height为高度,以startAngle为开始的角

14、度,arcAngle为画出的角度。注意,在圆形画图过程中,从中心水平向右表示0度,逆时针为正方向。,用Canvas开发简单画图系统,5:绘制填充矩形: void fillRect(int x, int y, int width, int height) 该函数从坐标(x,y)开始画一个长width,宽height.的实心矩形。 6:填充圆角方框 public void fillRoundRect(int x, int y, int width,int height,int arcWidth, int arcHeight),用Canvas开发简单画图系统,7:填充椭圆 public void f

15、illArc(int x, int y, int width, int height, int startAngle, int arcAngle) 8:填充三角型 public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3),用Canvas开发简单画图系统,上节课回顾,低级用户界面简介 Canvas类 setFullScreenMode(boolean mode): 该函数可以设置画布是否以全屏幕显示。 protected void showNotify():在画布放在界面最前端显示时自动调用。 protect

16、ed void hideNotify():在画布隐藏时自动调用。,上节课回顾,paint()方法:包含画图的代码,界面出现时自动调用。 重画的三种方法: repaint():调用paint()方法,异步方法。 serviceRepaints():堵塞当前线程,使repaint和paint同步。 callSerially(Runnable r):实现paint()和repaint()方法同步。等到队列中的其他调用都返回后才执行。Display类的方法。,上节课回顾,用Canvas开发简单画图系统: Graphics类 设置颜色:setColor() 设置线型:setStrokeStyle(int

17、 style) 二维图形的绘制:画线,画矩形,画圆角矩形,画圆弧,绘制字符串,字体的设置,本节课内容,文字绘制和Font类 图形的剪裁 图形的卷动设计 图像处理,文字绘制,Graphics类中提供了多个方法绘制文本。 drawString() drawChar() drawChars() drawSubstring(),文字绘制,绘制指定字符 void drawChar(char character,int x,int y,int anchor) 绘制指定字符数组 void drawChars(char character, int offset,int len,int x,int y,int

18、 anchor) 绘制字符串子串 void drawSubstring(String str,int offset,int len,int x,int y,int anchor) str是制定绘制的字符串文本,offset制定子字符串的起始位置,len指定子字符串的长度。,绘制字符串: void drawString(String str, int x, int y, int anchor) 参数 1 是字符串的内容,如“中国人”; 参数 2 和参数3 是参考点在屏幕上的坐标(x,y),注意,不是左上角在屏幕上的坐标(x,y)! 因为参考点不一定是左上角的那个点!参考点到底确定为哪一点呢?由第

19、四个参数决定。第四个参数由两个值合成,这两个值之间用“|”隔开。其中一个值表示水平方向,另一个值表示垂直方向。,文字绘制,画笔之字符串绘制,由于字符串本身显示就占有一定的屏幕控件,占用的空间是个矩形的空间。anchor的作用就是设置字符串占用屏幕的矩形方块哪个部分的坐标。,字符串占用空间,表示水平方向的值通常可以在以下内容中选择: 1:Graphics.LEFT:锚点位于文本或图像的左方 2:Graphics.HCENTER:锚点位于文本或图像的水平中央 3:Graphics.RIGHT:锚点位于文本或图像的右方 表示垂直方向的值,可以选择: 1:Graphics.BOTTOM:锚点位于文本或

20、图像的下部 2:Graphics.TOP:锚点位于文本或图像的上部 3:Graphics.BASELINE:锚点位于文本的基线 根据定义,锚点的值必须有水平常量和垂直常量组合表示。,画笔之字符串绘制,画笔之字符串绘制,画笔之字符串绘制,举例:g.drawString(“字符串”, 40, 40, Graphics.TOP|Graphics.LEFT) Graphics.TOP|Graphics.LEFT的含义是表示“字符串”这3个字符占用的矩形框的左上角位于坐标(40,40)的位置。,画笔之字符串绘制,如果anchor设置为Graphics.BOTTOM|Graphics.LEFT,画笔之字符

21、串绘制,开发手机程序的过程中,经常需要使图片或者字符串在屏幕上居中显示,那么如何处理呢? Canvas类提供了获得屏幕宽度和高度的函数,获得屏幕宽度的函数是getWidth(),获得屏幕高度的函数是getHeight()。,画笔之字符串绘制,使用以下语句可以显示居中的字符串:,g.drawString(“字符串“, this.getWidth()/2, this.getHeight()/2,Graphics.BOTTOM|Graphics.HCENTER);,画笔之字体设置-Font类,Graphics 中还提供了对字体的控制方法,每个Graphics都有一个Font对象与其关联,来进行文字的

22、渲染操作。 设置字体: public void setFont(Font font) 可以调用其类方法setFont(null),即可使字体恢复到默认状态。,画笔之字体设置,得到字体对象: static Font getFont(int face,int Style,int size):获得一个对象以表示字体所具有指定的外观,样式和大小。 其中: face参数,用来定义字体的外观。 Style参数,用来定义字体的样式。Font类定义的样式参数。 size参数,定义字体大小。Font类定义的字号大小常数。,画笔之字体设置,例:,Font fnt=Font.getFont(Font.FACE_SY

23、STEM, Font.STYLE_BOLD, Font.SIZE_LARGE); g.setFont(fnt); g.drawString(“好好学习“,80, 80,Graphics.LEFT|Graphics.BOTTOM);,画笔之字体设置,得到字体对象有一个重要作用就是可以得知每个字的宽度和高度,Font有以下方法: 得到字符高度: public int getHeight() 得到字符宽度: public int charWidth(char ch) public int charsWidth(char ch, int offset, int length),画笔之字体设置,通过如下

24、方法得到字符串所占宽度: public int stringWidth(String str) 获取字符子串所占宽度: public int substringWidth(String str, int offset, int len),画笔之字体设置,举例:,图形剪裁,在某些情况下可能需要在Canvas中设置一个工作区域,或者只想把绘制内容放到Canvas的一个小区域中。Graphics类提供了一个这样的区域,称为裁剪区域。 绘图操作中涉及的像素落到该区域内都可以进行操作,如果落到该区域之外,即使程序对其进行操作,它也不受影响。 当屏幕重画的时候,可以保证屏幕其他部分的内容不必重画,而仅仅重

25、画需要更新的部分内容。,图形剪裁,该区域是个矩形区域,通常使用(x,y,w,h)的形式来表示,其中,x,y表示该区域的左上角坐标,w,h表示这个矩形的宽度和高度。 public void setClip(int x, int y, int width, int height):定义剪裁区域。,图形剪裁,public int getClipX():获取剪裁区域中相对于绘图环境中坐标原点的X轴坐标。 public int getClipY():获取剪裁区域中相对于绘图环境中坐标原点的Y轴坐标。 public int getClipHeight():获取当前剪裁区域的宽度。 public int g

26、etClipWidth():获取当前剪裁区域的高度。,图形剪裁,一般使用了裁减函数以后,应该恢复到原来的裁剪区域。 如下代码所示: int oldClipX = g.getClipX(); int oldClipY = g.getClipY(); int oldClipWidth = g.getClipWidth(); int oldClipHeight = g.getClipHeight(); /设置新裁减区域的大小 g.setClip(0,0,this.getWidth()/2,this.getHeight()/2); 。/执行画图操作 / 恢复原来的画布裁剪区域的信息 g.setClip

27、(oldClipX, oldClipY, oldClipWidth, oldClipHeight);,Graphics类的卷动设计,public void translate(int x, int y):该函数将原坐标系的(x,y)作为新坐标系的原点。如果想恢复原坐标系,则调用translate(-x,-y);,Graphics类的卷动设计,已经转换的坐标原点可以用如下方法查看: public int getTranslateX() public int getTranslateY() 这两个方法返回的坐标值与当前坐标系无关,其返回值是默认坐标系。,图像处理,Graphics对象除了用来绘制简

28、单的二维几何图形和文本之外,还可以绘制图像,这些图像可以来自网络或者本地图像文件。 Graphics 只是负责将图像显示在屏幕上,实际的图像处理都是通过Image类实现。Image对象的存在与屏幕设备完全独立,它存在于设备的存储器中,通过Graphics中的方法或者高级屏幕界面组件如ImageItem等显示到屏幕上。,图像处理,Image类是被设计成存储图像数据的类,一旦创建了一个Image对象,它们将把存储图像数据放在内存中,并不会显示在屏幕上,只要当Graphics对象使用绘图函数绘制Image对象的时候,图片才会显示在屏幕上。,Image类的分类,Image类分为可变和不可变两种类型。

29、不可变的Image对象:是从资源文件,二进制数据,网络资源,RGB数值及其他Image直接创建的,一旦读取数据,创建完成,Image对象就无法再变化。 可变的Image对象:是一个在内存中存储的对象,可以在内存中修改图像数据以后再显示出来的对象,由于一切操作都在内存中进行,并没有显示在屏幕上,所以称为可变对象。,Image类的创建,Image对象的生成是使用Image类中的系列静态方法createImage()生成对象。 不可变图像对象的创建 可变图像对象的创建,不可变图像对象的创建,创建不可变图像对象的方法有好几个,如下所示: 从一个指定名称的源图象文件中创建一个不可改变的图象。 publi

30、c static Image createImage(String name) throws IOException 参数说明: name :源图像文件路径,注意参数中的字符串必须以”/”打头。,不可变图像对象的创建,从一个字节数组存储中创建一个不可变图象 public static Image createImage(byte imageData, int imageOffset, int imageLength) 参数说明: imageData :图像字节数组 imageOffset: 起始数据位置 imageLength :数据的长度,不可变图像对象的创建,从二进制数据流中创建一个不可变

31、图象。 public static Image createImage(java.io.InputStream stream) throws java.io.IOException 参数说明: stream :包含图象数据字节流,不可变图像对象的创建,从一个Image对象创建另一个Image对象,并可以旋转。 public static Image createImage(Image image, int x, int y,int width,int height, int transform) 参数说明: x,y是图像左上角的坐标 width和height是图像的宽度和高度 transfor

32、m是图像旋转的角度,不可变图像对象的创建,旋转的角度,有如下可选: 1:Sprite.TRANS_NONE:不旋转 2:Sprite.TRANS_ROT90:旋转90度 3:Sprite.TRANS_ROT180:旋转180度 4:Sprite.TRANS_ROT270:旋转270度,5:Sprite.TRANS_MIRROR:镜像 6:Sprite.TRANS_MIRROR_ROT90:镜像,然后旋转90度 7:Sprite.TRANS_MIRROR_ROT180:镜像,然后旋转180度 8:Sprite.TRANS_MIRROR_ROT270:镜像,然后旋转270度,不可变图像对象的创建,

33、可变图像对象的创建,可变的Image对象其实就是一个在内存中存储的对象,可以在内存中修改图像数据以后再显示出来的对象,由于一切操作都在内存中进行,并没有显示在屏幕上,所以称为可变对象。,可变图像对象的创建,创建一个可变的Image对象,使用到的createImage构造函数如下所示: public static Image createImage(int width,int height),其中参数width,height表示所创建的图像的大小,其值必须大于0,否则会抛出异常。,可变图像对象的创建,创建可变图像后经常都需要提取该图像的Graphics对象,以便对可变图像进行修改。,示例: Im

34、age img=Image.createImage(100,100); /创建可变图像 Graphics graphics=img.getGraphics(); /获取可变图像的Graphics对象 graphics.fillArc(10,10,60,50,180,180);/绘图,可变图像对象的创建,将一个图像对象转化成不可变图像: public static Image createImage( Image source ) 参数说明: source 源图像 备注: 此方法一般用于将可变图像转化为不可变图像,但是不可变图像不能转化成可变图像。,画笔之图形绘制,Graphics中绘制图片:

35、void drawImage(Image img, int x, int y, int anchor) 该函数第一个参数是图片对象,第二个参数和第三个参数是参考点的坐标(x,y),参考点由第四个参数决定,类似字符串的绘制,注意:没有BASELINE常量,新增了VCENTER常量。,在Graphics类中,还有一个函数也可以画图片:,在画图系统中画图片,在画图系统中画图片,参数1表示图片对象; 参数2到5表示在图片上取一个矩形块,左上角坐标为(x_src,y_src),宽度为width,高度为height; 参数6表示将这个矩形块画到画布上的时候,进行旋转的角度。 参数7和8表示将矩形块画到画布

36、上,矩形块上参考点的位置,参考点由最后一个参数确定。,在画图系统中画图片,例如:有一副图片,我们将其上一半切下来画在界面上,左上角位置(0,0)。,案例: RotateImageMIDlet.java,图像双缓冲技术,图像双缓冲技术:先把屏幕画在缓冲之中,然后再绘制在显示屏上,而不是直接绘制在显示屏上。 某些设备支持双缓冲,可使用Canvas类的isDoubleBuffered()方法事先判断设备是否支持双缓冲。 对于本身不支持双缓冲的设备,可以使用可变图像复制不可变图像的方法实现类似双缓冲的效果。,图像双缓冲技术,Step1:声明一个可变图像,并初始化这个图像 Step2:获得访问可变图像的

37、Graphics对象 Step3:Graphics对象绘图 Step4:释放缓冲区的Graphics对象,将其置为null Step5:paint方法中将缓冲区的内容绘制到屏幕上。注意:是绘制可变图像的对象。,图像双缓冲技术,一个可变的Image对象可以复制一个不可变的对象,然后绘画出来,代码如下所示: Image source; /源Image不可变对象 source = Image.createImage(.); Image copy=Image.createImage(source.getWidth(),source.getHeight(); Graphics g = copy.getG

38、raphics();/获得相应Graphics对象 g.drawImage(source,0,0,TOP|LEFT); 用完后注意手动将Graphics对象设置为null. 课本: 175页案例!BufferDrawExample.java,实验分析,实现一个时钟实例主要涉及到以下几个技术特点: (1)如何获得当地时间 (2)如何绘画时钟的分针和时针 (3)如何控制时钟的分针和时针移动的速度,获得当地时间,java.util.Calendar类是J2ME标准库提供的日历工具类。 创建一个Calendar对象: Calendar calendar=Calendar.getInstance();

39、在Calendar类中把日期分成年、月、日、时、分、秒、微秒、星期八个部分,每一个部分又有一个或多个静态常量与之对应。 calendar=Calendar.getInstance(TimeZone.getTimeZone(“GMT+8:00“);,Calendar类里面提供了多个成员函数,但是最重要的2个函数如下所示: 这两个函数的field变量的值是上面表格中的, MONTH, DATE, DAY_OF_WEEK, HOUR_OF_DAY, HOUR, AM_PM, MINUTE, SECOND,和 MILLISECOND,通过这些field变量,可以获得需要的时间数据。,获得当地时间,例如

40、,获得当天时间的所在年份的具体代码如下所示:,获得当地时间,时分秒指针的移动,秒针移动的角度(6度): angle = (2/360 )*second*6 =*second/30 假设圆心的位置的坐标是(cx,cy),变量ls为绘制秒针的直线的长度,则直线的另外一个点的坐标如下所示: sx=cx+ls*SIN(angle) sy=cy-ls*COS(angle),用程序实现这几个数学式子的代码如下所示: 分钟的移动角度和秒种的移动角度式一致的,也是每次移动*second/30度。,时分秒指针的移动,时钟的移动角度略有不同, 时针、分针、秒针的动画显示速度使用线程的sleep函数来控制,每隔1秒的时间请求重画一次屏幕,并计算新的坐标。,时分秒指针的移动,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1