专题三 低级用户界面

57
Hands-On 实实实实实实 实实实 实实实实实实 实实 实实实实实

Upload: chloe

Post on 11-Jan-2016

73 views

Category:

Documents


8 download

DESCRIPTION

专题三 低级用户界面. 案例一 运动的小球. 回顾. MVC 设计模式 在 JavaME 开发中的应用 优点及缺点 学习 Form 类及 Item 子类 Item TextField ChoiceGroup Spacer ImageItem ) 掌握 Item 事件处理( ItemCommandListener/ItemStateListener ). 本章目标. 掌握 Canvas 类 屏幕绘制及重绘 事件处理 学习 Graphics 类 绘制几何图形 设置颜色 绘制文本 学习 Font 类. 工作任务 2-1. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 专题三 低级用户界面

Hands-On 实训教程系列

专题三 低级用户界面

案例一 运动的小球

Page 2: 专题三 低级用户界面

Hands-On 实训教程系列

回顾

MVC 设计模式 在 JavaME 开发中的应用 优点及缺点

学习 Form 类及 Item 子类 Item TextField ChoiceGroup Spacer ImageItem )

掌握 Item 事件处理( ItemCommandListener/ItemStateListener )

Page 3: 专题三 低级用户界面

Hands-On 实训教程系列

本章目标

掌握 Canvas 类 屏幕绘制及重绘 事件处理

学习 Graphics 类 绘制几何图形 设置颜色 绘制文本

学习 Font 类

Page 4: 专题三 低级用户界面

Hands-On 实训教程系列

工作任务 2-1

实现一个运动小球的游戏,具体要求如下: 游戏包含一个开始菜单,包括“开始”和“退

出”两个菜单项。用户选择“开始”菜单项,启动弹球游戏;选择“退出”菜单项,结束弹球游戏。

游戏开始后,屏幕上显示一个运动的小球,还包括一个“暂停”命令。当用户执行“暂停”命令(屏幕右下角)时,屏幕返回菜单选择界面 。

Page 5: 专题三 低级用户界面

Hands-On 实训教程系列

工作任务 2-2

参考实现结果:

Page 6: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-1

1. 创建名为 subject5 的 MIDlet Project ,并在 src 源文件夹下创建 BounceMIDlet 类

//BounceMIDlet 类是弹球游戏主程序 public class BounceMIDlet extends MIDlet {

/** display Display 界面管理器 */ private Display display;

// 无参构造 public BounceMIDlet() {

// 获得界面管理器 display = Display.getDisplay(this);

}

protected void startApp() throws MIDletStateChangeException {

}

protected void destroyApp(boolean unconditional)

throws MIDletStateChangeException {}

protected void pauseApp() {}

}

Page 7: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-2

2. 创建封装小球特征的 Ball 类 //Ball 类封装了小球的特征 public class Ball {

/** diameter int 直径 */ private int diameter;

/** x int X 坐标 */ private int x;

/** y int Y 坐标 */ private int y;

// 带参构造 public Ball(int diameter, int x, int y) {

this.diameter = diameter;

this.x = x;

this.y = y;

}

//move 方法模仿了小球移动的行为 public void move(int dx,int dy){

x += dx;

y += dy;

}

//.... 下面省略了属性的 getter/setter 方法 }

Page 8: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-33. 创建继承 Canvas类的菜单屏幕类 MenuCan

vas//MenuCanvas 类代表菜单屏幕类public class MenuCanvas extends Canvas {

// 无参构造public MenuCanvas(){

}

//paint 方法用于界面绘制protected void paint(Graphics g) {

}

}

Graphics类屏幕绘制

Page 9: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-4为 MenuCanvas 添加属性:

屏幕尺寸: canvasWidth (画布宽)、 canvasHeight(画布高)

矩形方框的坐标: recX (左上角 x 坐标)、 recY (左上角 y 坐标)

矩形方框的尺寸: menuWidth (菜单宽度)、 menuHeight (菜单高度)

每个填充菜单项的坐标:基于 recX 和 recY 计算获取 每个填充菜单项的尺寸: fillMenuWidth (填充菜单宽

度)、 fillMenuHeight (填充菜单高度)

//MenuCanvas 类定义↓private int canvasWidth;// 画布宽

private int canvasHeight;// 画布高

private int menuWidth = 80;// 菜单宽

private int menuHeight = 50;// 菜单高

private int fillMenuWidth = menuWidth - 2;// 填充矩形的宽度

private int fillMenuHeight = menuHeight/2 - 2;// 填充矩形的高度

private int recX;// 填充矩形的左上角 X 坐标

private int recY;// 填充矩形的左上角 Y 坐标

/// 保存填充矩形左上角坐标的二维数组,数组中的每个一维数组代表一个填充矩形的左上角坐标private int[][] fillPoint;

//MenuCanvas 类定义↑

减 2 是为了让显示效果有一点立体感

Page 10: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-5在构造方法中初始化上面的属性:

//MenuCanvas 构造方法定义↓ // 获得画布宽度 canvasWidth = getWidth();

// 获得画布高度 canvasHeight = getHeight();

// 计算并初始化两个填充矩形的左上角坐标 recX = (canvasWidth - menuWidth)/2;

recY = (canvasHeight - menuHeight)/2;

fillPoint = new int[][]{

new int[]{recX + 2,recY + 2},

new int[]{recX + 2,recY + fillMenuHeight + 4}};

//MenuCanvas 构造方法定义↑

Page 11: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-6实现 paint 方法,在其中编写界面绘制的代

码 : //paint 方法定义↓ // 绘制白色背景,在重绘前初始化界面 g.setColor(255, 255, 255);// 设置画笔颜色 g.fillRect(0, 0, canvasWidth, canvasHeight);// 绘制填充矩形 g.setColor(210, 105, 30);// 设置画笔颜色 g.drawRect(recX, recY, menuWidth, menuHeight);// 绘制矩形菜单 // 在矩形之间绘制一条线,形成两个菜单项 int lineY = recY + menuHeight/2;

g.drawLine(recX, lineY, recX + menuWidth, lineY);

// 设置画笔颜色 g.setColor(0, 0, 0);

// 设置字体样式 g.setFont(Font.getFont(Font.FACE_MONOSPACE,

Font.STYLE_BOLD|Font.STYLE_ITALIC, Font.SIZE_LARGE));

// 为两个按钮添加文字 g.drawString(" 开始 ", canvasWidth/2, recY + 3,

Graphics.TOP|Graphics.HCENTER);

g.drawString(" 退出 ", canvasWidth/2, lineY + 3,

Graphics.TOP|Graphics.HCENTER);

//paint 方法定义↑

设置颜色

绘制矩形

绘制直线

设置字体

绘制文本

Page 12: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-7在 BounceMIDlet 类中创建 MenuCanvas 对

象,然后设置为当前界面 ://BounceMIDlet 定义↓// 添加 menu 属性,创建 MenuCanvas 对象并显示//... 这里省略了部分属性定义/** menu MenuCanvas 菜单画布 */private MenuCanvas menu;

// 无参构造public BounceMIDlet() {

// 获得界面管理器display = Display.getDisplay(this);

// 创建菜单画布对象menu = new MenuCanvas();

}

protected void startApp() throws MIDletStateChangeException {

display.setCurrent(menu);

}

//... 这里省略了部分方法定义//BounceMIDlet 定义↑

Page 13: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-8绘制选中菜单项:

//MenuCanvas 类定义↓ // 添加 curMenu 属性 //... 这里省略了部分属性定义 /** curMenu int 当前菜单索引:第一个为 0 */

private int curMenu;

//MenuCanvas 类定义↑

//paint 方法定义↓// 添加绘制填充矩形的代码//... 这里省略了部分代码// 设置填充矩形颜色g.setColor(244, 144, 96);

// 绘制填充矩形菜单项g.fillRect(fillPoint[curMenu][0],

fillPoint[curMenu][1], fillMenuWidth, fillMenuHeight);

//... 后面省略了绘制菜单文字的代码//paint 方法定义↑

Page 14: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-94. 实现选择菜单的操作 :

//MenuCanvas 类定义↓ // 重写 Canvas 类的 keyPressed 方法 /**

* keyPressed 方法处理用户的按键操作 */

protected void keyPressed(int keyCode) {

// 判断用户按键类型 switch(getGameAction(keyCode)){

case UP:

case DOWN:

// 按下 "↑" 或 "↓" 时,循环设置当前菜单索引 curMenu = ++curMenu % 2;

break;

}

repaint();// 重绘当前画布 }

//MenuCanvas 类定义↑

按键事件处理游戏动作

Page 15: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-105. 实现退出功能:

为 MenuCanvas 类添加一个 BounceMIDlet 对象的引用,并重载构造方法 //MenuCanvas 类定义↓ // 添加 BounceMIDlet 引用,重载构造方法 //... 这里省略了部分属性定义 /** bounceMIDlet BounceMIDlet 弹球应用程序引用 */ private BounceMIDlet bounceMIDlet;

// 带参构造 public MenuCanvas(BounceMIDlet bounceMIDlet){

this();

this.bounceMIDlet = bounceMIDlet;

}

//... 这里省略了部分方法定义 //MenuCanvas 类定义↑

Page 16: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-11在 BounceMIDlet 类中添加一个 exit 方法:

//BounceMIDlet 定义↓ // 添加一个 exit 方法 //... 这里省略了部分代码 // 退出应用程序 public void exit(){

try {

destroyApp(true);

notifyDestroyed();

} catch (MIDletStateChangeException e) {

e.printStackTrace();

}

}

//BounceMIDlet 定义↑

Page 17: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-12修改 MenuCanvas 类,在 keyPressed 方法

中增加一个处理“ Fire” 键被按下的 case分支判断 ://MenuCanvs 类定义↓

//keyPressed 方法定义↓// 修改 keyPressed 方法,添加处理 " 确定键 " 按下的 case 分支 switch(getGameAction

(keyCode)){

//... 这里省略了其他 case 分支case FIRE: // 处理按下 " 确定键 "

switch(curMenu){// 根据索引判断用户按下了哪个菜单项case 1:// 按下 " 退出 " 菜单项

bounceMIDlet.exit();

break;

}

break;

}

//keyPressed 方法定义↑//MenuCanvs 类定义↑

Page 18: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-13修改 BounceMIDlet 的构造方法 :

//BounceMIDlet 类定义↓ // 修改构造方法 //... 这里省略了部分代码 // 无参构造 public BounceMIDlet() {

// 获得界面管理器 display = Display.getDisplay(this);

// 创建菜单画布对象 menu = new MenuCanvas(this);

}

//BounceMIDlet 类定义↑调用 MenuCanvas的带参构造

Page 19: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-14

6. 实现游戏主界面,创建 BounceCanvas 类

//BounceCanvas 类代表游戏的主窗体 public class BounceCanvas extends Canvas

implements CommandListener{

// 实现 Canvas 类的 paint 方法 protected void paint(Graphics g) {

}

// 实现 CommandListener 接口的 commandAction 方法 public void commandAction(Command c, Displayable d) {

}

}

Page 20: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-15

为 BounceCanvas 类添加下面的属性//BounceCanvas 类定义↓// 添加属性private Ball ball;// 小球

private int canvasWidth;// 画布宽

private int canvasHeight;// 画布高

private int dx = 5;// 小球水平位置变化量

private int dy = 5;// 小球垂直位置变化量

// 暂停命令 private Command pauseCmd = new Command(" 暂停 ",Command.SCREEN,1);

/** midlet BounceMIDlet 弹球主应用程序 */ private BounceMIDlet midlet;

//... 这里省略了部分代码//BounceCanvas 类定义↑

值越大,小球的运动速度越快

Page 21: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-16

为 BounceCanvas 添加构造方法,对属性进行初始化 //BounceCanvas 类定义↓ // 添加带参构造 // 带参构造 public BounceCanvas(BounceMIDlet midlet) {

setTitle(" 弹球游戏 ");// 设置画布标题 this.midlet = midlet;// 获得主程序引用 // 获得画布的宽 canvasWidth = getWidth();

// 获得画布的高 canvasHeight = getHeight();

// 创建一个直径为 10 ,初始位置在 X:5,Y:5 的小球 ball = new Ball(10, 5, 5);

// 为画布添加 " 暂停命令 "

addCommand(pauseCmd);

// 为画布设置 CommandListener 监听 setCommandListener(this);

}

//... 这里省略了部分代码 //BounceCanvas 类定义↑

Page 22: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-17

实现 BounceCanvas 类的 paint 方法,在屏幕上绘制小球 //BounceCanvas 类定义↓ // 实现绘制小球的功能 protected void paint(Graphics g) {

// 将画笔设置为白色 g.setColor(255,255,255);

// 填充矩形,为画布重绘背景色 g.fillRect(0, 0, canvasWidth, canvasHeight);

// 将画笔设置为红色 g.setColor(255, 0, 0);

// 在画布上画一个红色的小球 g.fillArc(ball.getX(), ball.getY(),

ball.getDiameter(), ball.getDiameter(), 0, 360);

}

//BounceCanvas 类定义↑

绘制圆弧和扇面

Page 23: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-18

在 BounceMIDlet 类中添加一个 BounceCanvas 界面引用,并提供一个开始游戏的 play 方法//BounceMIDlet 类定义↓ // 添加 BounceCanvas 界面引用和启动游戏的 play 方法

/** bounceCanvas BounceCanvas 弹球画布 */ private BounceCanvas bounceCanvas;

// 启动游戏的 play 方法 public void play(){

// 创建一个用于绘制弹跳小球的新画布 bounceCanvas = new BounceCanvas(this);

// 设置弹球画布为当前界面 display.setCurrent(bounceCanvas);

}

//BounceMIDlet 类定义↑

Page 24: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-19

为 MenuCanvas 的 keyPresssed 方法添加判断按下“开始”菜单项的 case 分支 //keyPressed 方法定义↓ // 添加处理 " 确定键 " 按下的 case 分支 switch(getGameAction(keyCode)){

//... 这里省略了其他 case 分支 case FIRE: // 处理按下 " 确定键 "

switch(curMenu){// 根据索引判断用户按下了哪个菜单项 case 1:// 按下 " 退出 " 菜单项 bounceMIDlet.exit();

break;

case 0:// 按下 " 开始 " 菜单项 bounceMIDlet.play();// 运行游戏 break;

}

break;

}

//keyPressed 方法定义↑

Page 25: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-20

绘制动态小球 修改 BounceCanvas 类,让它实现 Runnable 接

口,成为线程运行的目标类:

//BounceCanvas 类定义↓ // 为 BounceCanvas 类添加 Runnable 接口实现 , 并添加一个 isRun 属性 public class BounceCanvas extends Canvas

implements CommandListener,Runnable{

//... 这里省略了部分代码private boolean isRun = true;// 线程执行的标识

// 实现 Runnable 接口的 run 方法 public void run() {

while(isRun){

// 让小球移动指定的距离 ball.move(dx, dy);

repaint();// 重绘屏幕 try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

//BounceCanvas 类定义↑

Page 26: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-21

修改 BounceMIDlet 类的 play 方法,添加启动线程的代码

//play 方法定义, BounceMIDlet 类定义↓ // 添加启动线程的代码 //... 这里省略了部分代码 // 启动游戏 public void play(){

// 创建一个用于绘制弹跳小球的新画布 bounceCanvas = new BounceCanvas(this);

// 设置弹球画布为当前界面 display.setCurrent(bounceCanvas);

new Thread(bounceCanvas).start();

}

Page 27: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-22

实现“暂停”游戏的操作 -1 在 BounceCanvas 中添加一个 pause 方法,将线程执行的标识修改为 false

//BounceCanvas 类定义↓ // 添加 pause 方法,用于停止线程的执行 //... 这里省略了部分代码 //public void pause(){

isRun = false;

}

//BounceCanvas 类定义

Page 28: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-23

实现“暂停”游戏的操作 -2 实现 BounceMIDlet 的 pauseApp 方法,在其中

执行释放资源和切换界面的操作: //pauseApp 方法定义↓ protected void pauseApp() {

// 停止控制小球弹跳的线程 bounceCanvas.pause();

// 释放资源 bounceCanvas = null;

// 返回选项菜单 display.setCurrent(menu);

}

//pauseApp 方法定义↑

Page 29: 专题三 低级用户界面

Hands-On 实训教程系列

相关实践 24-24

实现“暂停”游戏的操作 -3 实现 BounceCanvas 类的 commandAction 方法,

处理执行“暂停”命令的操作

//commandAction 方法定义↓// 实现 CommandListener 接口的 commandAction 方法

public void commandAction(Command c, Displayable d) {

if(c == pauseCmd){

midlet.pauseApp();

}

}

//commandAction 方法定义↑

Page 30: 专题三 低级用户界面

Hands-On 实训教程系列

总结 -1

掌握 Canvas 类 屏幕绘制

paint 方法 重绘

repaint 方法 事件处理

键盘按键事件游戏动作

Page 31: 专题三 低级用户界面

Hands-On 实训教程系列

总结 -2

学习 Graphics 类 绘制几何图形

绘制直线绘制矩形绘制圆弧和扇面

设置颜色 绘制文本

学习 Font 类

Page 32: 专题三 低级用户界面

Hands-On 实训教程系列

Canvas-1

Canvas “ 画布”类,是 Displayable 的子类 提供了一系列屏幕绘制以及处理低级界面事件的

方法 是一个抽象类,它包含一个 paint 抽象方法,必须创建该类的子类

Page 33: 专题三 低级用户界面

Hands-On 实训教程系列

Canvas-2

Canvas 类的常用方法 界面设置及设备信息相关

setFullScreenMode/isDoubleBuffered/hasPointerEvents/hasPointerMotionEvents/hasRepeatEvents

屏幕绘制相关paint/repaint/serviceRepaints

事件处理相关hideNotify/showNotify/sizeChangedkeyPressed/keyReleased/keyRepeated/getKeyNa

me/getKeyCode/getGameActionpointerDragged/pointerPressed/pointerReleased

Page 34: 专题三 低级用户界面

Hands-On 实训教程系列

Canvas-2

创建 Canvas 子类 // 创建 Canvas 类的子类 public class SubCanvas extends Canvas {

private int canvasWidth;// 画布宽

private int canvasHeight// 画布高

public SubCanvas(){// 无参构造方法 // 获取画布的宽与高 canvasWidth = getWidth();

canvasHeight = getHeight();

}

public void paint(Graphics g){// 实现 Canvas 类 paint 方法 // 编写屏幕绘制代码 }

}

Page 35: 专题三 低级用户界面

Hands-On 实训教程系列

Canvas-3

Canvas 的两种显示方式 正常模式(默认)

setFullScreenMode(false) 全屏模式

setFullScreenMode(true)

在全屏模式下, Canvas 的标题、 Ticker 将自动被隐藏,Command 命令也无法使用。

Page 36: 专题三 低级用户界面

Hands-On 实训教程系列

屏幕绘制 -1

paint 方法 protected abstract paint(Graphics g) 子类应实现 paint 方法 不建议在应用程序中直接调用

repaint 方法 调用该方法将引起 paint 方法的执行

public final void repaint() :重绘整个屏幕public final void repaint(int x,int y,int width,int height) :重

绘屏幕的指定区域 repaint 方法不能被子类重写

Page 37: 专题三 低级用户界面

Hands-On 实训教程系列

屏幕绘制-2

public class SubCanvas extends Canvas

implements CommandListener{

//repaintCmd :重画屏幕命令 private Command repaintCmd =

new Command(" 重画屏幕 ",Command.SCREEN,1);

// 无参构造 public SubCanvas(){

System.out.println(" 当前画布 "

+ (isShown()?" 正在显示! ":" 未显示 !"));

System.out.println(" 当前设备 "

+ (hasPointerEvents()?" 支持 ":" 不支持 ") + " 指针事件 !");

System.out.println(" 当前设备 "

+ (hasRepeatEvents()?" 支持 ":" 不支持 ") + " 连续按键事件 !");

System.out.println(" 当前设备 "

+ (isDoubleBuffered()?" 支持 ":" 不支持 ") + " 图像双缓冲 !");

addCommand(repaintCmd);// 添加重画命令 this.setCommandListener(this);

}

// 实现了 paint 方法 protected void paint(Graphics g) {

System.out.println(" 执行了 paint 方法 ....");

System.out.println(" 当前画布 "

+ (isShown()?" 正在显示! ":" 未显示 "));

}

// 实现了 commandAction 方法 public void commandAction(Command c, Displayable d) {

if(c == repaintCmd){

repaint();// 执行屏幕重画 System.out.println("调用 repaint 方法,执行了屏幕重

画 ....");

}

}

}

Page 38: 专题三 低级用户界面

Hands-On 实训教程系列

Graphics-1

Graphics 类 主要提供了基本的绘制功能

几何图形:包括直线、(圆角)矩形、弧形、填充三角形等

文本:字符或字符串图像:绘制可变图像或不可变图像

设置绘图环境设置颜色设置字体

Page 39: 专题三 低级用户界面

Hands-On 实训教程系列

Graphics-2

获取 Graphics 类的对象通过 paint 方法的参数

Graphics 对象主要用于在屏幕上绘制图形利用 Image 类的 getGraphics 方法

一般用于绘制后台缓冲

Page 40: 专题三 低级用户界面

Hands-On 实训教程系列

设置颜色 -1

颜色表示 Graphics 类中提供了一个 24 位的颜色模型,分别使用三个 8 位二进制表示红( R )、绿( G )、蓝( B )三种颜色public void setColor(int red,int green,int blue) :

每个参数的范围是 0-255public viod setColor(int RGB) :参数使用一个十六

进制的整数,该整数的形式为“ 0xAARRGGBB”– 后 24 位( RRGGBB )代表红、绿、蓝三种颜色– 前八位( AA )则代表了 Alpha 透明度值,该值在颜色模型

中被忽略 Graphics 的默认颜色为黑色,颜色值是 0

Page 41: 专题三 低级用户界面

Hands-On 实训教程系列

设置颜色 -2

//ColorSetCanvas 类演示了如何设置绘图颜色 public class ColorSetCanvas extends Canvas {

protected void paint(Graphics g) {

// 将绘图颜色设置为红色 g.setColor(255, 0, 0);

g.fillRect(10, 25, 50, 80);

// 将绘图颜色设置为蓝色 g.setColor(0x0000FF);

g.fillRect(40, 100, 50, 80);

}

}后面设置的颜色会替代之前设定的颜色

Page 42: 专题三 低级用户界面

Hands-On 实训教程系列

绘制矩形 -1

Graphics 类的 drawRect 方法用来绘制矩形,fillRect 方法用来绘制填充矩形: drawRect(int x,int y,int width,int height) fillRect(int x,int y,int width,int height)

x :矩形左上角横坐标y :矩形左上角纵坐标width :矩形宽度height :矩形高度

Page 43: 专题三 低级用户界面

Hands-On 实训教程系列

绘制矩形 -2

//DrawRectCanvas 类演示了 drawRect 方法和 fillRect 方法的使用 public class DrawRectCanvas extends Canvas {

protected void paint(Graphics g) {

// 在( 10,25)的坐标位置绘制了一个宽为 50, 高为 80 的矩形框 g.drawRect(10, 25, 50, 80);

//使用当前前景色在( 40,70)的坐标位置 // 绘制一个宽为 100 ,高为 50 的填充矩形 g.fillRect(45, 70, 100, 50);

}

}

Page 44: 专题三 低级用户界面

Hands-On 实训教程系列

绘制圆弧和扇面 -1

Graphics 类提供了用于绘制圆弧和扇面的 drawArc 和 fillArc 方法: public drawArc(int x,int y, int width,int height,int startAngle,int arcAngle)

public fillArc(int x,int y,int width,int height,int startAngle,int arcAngle)x :圆弧所在矩形区左上角的横坐标y :圆弧所在矩形区左上角的纵坐标width :圆弧所在矩形区的宽height :圆弧所在矩形区的高startAngle :以圆弧所在矩形的中心为圆心,时钟 3 点的方向为 0

度角,逆时针旋转的角度arcAngle :以 startAngle 为起始角度,逆时针旋转的角度

Page 45: 专题三 低级用户界面

Hands-On 实训教程系列

绘制圆弧和扇面 -2

//DrawArcCanvas 类演示了 drawArc 方法和 fillArc 方法的使用 public class DrawArcCanvas extends Canvas {

protected void paint(Graphics g) {

// 绘制一个圆弧 g.drawArc(50, 75, 100, 100 , 30, 90);

// 绘制一个填充圆形 g.fillArc(90,120,90,90,0,360);

}

}

Page 46: 专题三 低级用户界面

Hands-On 实训教程系列

绘制直线

可以调用 Graphics 类的 drawLine 方法在屏幕上绘制一条直线: public void drawLine(int x1,int y1,int x2,int y

2)(x1,y1) 和 (x2,y2) 分别代表直线两个端点的坐标值

//DrawLineCanvas 类演示了 drawLine 方法的使用 public class DrawLineCanvas extends Canvas {

protected void paint(Graphics g) {

g.drawLine(5, 5, 3, 60);

g.drawLine(3, 60, 55, 100);

g.drawLine(55, 100, 5, 5);

}

}

Page 47: 专题三 低级用户界面

Hands-On 实训教程系列

设置字体 -1

Font 类 -1 Font 类封装了字体的属性信息。 属性主要分为三种:字型、外观和字号,属性及

属性值由 Font 类中定义的常量表示:字型属性:

– STYLE_PLAIN : 0 ,表示“普通”– STYLE_BOLD : 1 ,表示“粗体”– STYLE_ITALIC : 2 ,表示“斜体”– STYLE_UNDERLINED : 4 ,表示“下划线”

Page 48: 专题三 低级用户界面

Hands-On 实训教程系列

设置字体 -2

Font 类 -2外观属性:

– FACE_SYSTEM : 0 ,表示“系统字体”– FACE_MONOSPACE : 1 ,表示“等宽字体”– FACE_PROPORTIONAL : 64 ,表示“均衡字体”

字号属性:– SIZE_MEDIUM : 0 ,表示“中号”– SIZE_SMALL : 8 ,表示“小号”– SIZE_LARGE : 16 ,表示“大号”

字体属性之间可以利用“ |” 操作符组成位运算表达式 – Font.FACE_MONOSPACE | Font.STYLE_UNDERLINED |

Font.SIZE_LARGE

Page 49: 专题三 低级用户界面

Hands-On 实训教程系列

设置字体 -3

字体属性组合规则 外观属性之间不能组合,例如 FACE_SYSTEM |

FACE_MONOSPACE 是非法的 字号属性之间不能组合,例如 SIZE_SMALL | SIZE_LARGE 是非法的

字型属性中 SYTLE_PLAIN不能与其他字型组合使用,因为它的值是 0 。而其他三种字型可以随意组合使用

Page 50: 专题三 低级用户界面

Hands-On 实训教程系列

设置字体 -4

创建字体的方式 无法通过构造方法创建 Font 类的对象 利用 Font 类提供的三个静态方法获取 Font 对

象的引用 public static Font getDefaultFont() public static Font getFont(int face,int style,int siz

e)public static Font getFont(int fontSpecifier)

//FontSetCanvas 类演示了如何设置字体 public class FontSetCanvas extends Canvas {

protected void paint(Graphics g) {

// 获取字体引用 Font f = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD

| Font.STYLE_ITALIC, Font.SIZE_SMALL);

// 将绘图环境的字体设置为带下划线、粗体的小号均衡字体 g.setFont(f);

}

}

Page 51: 专题三 低级用户界面

Hands-On 实训教程系列

绘制文本 -1

Graphics 类提供了 4 个绘制文本的方法 drawChar(char character,int x,int y,int ancho

r) drawChars(char[] data ,int offset, int length, i

nt x, int y, int anchor) drawString(String str ,int x, int y, int anchor) : drawSubstring(String str,int offset, int len, in

t x, int y, int anchor)

什么是 anchor?

Page 52: 专题三 低级用户界面

Hands-On 实训教程系列

绘制文本 -2

屏幕上绘制的文本都被限制在一个虚拟的矩形框中

锚点就是虚拟方框上指定的几个特殊位置,可以减少定位字符串时所需的计算量

Page 53: 专题三 低级用户界面

Hands-On 实训教程系列

绘制文本 -3

锚点: Graphics.HCENTER : 1 ,代表文本或图像围绕锚点水平中央放置 Graphics.VCENTER : 2 ,代表图像围绕锚点水平中央放置(该值不能用于文本)

Graphics.LEFT : 4 ,代表锚点位于文本或图像的左边缘 Graphics.RIGHT : 8 ,代表锚点位于文本或图像的右边缘 Graphics.TOP : 16 ,代表锚点位于文本或图像的上边缘 Graphics.BOTTOM : 32 ,代表锚点位于文本或图像的下边缘 Graphics.BASELINE : 64 ,代表锚点位于文本的基线(该值不能

用于图像)演示绘制字符串的示例代码

Page 54: 专题三 低级用户界面

Hands-On 实训教程系列

按键事件 -1

按键事件 当用户按下某个按键时触发 Canvas 类本身就具有处理按键事件的能力 子类可以有选择的重写以下三个方法:

keyPressed(int keyCode) :处理按键按下事件keyReleased(int keyCode) :处理按键释放事件keyRepeated(int keyCode) :处理按键重复按下事

件– 每个按键处理方法都包含一个 keyCode 参数,该参数称为

“键码”

Page 55: 专题三 低级用户界面

Hands-On 实训教程系列

按键事件 -2

//KeyEventTestCanvas 类演示了按键事件的处理 public class KeyEventTestCanvas extends Canvas {

protected void paint(Graphics g) {}

// 处理按键按下事件 protected void keyPressed(int keyCode) {

System.out.println(" 按下了名为 "

+ getKeyName(keyCode)

+ " 的按键,键码值是 " + keyCode);

}

}

Page 56: 专题三 低级用户界面

Hands-On 实训教程系列

游戏动作 -1

游戏键 在游戏程序中,经常将一些特殊的按键定义为游

戏键 游戏键通常用作“方向键”或“执行键” 不同设备上的游戏键定义可能会有所差异

为了提高程序的可移植性, Canvas 类为游戏中的常用按键定义了游戏动作

可以利用 getGameAction 方法将普通的键码转换为游戏动作键码

Page 57: 专题三 低级用户界面

Hands-On 实训教程系列

游戏动作 -2

//GameActionEventTestCanvas类演示了对游戏键事件的处理 public class GameActionEventTestCanvas extends Canvas {

protected void keyPressed(int keyCode) {//重写了 keyPressed方法,处理按键按下事件 int gameKeyCode = getGameAction(keyCode); //将普通键码转换为游戏动作 String gameEventStr = null;

switch (gameKeyCode) {

case UP:

gameEventStr = " ↑方向键 ";

break;

case DOWN:

gameEventStr = " ↓方向键 ";

break;

case LEFT:

gameEventStr = " ←方向键 ";

break;

case RIGHT:

gameEventStr = " →方向键 ";

break;

case FIRE:

gameEventStr = "开火键 ";

break;

case GAME_A:

gameEventStr = " 游戏键 A";

break;

case GAME_B:

gameEventStr = " 游戏键 B";

break;

case GAME_C:

gameEventStr = " 游戏键 C";

break;

case GAME_D:

gameEventStr = " 游戏键 D";

break;

default:

gameEventStr = "非游戏键 ";

break;

}

System.out.println("您按下了 " + gameEventStr);

}

//... 这里省略了 paint 方法的实现代码 }