分享
 
 
 

Java手机软件图形界面API之低级GUI组件

王朝java/jsp·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

在高级API编程时,你不能控制显示在屏幕上的内容,甚至用编程方式几乎无法控制这些组件。由系统实现体负责选取设备的最佳显示方式。然而,一些如游戏类的应用程序可能需要对屏幕绘制有更多的控制。

MIDP javax.microedition.lcdui包也提供了处理这类编程的低级API。

为了在屏幕直接绘制直线,文本和外形,你必须使用Canvas类。该类提供了一个MIDlet可以在其上绘制的空白屏幕。例如,在屏幕上绘制字符串"HelloWorld"。实现这个功能有一个简单的办法:子类化Canvas类(它是继续自Displayable的一个抽象类)并重载paint()方法。详见代码段1。

paint()方法的实现使用了javax.microedition.lcdui.Graphics类的绘图功能。在方法paint()中,绘图颜色置为红色,然后用红色画一个长方形。其中,方法getWidth( )和getHeight( )分别返回Canvas对象的宽度和高度。接下来setColor( )方法把绘图颜色设置为白色;之后,字符串"Hello World!"绘制在屏幕的左上角。

示例1:子类化Canvas

import javax.microedition.lcdui.*;

public class MyCanvas extends Canvas {

public void paint(Graphics g) {

g.setColor(255, 0, 0);

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

g.setColor(255, 255, 255);

g.drawString("Hello World!", 0, 0, g.TOP g.LEFT);

}

}

现在,为了观看MyCanvas,必须要把实例化后进行显示。既然Canvas是Displayable的一个子类,可以用与其它screen 类使用的同样的setCurrent( )方法来显示它。详见代码段2。

示例2:实例化和显示MyCanvas

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

public class MyMidlet extends MIDlet {

public MyMidlet( ) {}

public void startApp( ) {

Canvas canvas = new MyCanvas( );

Display display = Display.getDisplay(this);

display.setCurrent(canvas);

}

public void pauseApp( ) {}

public void destroyApp(boolean unconditional) {}

}

假如你在无线开发包提供的模拟器中运行,可能得到如图1所示的效果。注重在代码段5-1中,颜色被设置为红色与白色,但是既然使用了灰度级屏幕,这里的彩色就被映射到黑色和白色的不同的灰度级上。试着调整显示来观察哪一种设备的色彩显示更好些。

图1.在Canvas上绘制"Hello World!"

1. 绘图

坐标(0,0)代表了显示屏的左上角。X坐标的值是从左向右递增的,Y坐标的值是从顶向下递增的。应用程序应该一直检查绘图区的大小,这可以通过如下的类Canvas提供的方法实现:

public int getHeight( );

public int getWidth( );

这两个方法分别以像素值返回可显示区的高度和宽度。

所用的绘图模型是像素替换法--用在graphics对象中指定的当前像素值来代替目标像素值。一个24位的色彩模型由红,绿,蓝各8位(RGB)来提供。然而,由于并非所有的设备都支持彩色,应用程序中要求的颜色将被映射到设备中可用的颜色值上。但是,一个良好的应用程序,应该检查一个设备是否支持彩色-这可以用Display类的方法isColor()和numColors( )来完成。

Graphics类提供了方法setColor()和getColor( )来设置和取得颜色。但是,不象AWT/Swing,不存在方法setBackground( )和setForeground(),所以你必须显式地调用fillRect( )(见示例5-1)。Graphics类的大多数的另外一些方法是自解释的,与该类的AWT版本中的方法差不多。但是,我们还是要仔细地看一下其中的几个在环境J2ME下是如何工作的。

2. 双缓冲

双缓冲机制经常用来实现动画的平滑显示效果。在这种技术中,你不是在显示屏上绘图,而是绘制到显示屏的一个拷贝上(一个脱屏的缓冲区)-它是内存的一部分。当缓冲区绘制结束,你就可以把缓冲区内容拷贝到显示屏上。这里的基本原理是,直接拷贝内存内容到显示屏上要快于用原型绘制的速度。

要实现双缓冲,可以先生成一个其尺寸与屏幕一样的易变图像:

int width = getWidth( );

int height = getHeight( );

Image buffer = Image.createImage(width, height);

然后,取得缓冲区的图形上下文:

Graphics gc = buffer.getGraphics( );

现在,你可以在缓冲区中绘图了:

// animate

// ..

gc.drawRect(20, 20, 25, 30);

当需要把缓冲区拷贝到屏幕上时,你可以重载方法paint( )来把缓冲区内容绘制到设备显示屏上:

public void paint(Graphics g) {

g.drawImage(buffer, 0, 0, 0);

}

注重,一些MIDP实现中已经采用了双缓冲机制,因此这里的工作可能是不必要的。你可以使用Canvas的isDoubleBuffered( )方法来检查是否图形是双缓冲方式实现的。

3. 线程问题

MIDP GUI API是线程安全的。即是说,GUI API方法可以在任何时候从任何线程中调用。唯一的例外是Canvas类的serviceRepaints( )方法,它立即调用了paint( )方法以强迫显示的立即重绘。这是说,假如paint( )方法想在任何的应用程序调用serviceRepaints( )时已锁定的对象上同步,应用程序将会产生死锁。为了避免死锁,在使用了serviceRepaints( )方法时,请不要锁定将被paint()方法使用的对象。

另外,在所有未执行的重绘满足后,你可以使用Display类的方法callSerially( )来执行代码,如下所示:

class TestCanvas extends Canvas implements Runnable {

void doSomething( ) {

//代码段1

callSerially(this);

}

public void run( ) {

//代码段2

}

}

在此,对象的run( )方法在初始化结束后被调用。

4. 字体

应用程序不能自己产生字体。代之的是,应用程序应该要求基于一些属性(如大小,字体名称,字形)的一种字体,底层系统将试着返回一种与要求的字体最相近的字体。Font 类用来描述各种字体和尺寸。在Font 类中一共定义了三种字体属性,每一种属性取值不同,如下:

属性

取值

Face

MONOSPACE, PROPORTIONAL, SYSTEM

Size

SMALL, MEDIUM, LARGE

Style

BOLD, ITALIC, PLAIN, UNDERLINED

例如,要指定一种中等大小的字体,可以使用Font.SIZE_MEDIUM;用Font.STYLE_ITALIC来指定倾斜字形,等等。字形属性值可以用OR()操作符结合;另外一些属性值不能结合。例如:下面这种属性值指定了一种常规,带下划线的字体:

STYLE_PLAIN STYLE_UNDERLINED

而,下面是非法的组合:

SIZE_SMALL SIZE_MEDIUM

下面也是非法的:

FACE_SYSTEM FACE_MONOSPACE

系统中的每种字体实际上都是分别实现的,所以为了取得描述字体的对象,可以用getFont( )方法--该方法有三个参数,分别对应字体的字面,大小和字形。如,下面的代码以指定的字面,大小和字形属性得到一个Font对象:

Font font = Font.getFont(FACE_SYSTEM,STYLE_PLAIN, SIZE_MEDIUM);

假如没有相匹配的字体,系统将尽可能提供最相近的匹配-总是一个有效的字体对象。

一旦得到一种字体,你就可以使用Font类的方法来检索这种字体的信息。如,你可以用getFace(),getSize( )和getStyle( )方法来分别检索该字体的字面,大小和字形信息。

让我们再看一个例子:示例3中代码子类化Canvas 类。在此,绘图颜色设置为白色,并用该色画出一个矩形,然后把绘图色置为黑色。代码剩下的部分在设备屏幕上绘制系统字体,如图2所示。

图2.在设备显示屏上画出系统字体

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有