J2ME学习笔记整理

J2ME学习笔记整理

一直想写点东西为我学习J2ME做个总结,自从上次笔记本在寝室莫名其妙弄丢后,就再没写过J2ME的学习笔记,今天终于股起勇气再动笔,同时也为准备学习J2ME的兄弟姐妹起个抛砖引玉的作用,呵呵,希望不让大家失望。

先从最基本的开始说起吧 ~
J2ME 的全称是 Java2 Platform Micro Edition, 其技术架构如下

Optional Package

Profile
Configuration
Optional Package 是厂商选择性实现的, Profile 是针对特殊硬件规定制定的高级 API Configuration 则是起定义硬件功能与低级 API 的作用。
先从最下层的 Configuration 开始说起,它是 J2ME 规定嵌入式设备能够执行 Java 程序的规范, J2ME 把运算功能有限,电力有限这类的嵌入式设备叫做 Connected Limited Device ,规定这些设备如果能执行 JAVA 程序,则必须遵守哪些规范,而这些规范就定义在 Connected Limited Device Configuration 里面,简称 CLDC, 类似有个可连接,资源相对来说无限的设备则被称为 Connected Device ,同样有个 CDC 规范。我们平时所使用的手机属于 Connected Limited Device 范畴,支持 J2ME 的手机必须支持支持 CLDC 规范。就目前来看 CLDC 1.0 1.1 两种,两者最大的不同则是后者支持浮点运算,而前者不支持, CDC1.0 CDC1.1 的核心类库( java.lang.*,java.io.*,java.util.*) J2SE 几乎没什么区别, CLDC1.0 则差别较大, CLDC1.1 相对来说增强了 CLDC1.0 的功能,最小内存数量也从 160K 提升到 192K CLDC 加入的支持扩展类库为有 javax.microedition.io.* 等。
通过查阅 CLDC 的类库文档
可以得到以下一些信息,为了方便大家做个了解,我把几个大类做了一下整理:
系统类:
java.lang.Object
java.lang.Class
java.lang.Runtime
java.lang.System
java.lang.Thread
java.lang.Runnable (接口)
java.lang.String
java.lang.StringBuffer
java.lang.Throwable
数据类型类:
java.lang.Boolean
java.lang.Byte
java.lang.Short
java.lang.Integer
java.lang.Long
java.lang.Float( 1.1 版本开始支持 )
java.lang.Double( 1.1 版本开始支持 )
java.lang.Character
集合容器类:
java.util.Vector
java.util.Stack
java.util.Hashable
java.util.Enumeration( 接口)
输入 / 输出类:
java.io.InputStream
java.io.OutputStream
java.io.ByteArrayInputStream
java.io.ByteArrayOutputStream
java.io.DataInput( 接口)

java.io.DataOutput(接口)

java.io.DataOutputSteam
java.io.DataInputStream
java.io.Reader
java.io.Writer
java.io.InputSteamReader
java.io.OutputStreamReader
java.io.PrintStream
日历和时间类:
java.util.Calendar
java.util.Date
java.util.TimeZone
其他附加类:
java.util.Random
java.lang.Math
错误类:
java.lang.Error
java.lang.NoClassDeFoundError( 1.1 版本开始支持 )
java.lang.OutOfMemoryError
java.lang.VirtualMachineError
异常类:
java.lang.Exception
java.lang.ArithmeticException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayStoreException
java.lang.ClassCastException
java.lang.ClassNotFoundException
java.lang.IllegalAccessException
java.lang.IllegalArgumentException
java.lang.IllegalMonitorStateException
java.lang.IllegalThreadStateException
java.lang.IndexOutOfBoundsException
java.lang.InstantiationException
java.lang.InterruptedException
java.lang.NegativeArraySizeException
java.lang.NullPointerException
java.lang.RuntimeException
java.lang.NumberFormatException
java.lang.SecurityException
java.lang.StringIndexOutOfBoundsException
java.util.EmptyStackException
java.util.EmptyNoSuchElementException
java.io.EOFException
java.io.InterruptedIOException
java.io.IOException
java.io.UnsupportedEncodingException
java.io.UTFDataFormatException
弱引用: ( 1.1 版本开始支持 )
java.lang.ref.Reference
java.lang.ref.WeakReference
以下为 CLDC1.1 扩展类库:
javax.microedition.midlet.*
javax.microedition.lcdui.*
javax.microedition..rms.*
javax.microedition..io.*
javax.microedition.lcdui.game.*
javax.microedition.pki.*
javax.microedition..media.*
javax.microedition.media.control.*

下面来说说 Profile, 既然 Profile 构建在 Configuration 之上,其所规范的配备需求自然不会比 Configuration 低,而我们通常所提到的 Profile Mobile Information Device Profile( 简称 MIDP ),针对的是手机和寻呼机,等移动设备。还有一种常见的 Profile Information Module Profile ,是针对没有屏幕的移动设备所设计的。
目前 MIDP ,最高的规格是 2.0 ,硬件要求为:
内存: 256Kb 非易失性内存可供 MIDP 组件使用, 8Kb 非易失性内存可工应用程序创建持久化数据, 128Kb 易失性内存可供虚拟机运行时环境使用。
显示:屏幕大小 96*54 ,显示深度: 1 位,象素形状(长宽比): 1 1
输入:单手键盘或者双手键盘或者触摸屏。
网络:双向,无线,可以是间歇的,带宽有限的。
声音:播放不同声调的能力,可以通过专用硬件也可以通过软件算法获得。
J2ME 规范中还定义了厂商可以选择实现的包,那就是 Optional Packages, 通常不同的厂商不同的产品会有一些不同的功能,那么制造厂商可以通过 Optioanl Packages 规范来为实现某些产品的特殊功能制定相应的 API
那我们通常所说的 J2ME 开发,大部分其实都是 MIDP 程序设计,那我们先来看几个名词的解释 :
MIDlet: 一个可执行的应用手机程序的基本单位。
MIDlet Suite: 许多 MIDlet 所构成的集合一般称做 MIDP Application(MIDP 应用程序 )
MIDlet MIDlet Suite 的关系如下图所示
0 && image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}" border=undefined twffan="done">
JAR 文件( JAR File,.jar 文件)
实际是包裹着 MIDlet Suite 的文件,属于 ZIP 压缩格式。
JAD 文件( Descriptor File,.jad 文件)
用来描述 MIDlet Suite 的基本信息的文本文件,它是一个外部文件(不存在于 JAR 文件内部,独立存在的文件)。
它们只的关系如下图所示:
0 && image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}" border=undefined twffan="done">
0 && image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}" border=undefined twffan="done">
最后要介绍一下应用程序管理器( Java Application Manager), 它可是很重要的哦,它负责将 MIDlet 的执行及其生命周期。它是一个用来执行 J2ME 的原生程序。
接下来我们来介绍一下LCDUI这个包及其相关内容,大家都知道,在J2SE里面我们用AWT或者SWING来开发用户界面,但是在J2ME里面,开发用户界面并非上述的AWT或者SWING,我们使用的是全新的针对移动设备设计的LCDUI包(即Limited Configuration Device User Interface)。
下图是 LCDUI 包的简要结构:
0 && image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}" border=undefined twffan="done">
MIDP 中,和用户界面相关的回调函数有四个:
(1) javax.microedition.lcdui.Command ;
(2) javax.microedition.lcdui.Canvas
(3) 在屏幕重绘时,会产生重绘事件,此时的 Canvas 类的 paint() 方法会被调用,并传入一个 Graphics 对象的调用;
(4) 调用 Display 类的 callSerially ()方法时,会传入一个 Runnable 接口的类,其中的 run() 方法会被调用。
下面我们来介绍一下 javax.microedition.lcdui.Command 这个类,它既适用于高级 API(Screen ), 又使用于低级 API(Canvas ).
Command 类有两种构造函数,一个有三个参数,另一个则是四个参数。
区别在于:前者第一个参数是显示在画面上名称,第二个参数是命令的类型,第三参数是优先权,以自然数形式表示,如: 1 2 3… ,越小优先权越高,代表在屏幕显眼的地方显示。而后者则是在前者的基础上增加了一个长命令的参数,具体位于前者第一和第二个参数之间,具体机型上的显示和厂家的实现的不同而不同。
前面介绍的命令的类型共分为 8 种: Command.BACK ommand.EXIT Command.CANCEL Command.HELP Command.ITEM Command.OK Command.SCREEN Command.STOP
例:
Command c=new Command(“ 取消 ”,Command.CANCEL,1);
Command a=new Command(“ 这是长命令 ”,” 这是短命令 ”,Command.BACK,1);
在屏幕上光显示出这些是没有任何意义的,我们必须还要将 Command 类和 javax.microedition.lcdui.CommandListener 结合起来使用才能反应用户的动作,由于 setCommandListener() 定义于 Displayable 中,所以 CommandListener 是一个和 Command 一样可以通用与高级 API 和低级 API 的事件处理接口。
0 && image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}" border=undefined twffan="done">
需要注意的是 CommandListener 采用的是 Unicast 机制,也就是说,同一时刻只能注册一个时间处理函数。
下面是一个在 MIDlet 中使用 Command CommandListener 的大致情形:
public class example1 extends MIDlet implements CommandListener
{
public void startApp()
{
………
Command exp1=new Command(“ 命令<chmetcnv w:st="on" unitname="”" sourcevalue="1" hasspace="False" negative="False" numbertype="1" tcsc="0"></chmetcnv> 1” ,Command.OK,1);
………
}
public void pauseApp()
{
………
}
public void destroyApp(boolean exp)
{
………
}
public void commandAction(Command c,Displayable s)
{
………
}
}
介绍完了 Command 类,我们来介绍一下 Ticker 类,在 MIDP1.0 中,它只能用于 Screen 的子类,在 MIDP2.0 后,已经可以用于 Displayable 的所有子类了。它是一个类似于跑马灯的类,即通常所见的进度条,我们通常用 setTicker() 来设定画面上的 Ticker ,或者用 getTicker() 来取得画面上的 Ticker 对象, setTicker() 中的括号内的双引号中的字符串即显示在跑马灯中的文字。
下面用一个例子来详细介绍一下上面几个类的用法,作为本章的小结。
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class DisplayableTestMIDlet extends MIDlet implements CommandListener
{
public void startApp()
{
display=Display.getDisplay(this);
}
public void pauseApp()
{
f=new Form("Displayable 测试 ");
Command test1=new Command(" 开始 Ticker",Command.SCREEN,1);
Command test2=new Command(" 停止 Ticker",Command.SCREEN,1);
Command test3=new Command(" 退出 ",Command.EXIT,1);
f.addCommand(test1);
f.addCommand(test2);
f.addCommand(test3);
f.setCommandListener(this);
display.setCurrent(f);
}
public void destroyApp(boolean unconditional)
{
}
public void commandAction(Command c,Displayable s)
{
String cmd=c.getLabel();
if(cmd.equals(" 开始 Ticker"))
{
f.setTicker(new Ticker(" 运作中 "));
}
if(cmd.equals(" 停止 Ticker"))
{
f.setTicker(null);
}
}
private Display display;
Form f;
}

Screen类有四个相关的子类,分别为Alert,List,TextBox,Form,这四个子类可以细分为两类,前三者属于封装了较复杂用户界面的类,我们只能单纯的拿来使用,对于其内部的组成结构无法修改;相对前三者,Form则是自由的多,它是默认缺省没有任何用户界面的组件,它类似于一个容器,可以容纳Item类的子类,以构成复杂的图形用户界面.

下面我们来详细介绍一下这四个子类:
0 && image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}" align=middle border=undefined twffan="done">

List组件根据Choice接口中的定义,分为Choice.EXCLUSIVE,Choice.MULTIPLE,Choice.IMPLICIT三种,它们之间的区别也很简单,你只需从字面便可读出区别来,分别为单选类型的,多选类型的,简易式的单选,IMPLICITEXCLUSIVE的最大区别在于,Choice.IMLICIT类型的List会在用户选择之后立刻触发时间,并将List.SELECT_COMMAND做为commandAction()函数的第一个参数传入,经由次判别,我们可以知道事件是否由List触发,因为这种类型的List在同一时间只有一个选项会被选择。Choice接口给List提供了一种叫Fit Policy的机制,分别为Choice.TEXT_WRAP_DEFAULT,Choice.TEXT_WRAP_ON,Choice.TEXT_WRAP_OFF三种,它们用来决定过长的文字如何被处理,使用Choice.TEXT_WRAP_ON时,过长的文字会自动编排到下一行,而Choice.TEXT_WRAP_OFF则市自动截断,DEFAULT则是根据厂家默认来选择。

代码示范如下:
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class ImplicitListWithFitPolicyMIDlet extends MIDlet implements CommandListener
{
private Display display;
public ImplicitListWithFitPolicyMIDlet()
{
display=Display.getDisplay(this);
}
public void startApp()
{
Image img=null;
try
{
img=Image.createImage("/A.png");
}catch(Exception e)
{
System.out.println(e);
}
List l=new List("List 测试 ",Choice.IMPLICIT);
System.out.println(" 缺省的 Fit Policy:"+l.getFitPolicy());
l.append("12345678901234567890",img);
l.append("abcdefgabcdefg",img);
Command c1=new Command("WRAP_OFF",Command.OK,1);
l.addCommand(c1);
Command c2=new Command("WRAP_ON",Command.OK,1);
l.addCommand(c2);
Command c3=new Command("WRAP_DEFAULT",Command.OK,1);
l.addCommand(c3);
l.setCommandListener(this);
display.setCurrent(l);
}
public void commandAction(Command c,Displayable s)
{
String cmd=c.getLabel();
if(cmd.equals("WRAP_OFF"))
{
List tmp=(List) s;
tmp.setFitPolicy(Choice.TEXT_WRAP_OFF);
}
if(cmd.equals("WRAP_ON"))
{
List tmp=(List) s;
tmp.setFitPolicy(Choice.TEXT_WRAP_ON);
}
if(cmd.equals("WRAP_DEFAULT"))
{
List tmp=(List) s;
tmp.setFitPolicy(Choice.TEXT_WRAP_DEFAULT);
}
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
}
下面我们再来说一说 TextBox ,当用户需要输入文字时, TextBox 就派上用场了, TextBox 定义使用如下 :TextBox tb=new TextBox(“ 文字输入测试 ”,” 名字 ”,9 TextField.ANY);
其中 输入测试 Title, 名字 则是我们指的内容,第三个参数就是我们要限制的参数 2 的字符数,第四个参数则是对输入内容做了更进一步的限制, ANY 指的是允许输入任何字符或数字,类似还有 EMAILADDR 则是指允许输入电子邮件地址,等等(参见 API 说明文档)。
下面介绍一下 AlertType ,它是一个工具类,本身是无法实体化的它提供了几种定义好的 AlertType 用以辅助 Alert 类的使用。比如: ALARM (警报), CONFIRMATION (确定), ERROR (错误)等等, Alert 是一个比较特殊的 Screen 类的对象,当我们利用 Display.setCurrent() 这个方法的时候,它会先发出一段声音,然后将自己显示在屏幕上,过一段时间后,跳回之前的画面,因此,请注意,我们必须要使系统一定要存在一个画面,这样才能让 Alert 条回,否则,会发生错误,下面一段代码提示 Alert 的使用 :
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class AlertSplashScreenMIDlet extends MIDlet
{
private Display display;
public AlertSplashScreenMIDlet()
{
display=Display.getDisplay(this);
}
public void startApp()
{
Alert a1=new Alert(“ 应用程序开始启动 ”);
a1.setType(AlertType.INFO);
setTimeout(5000);
a1.setString(“ 应用程序初始化中,请稍等 ”);
Form f=new Form(“ 主画面 ”);
dsplay.setCurrent(a1,f);
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
}
至于 Form ,是这个 Screen 类中最终要的一个子类,是高级图形界面中最长用到的,我们留在后面的章节中继续探讨它 ~

代码示范如下:
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class ImplicitListWithFitPolicyMIDlet extends MIDlet implements CommandListener
{
private Display display;
public ImplicitListWithFitPolicyMIDlet()
{
display=Display.getDisplay(this);
}
public void startApp()
{
Image img=null;
try
{
img=Image.createImage("/A.png");
}catch(Exception e)
{
System.out.println(e);
}
List l=new List("List 测试 ",Choice.IMPLICIT);
System.out.println(" 缺省的 Fit Policy:"+l.getFitPolicy());
l.append("12345678901234567890",img);
l.append("abcdefgabcdefg",img);
Command c1=new Command("WRAP_OFF",Command.OK,1);
l.addCommand(c1);
Command c2=new Command("WRAP_ON",Command.OK,1);
l.addCommand(c2);
Command c3=new Command("WRAP_DEFAULT",Command.OK,1);
l.addCommand(c3);
l.setCommandListener(this);
display.setCurrent(l);
}
public void commandAction(Command c,Displayable s)
{
String cmd=c.getLabel();
if(cmd.equals("WRAP_OFF"))
{
List tmp=(List) s;
tmp.setFitPolicy(Choice.TEXT_WRAP_OFF);
}
if(cmd.equals("WRAP_ON"))
{
List tmp=(List) s;
tmp.setFitPolicy(Choice.TEXT_WRAP_ON);
}
if(cmd.equals("WRAP_DEFAULT"))
{
List tmp=(List) s;
tmp.setFitPolicy(Choice.TEXT_WRAP_DEFAULT);
}
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
}
下面我们再来说一说 TextBox ,当用户需要输入文字时, TextBox 就派上用场了, TextBox 定义使用如下 :TextBox tb=new TextBox(“ 文字输入测试 ”,” 名字 ”,9 TextField.ANY);
其中 输入测试 Title, 名字 则是我们指的内容,第三个参数就是我们要限制的参数 2 的字符数,第四个参数则是对输入内容做了更进一步的限制, ANY 指的是允许输入任何字符或数字,类似还有 EMAILADDR 则是指允许输入电子邮件地址,等等(参见 API 说明文档)。
下面介绍一下 AlertType ,它是一个工具类,本身是无法实体化的它提供了几种定义好的 AlertType 用以辅助 Alert 类的使用。比如: ALARM (警报), CONFIRMATION (确定), ERROR (错误)等等, Alert 是一个比较特殊的 Screen 类的对象,当我们利用 Display.setCurrent() 这个方法的时候,它会先发出一段声音,然后将自己显示在屏幕上,过一段时间后,跳回之前的画面,因此,请注意,我们必须要使系统一定要存在一个画面,这样才能让 Alert 条回,否则,会发生错误,下面一段代码提示 Alert 的使用 :
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class AlertSplashScreenMIDlet extends MIDlet
{
private Display display;
public AlertSplashScreenMIDlet()
{
display=Display.getDisplay(this);
}
public void startApp()
{
Alert a1=new Alert(“ 应用程序开始启动 ”);
a1.setType(AlertType.INFO);
setTimeout(5000);
a1.setString(“ 应用程序初始化中,请稍等 ”);
Form f=new Form(“ 主画面 ”);
dsplay.setCurrent(a1,f);
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
}
至于 Form ,是这个 Screen 类中最终要的一个子类,是高级图形界面中最长用到的,我们留在后面的章节中继续探讨它 ~
当我们选择了Canvas这个类,就意味着我们准备采用低级API,之所以称之为低级API,并不是因为它很低能,恰恰相反,我们可用它来处理一些很底层的系统事件,具体如何支持,我们要看硬件上的支持程度来判定。
下面列出判断硬件支持程度的方法列表:
0 && image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}" border=undefined twffan="done">
所有的低级 API 都是从 javax.microedition.lcdui.Canvas 开始,我们必须继承 Canvas ,才可以建立一个显示在屏幕上的画面,需要注意的是每一个 Canvas 里面必须有一个抽象方法 paint(), 并且需要传入一个 Graphics 的引用,可以说 Canvas 的精华就在这个 paint() 方法里面,我们用这个方法来负责这个屏幕画面的描绘。
任何时候我们都可以用 repaint() 来产生重绘事件, repaint() 一共有两个同名方法,其中一个需要四个参数,分别是起始坐标( x,y ),还有宽度和高度,另外一个不需要任何参数,它是代表整个屏幕全部重新绘制,由此看来,前者的效率较后者要高,实际开发中也大多数是用前者而不是后者,我们调用了 repaint() 之后,会立刻返回,调用 paint() 则是由另外一个专门处理 UI 的线程来完成,如果我们希望等到 paint() 完成后再返回,我们可以在 repaint() 方法后加一个 serviceRepaints() 方法,它的作用是强制队列中的重绘事件尽快完成,如果队列中无重绘事件,它就什么也不会做,因此调用 repaint() 方法的时候,我们通常会在后面加一个 serviceRepaints() 方法。
我们在手机上绘制图象的坐标系和我们通常所见的坐标系是不一样的

<textbox style="MARGIN-TOP: 4.656pt; LEFT: auto; MARGIN-LEFT: 8.281pt; WIDTH: 29.875pt; TOP: auto; HEIGHT: 23.312pt"></textbox>

X
<textbox style="MARGIN-TOP: 4.875pt; LEFT: auto; MARGIN-LEFT: 8.281pt; WIDTH: 11.906pt; TOP: auto; HEIGHT: 31.031pt"></textbox>
Y
<textbox style="MARGIN-TOP: 4.843pt; LEFT: auto; MARGIN-LEFT: 8.281pt; WIDTH: 65.906pt; TOP: auto; HEIGHT: 31.062pt"></textbox>
通常的坐标系
<textbox style="MARGIN-TOP: 5pt; LEFT: auto; MARGIN-LEFT: 8.312pt; WIDTH: 56.875pt; TOP: auto; HEIGHT: 15.468pt"></textbox>
X
<textbox style="MARGIN-TOP: 4.562pt; LEFT: auto; MARGIN-LEFT: 8.312pt; WIDTH: 2.875pt; TOP: auto; HEIGHT: 54.468pt"></textbox>
Y
<textbox style="MARGIN-TOP: 4.375pt; LEFT: auto; MARGIN-LEFT: 8.312pt; WIDTH: 74.875pt; TOP: auto; HEIGHT: 46.656pt"></textbox>
MIDP 中的坐标系

0 && image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}" border=undefined twffan="done">
这是我们在绘制图象时要注意的。
下面我们来讲一讲 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());
}
}
需要大家注意的是 R G B 的值只能在 0 —— 255 之间,不可以超出这个范围,另外我们可以直接用 0x00RRGGBB 格式进行颜色的调配。
上面的代码简要说了一下 Graphics 几个重要的参数如何获得,下面我们就来谈一谈如何用 Graphics 做具体的图形,如果我们需要绘制一条直线,我们可以调用 drawLine() 方法,需要定义其开始坐标和结束坐标,共四个参数,同时, Graphics 提供两种形式的线条,一个是虚线,即 Graphics.DOTTED ,一个是实线,即 Graphics.SOLID, 同样我们给出一段代码供大家参考:
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class GraphicsTestCanvas2 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);
分享到:
评论

你可能感兴趣的:(java,C++,网络应用,C#,嵌入式)