×

关注微信公众号

免备案网站空间虚拟主机双线空间域名查询PS数码后期
photoshop互助课堂数百G视频教程下载英语培训机构初中英语如何学随时随地聆听大师开讲/课堂
软件安装教程 远程服务 超值!手绘教程抠图教程路径专辑photoshop cs3视频教程
楼主: vogue

[java] 清华大学:王克宏教授讲JAVA

    [复制链接]
 楼主| 发表于 2006-3-3 09:04:37 | 显示全部楼层

第十七讲 交互效果(三)

教 学 纲 要


有了 Java , 你 和 Homepage 的 交 互 不 仅 仅 是 点 击 某
个 字 、 按 钮 或者 图 , 它 切 换 成 下 一 页 。 Java
为 浏 览 Homepage 的 用 户 提 供了 地 地 道 道 的 交 互
。 包 含 了 Java 程 序 的 Homepage 知 道 你 需要 它 做 什
么 , 而 不 是 简 简 单 单 地 切 换 到 下 一 页 。

·猜 一 猜 我 敲 了 哪 个 键  

·勇 敢 的 冲 浪 小 子
——————————————————————————

猜 一 猜 我 敲 了 哪 个





现 在我 们 已 经 能 够 处 理 鼠 标 产 生 的 各 种 事
件 , 对 鼠 标 的 各 种操 作 作 出 相 应 的 反 应 。
和 鼠 标 比 起 来 , 键 盘 产 生 的 动 作要 简 单 得
多 , 因 为 键 盘 不 像 鼠 标 那 么 活 跃 , 能 够 在
屏 幕里 蹿 上 跳 下 。 键 盘 要 规 矩 得 多 , 它 只
会 产 生 两 种 事 件 : KEY_PRESS 和 KEY_RELEASE 。 当 你
按 下 键 盘 上 的 任 意 一 个 键 , 就会 产 生 KEY_PRESS
( 按 下 键 盘 ) 事 件 , 而 放 开 已 按 下 的 按
键时 , 则 发 生 KEY_RELEASE ( 松 开 键 盘 ) 事 件 。 你
会 不 会 觉 得这 两 个 事 件 似 曾 相 识 ? 对 了 ,
它 们 很 像 MOUSE_DOWN 和 MOUSE_UP , 同 样 是 按 下 按 键
和 释 放 按 键 。 和 对 鼠 标 按 键 一 样 , 我们 更
关 心 的 是 什 么 键 被 按 下 , 而 不 是 什 么 键 被
释 放 。 所以 我 们 通 常 所 处 理 的 也 是 KEY_PRESS (
按 下 键 盘 ) 这 个 事 件。



你 可以 通 过 键 盘 告 诉 你 HomePage 里 的 小 人 向 左
、 向 右 , 也 可 以写 一 些 只 有 你 才 懂 的 密 码
。 要 实 现 这 些 功 能 , 你 只 需 要把 想 做 的 事
情 写 到 keyDown 或 keyUp 方 法 里 。 一 旦 你 按 下 了某
个 键 , 系 统 就 把 事 情 交 给 这 两 个 方 法 来 干
。 那 么 方 法 keyDown 和 keyUp 是 什 么 样 子 呢 ?


    public boolean keyDown ( Event evt , int key
) { … … }

    public boolean keyUp ( Event evt , int key ) {
… … }



你 也许 发 现 了 , 这 两 个 方 法 同 前 面 处 理 鼠
标 事 件 的 方 法 都 不太 一 样 。 evt 仍 然 表 示 事
件 本 身 , keyDown 中 的 evt 表 示 KEY_PRESS ( 按 下 键
盘 ) 这 一 事 件 , keyUp 中 的 evt 表 示 KEY_RELEASE (
释放 键 盘 ) 。 那 么 整 数 key 表 示 什 么 呢 ? 它
表 示 所 按 下 键 的键 值 。 键 盘 可 不 像 鼠 标 把
所 有 的 键 都 一 视 同 仁 , 键 盘 上的 每 一 个 键
都 有 一 个 特 定 的 值 与 之 相 对 应 。 也 就 是 说
,为 了 区 分 键 盘 上 的 键 , 我 们 给 每 个 键 都
编 了 号 , 这 个 编号 就 是 该 键 的 键 值 。 而 且
这 个 编 号 也 不 是 随 随 便 便 编 出来 的 , 而 是
该 键 所 对 应 字 符 的 ASCII 码 。 对 于 那 些 没 有
ASCII 码 的 按 键 , Java 在 Event 类 中 已 经 定 义 好 了
一 些 标 准 键 值, 这 些 特 殊 键 所 对 应 的 值 如
表 17.1 所 示 :


表 17.1 Event 类 里 面 的 标 准 键

[见附件]

勇 敢 的 冲 浪 小 子




不 要以 为 键 盘 只 能 产 生 两 个 简 单 的 事 件 就
没 有 什 么 意 思 , 试一 试 下 面 这 个 程 序 , 你
就 会 发 现 键 盘 和 鼠 标 一 样 有 意 思。

程 序 17.4

  1. // key.java

  2. import java.awt.Graphics;

  3. import java.awt.Event;

  4. import java.awt.Image;


  5. public class key extends java.applet.Applet

  6. { char PressKey = 0;        // 初 始 化 设


  7.   int x = 5,y =15;

  8.   Image surfer ;          // 定 义 一 个
  9. 名 为 surfer 的 Image 对 象

  10.   public void init( )

  11.   { surfer = getImage(getDocumentBase( ),"surfer.gif")
  12. } // 加 载 图 片

  13.   public boolean keyDown (Event evt,int key0)  //
  14. “ 键 盘 按 下 ” 事 件 处 理

  15.   { switch(key0)

  16.     {case Event.UP:     // 按 下 ↑ 时 y 坐
  17. 标 减 1

  18.     y--;

  19.     break;

  20.     case Event.DOWN:     // 按 下 ↓ 时 y
  21. 坐 标 加 1

  22.     y++;

  23.     break;

  24.     case Event.LEFT:     // 按 下 ← 时 x
  25. 坐 标 减 1

  26.     x--;

  27.     break;

  28.     case Event.RIGHT:     // 按 下 → 时 x
  29. 坐 标加 1

  30.     x++;

  31.     break;

  32.     default:           // 按 下 除 四
  33. 个 键 外的 键 时 ,

  34.     PressKey = (char)key0;  // 就 给 出 该 键
  35. 键 值对 应 的 字 符

  36.     break;

  37.   }

  38.   repaint( );

  39.   return true;

  40.   }

  41.   public void paint(Graphics g)

  42.   { if (PressKey!=0)

  43.     g.drawString("Press Up, Down, Left and
  44. Right arrow to move the surfer.",10,15);

  45.     g.drawImage (surfer,x,y,this);    // 根 据
  46. ↑ 、 ↓ 、 → 、 ← 改 变 的 (x , y) 输 出 图 片

  47.     g.drawString("You have pressed "+PressKey+"
  48. just now!",10,250); // 输 出 所 按 下 的 键

  49.   }

  50. }
复制代码



程 序 17.4 的 HTML 文 件 是 如 下 所
示 :

< HTML>

< HEAD> < TITLE>key< /TITLE> <
/HEAD>

< BODY>

< APPLET CODE = "key.class" WIDTH = 500
HEIGHT = 260>< /APPLET>

< /BODY>

< /HTML>



运 行程 序 时 , 看 看 提 示 行 信 息 , 按 一 下 空
格 键 , 一 只 冲 浪 企鹅 就 会 出 现 在 你 的 眼 前
, 按 ↑ 、 ↓ 、 → 、 ← 键 , 你 将 看到 它 勇 往
直 前 地 在 你 的 主 页 上 冲 浪 。 如 果 你 偷 偷 按
了 字符 键 , 程 序 能 猜 出 你 按 的 是 哪 一 个 键
。 不 信 你 可 以 试 一试 。



怎 么样 ? 可 以 交 互 的 Java 程 序 是 不 是 比 那 些
静 态 的 图 形 、 文字 有 意 思 多 了 ? 这 回 你 知
道 电 子 游 戏 里 的 金 钢 是 怎 么 在你 的 鼠 标 和
键 盘 的 控 制 下 , 所 向 披 靡 了 吧 。


图 17.5 程 序 17.4 的 运 行 结 果


小 结



学 习了 这 一 章 , 你 应 该 知 道 什 么 呢 ? 总 结
一 下 吧 。




Java 通 过 Event 类 来 处 理 鼠 标 键 盘
事 件 。

可 以 在 mouseDown 里 处 理 鼠 标 按 下
这 个 事 件 , 鼠标 按 下 了 , 你 想 做 什 么 就
把 想 做 的 事 情 写 在 mouseDown 这 个方 法 里 。

鼠 标 还 能 产 生 移 动 (mouseMove) 、
拖 动 (mouseDrag) 、 进 入 (mouseEnter) 、 离 开 (mouseExit)
等 许 多 事 件 , 我 们 可 以在 它 们 对 应 的 事
件 处 理 中 做 任 何 想 做 的 事 情 。

键 盘 会 产 生 按 下 (keyPress) 和 释 放
(keyRelease) 两个 事 件 , 通 常 我 们 只 处 理 KeyPress
事 件 , 处 理 这 个 事 件 的代 码 就 写 在 方 法
keyDown 里 。

鼠 标 按 键 对 Java 而 言 是 没 有 区
别 的 , 但 键 盘 上的 每 个 键 都 有 各 自 的 键
值 代 表 特 定 的 字 符 。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?[立即注册]

x
 楼主| 发表于 2006-3-3 09:08:15 | 显示全部楼层

第十八讲 动画制作及声音载入(一)

酷素材
教 学 纲 要

Java 世界 里 最 激 动 人 心 的 时 刻 终 于 到 来 了 , 在 这 一 章 里
你 将 学到 在 主 页 里 播 放 动 画 的 技 巧 , 以 及 载 入 和 播 放 声 音 的 方法 , 掌 握 了 本
章 所 讲 授 的 这 些 技 巧 , 再 加 上 你 脑 子 里 各种 希 奇 古 怪 的 念 头 , 你 就 有 能 力 创
造 出 你 自 己 的 真 正 活灵 活 现 、 有 声 有 色 的 活 动 Web 主 页 来 。
————————————————————————-

·学 习 动 画 原 理

·了 解 多 线 程 的 工 作 过 程

·利 用 多 线 程 制 作

·在 动 画 里 加 入 背 景 音 乐


    想 像 一 下 , 当 别 人 正 在 浏 览 你 的 主 页 时, 突 然 有 个 小 丑
向 他 做 了 个 鬼 脸 , 跑 出 一 只 甲 虫 在 你 的主 页 上 载 歌 载 舞 , 或 者 不 知 道 从 哪 里 冒
出 点 儿 声 儿 来 吓他 一 跳 , 那 将 是 多 么 让 人 欣 喜 的 事 情 。 这 也 正 是 Java 的迷 人 之
处 , 它 能 在 你 不 注 意 的 时 候 给 你 一 个 惊 喜 。 如 今我 们 到 处 都 能 听 到 或 看 到 所 谓
活 动 Web 主 页 ( Live Web Page ) , 是 不 是 很 吸 引 人 呢 ?



孙 悟 空 的 筋 斗 是 怎 么 翻出 来 的 ?


    我 们 知 道 电 影 是 一 张 张 电 影 胶 片 在 放映 机 前 滚 过 ,
在 银 幕 上 投 影 出 动 态 的 画 面 , 动 画 片 是 由一 组 差 异 很 小 的 图 片 组 合 在 一 起 ,
快 速 地 切 换 这 些 图 片, 你 所 看 到 的 就 是 一 个 在 翻 跟 头 的 孙 悟 空 。 那 么 计 算 机上
的 动 画 也 是 这 样 做 出 来 的 吗 ? 基 本 原 理 差 不 多 。 首 先要 有 一 组 连 续 动 作 的 图
片 , 然 后 只 需 要 快 速 地 用 这 一 组图 片 顺 序 刷 新 显 示 器 上 的 画 面 就 可 以 看 到 一
张 张 静 态 的画 面 变 成 一 段 可 爱 的 动 画 片 段 了 。


    所 以 用 Java 来 实 现 动 画 实 在 是 再 简 单 不过 了 , 你 肯
定 马 上 就 想 到 了 前 面 已 经 学 过 的 加 载 和 显 示图 片 。 既 然 制 作 动 画 最 基 本 的 两
个 步 骤 你 都 会 了 , 那 还有 什 么 能 难 得 住 你 呢 ? 现 在 你 已 经 会 用 getImage 把
一 个 图形 文 件 加 载 到 Java 程 序 中 , 并 用 drawImage 把 加 载 进 来 的 图片 输 出 到
你 的 Applet 窗 口 中 。 ( 如 果 getImage 和 drawImage 这两 个 方 法 你 忘 了 的 话
, 请 参 阅 第 十 二 章 。 ) 问 题 是 在 这一 章 中 我 们 将 加 载 的 不 是 单 张 的 图 片 , 而
是 一 组 图 片 ,并 依 次 每 隔 一 段 时 间 就 显 示 一 张 。 我 们 怎 么 控 制 它 什 么时 候 该
换 掉 旧 的 显 示 新 的 呢 ? 问 得 好 ! 这 就 是 下 面 要 讲的 问 题 。  


    动 画 效 果 的 好 坏 不 仅 仅 取 决 于 画 面 是否 漂 亮 , 而 且
还 取 决 于 动 画 中 动 作 的 平 滑 程 度 。 我 们 当然 不 希 望 看 到 自 己 主 页 里 的 动 画 动
起 来 像 僵 硬 的 木 偶 ,要 让 你 的 动 画 看 上 去 动 作 连 贯 平 滑 就 需 要 控 制 切 换 图 片的
速 度 。 可 想 而 知 , 相 同 时 间 内 放 映 的 图 片 张 数 越 多 ,动 画 中 人 物 的 动 作 看 上
去 就 越 平 滑 。  


    那 么 Java 到 底 靠 什 么 来 决 定 何 时 显 示 图片 、 何 时 更
换 图 片 呢 ? 当 然 是 时 钟 。 每 台 计 算 机 内 部 都有 一 个 很 精 确 的 时 钟 , 计 算 机 依
赖 它 才 能 有 条 不 紊 地 进行 工 作 。 我 们 可 以 对 显 示 的 每 一 帧 图 片 计 时 , 一 到 规
定时 间 就 把 它 撤 换 掉 , 定 时 地 顺 序 地 替 换 组 成 动 画 的 每 一帧 画 面 , 画 不 就 动
起 来 了 吗 ? 那 我 们 用 什 么 来 计 时 呢 ?线 程 ! 这 是 最 好 的 解 决 办 法 。 支 持 多 线
程 也 是 Java 的 一大 特 征 。




什 么 是 线 程 ?



    " 线 程 ” 这 个 词 似 乎 听 说 过 。 其 实 它 的确 也 没
有 什 么 神 秘 的 , 线 程 就 是 执 行 中 的 一 段 程 序 。 举个 生 活 中 的 例 子 : 生 活 中 很
多 事 情 都 可 以 看 作 是 线 程 ,比 如 吃 饭 、 睡 觉 、 看 书 、 工 作 … … 有 时 候 为 了 提
高 效 率, 你 可 能 会 同 时 做 几 件 事 , 每 一 件 事 叫 做 一 个 线 程 , 那么 你 就 工 作 在
多 线 程 状 态 下 了 。 假 设 你 正 在 准 备 晚 餐 ,微 波 炉 里 正 烤 着 面 包 , 咖 啡 壶 里 正
煮 着 咖 啡 , 你 也 许 正在 煤 气 灶 边 忙 着 煎 鸡 蛋 。 你 得 不 时 地 关 照 着 微 波 炉 和 咖啡
壶 , 还 得 注 意 不 要 把 蛋 煎 糊 了 , 如 果 电 话 铃 响 了 , 你还 得 把 电 话 夹 在 腋 窝 下
接 电 话 。 那 我 要 说 你 简 直 是 个 效率 专 家 , 你 正 在 完 成 多 线 程 任 务 。



图 18.1 什 么 是 多 线 程  


    其 实 Java 就 是 一 种 能 让 CPU 忙 得 团 团 转的 语 言 , 因
为 它 支 持 多 线 程 。 它 可 以 让 CPU 同 时 从 从 网 络上 读 取 数 据 、 等 待 用 户 的 输 入
、 在 屏 幕 上 显 示 动 画 , 并且 向 打 印 机 发 出 打 印 指 令 。 你 看 Java 通 过 它 的 多
线 程 机制 大 大 地 提 高 了 CPU 的 工 作 效 率 。


    既 然 多 线 程 是 这 么 一 个 好 东 西 , 我 们何 不 利 用 它 呢
。 听 起 来 似 乎 挺 复 杂 , 其 实 使 用 多 线 程 的过 程 很 简 单 。 只 要 遵 循 固 定 的 步 骤
, 一 步 步 地 在 程 序 里加 入 我 们 想 做 的 事 情 就 可 以 了 。     1.用 你 所 编 的 Applet
去 实 现 Runnable 接 口 。

    2.在 方 法 start 中 产 生 一 个 新 的 工 作 进程 。

    3.在 方 法 stop 中 编 写 结 束 线 程 要 处 理 的事 情 。

    4.加 一 个 run 方 法 , 在 这 个 方 法 中 写 你想 让 新 产 生 的
那 个 线 程 做 的 事 情 , 其 实 就 是 给 新 线 程 分配 任 务 。


    哦 ! 我 又 糊 涂 了 , 又 是 线 程 , 又 是 方法 , 还 有 什 么
接 口 。 我 们 下 面 就 一 步 一 步 地 讲 。


第 一 步 : 让 你 的 Applet 实 现 Runnable 接 口 。


    这 并 不 难 理 解 , 我 们 可 以 把 每 个 程 序看 作 一 个 线 程
, 它 从 开 始 到 结 束 只 能 干 一 件 事 。 如 果 你想 让 它 同 时 干 两 件 事 , 就 必 须 在 原
来 那 个 程 序 里 加 上 Runnable 接 口 以 便 让 连 贯 线 程 能 够 同 时 工 作 。 举 个 例 子
来 说 , 一个 电 源 插 座 上 只 能 插 一 个 电 器 , 如 果 你 正 在 看 电 视 , 就不 能 使 用 录
像 机 , 可 是 你 想 把 好 看 的 节 目 录 下 来 , 非 用录 像 机 不 可 , 怎 么 办 呢 ? 聪 明 的
你 马 上 就 想 到 加 一 个 插线 板 问 题 就 解 决 了 。 在 这 里 Runnable 接 口 就 是 线 程
的 插 线板 , 只 要 你 的 Applet 实 现 了 Runnable 接 口 , 它 就 可 以 成 为 多线 程 程
序 了 , 而 且 实 现 Runnable 接 口 也 的 确 和 加 一 个 插 线板 一 样 简 单 , 你 只 需 要
这 样 写 :     public class cartoon extends java.applet.Applet  implements
Runnable { … … }

这 句 话 的 前 面 一 部 分 , 我 们 都 已 经 很 熟 悉了 , cartoon 是
你 的 Applet 的 名 字 , implements Runnable 就 是 咱们 的 插 线 板 。


第 二 步 : 在 Start 方 法 里 产 生 一 个 新 的 线 程。


    在 Java 里 线 程 也 被 当 作 一 个 类 。 类 Thread 封 装 了
所 有 有 关 线 程 的 控 制 , 用 来 控 制 线 程 的 运 行 、 睡眠 、 挂 起 和 中 止 。 Thread
类 是 唯 一 可 以 用 来 控 制 线 程 的 手段 。 start 的 实 现 很 简 单 。

    public void start ( )

    {    if (thread1 == null )

        {    thread1 = new Thread ( this ) ;

            thread1. start ( ) ;

        }

    }

方 法 start 里 产 生 了 一 个 新 的 进 程 , 当 start( ) 执 行 完
以 后 , 程 序 里 就 有 了 两 个 线 程 在 同 时 工 作 , 一个 是 原 来 的 程 序 , 另 一 个 则 是
由 start( ) 产 生 的 , start( ) 中 产 生 的 这 个 线 程 完 成 下 面 将 谈 到 的 方 法
run 中 指 定 的 任务 。





第 三步 : 在 方 法 stop( ) 里 把 start( ) 产 生 的 一 个 线 程 关 掉 , 中止 线 程 的
工 作 , 并 释 放 线 程 , 用 stop 中 止 的 线 程 将 不 能再 启 动 , 也 就 是 说 这 个 线 程
已 经 死 了 , 所 以 应 该 释 放 它。 Stop 方 法 应 该 这 样 写 :

    public void stop ( )

    {    thread1.stop ( ) ;

        thread1 = null ;    }


第 四 步 : 在 run( ) 方 法 里 给 新 产 生 的 进 程 分配 任 务 。


    run 是 线 程 的 核 心 , 在 这 个 方 法 里 , 我们 将 写 入 新 线 程 工 作 的 程 序 代
码 , 告 诉 这 位 新 来 的 线 程先 生 该 做 什 么 。 事 实 上 你 可 以 在 方 法 run 里 做 任 何
你 想 做的 事 情 , 原 来 的 那 个 线 程 并 不 会 因 为 它 而 受 到 什 么 影 响, 因 为 它 们 是
两 个 完 全 独 立 的 线 程 , 互 不 干 扰 。 这 里 还要 提 一 句 , 除 了 stop 可 以 中 止 线
程 的 工 作 外 , run 中 的 程序 代 码 一 旦 执 行 结 束 , 线 程 也 会 自 动 中 止 。


    好 啦 ! 讲 了 这 么 多 , 不 知 道 你 清 楚 了没 有 ? 如 果 你 还 是 觉 得 云 山 雾 罩
, 没 有 关 系 , 只 要 你 照着 这 四 个 步 骤 一 步 步 来 , 你 仍 然 能 很 容 易 写 出 一 个 像
模像 样 的 多 线 程 程 序 来 。 下 面 就 让 我 们 来 试 试 吧 。



翻 筋 斗 的 小 企 鹅



    这 一 章 不 是 讲 动 画 吗 ? 怎 么 又 讲 这 么一 大 堆 线 程 的
东 西 ? 这 是 因 为 要 编 出 一 个 好 的 具 有 动 画效 果 的 Java 程 序 , 就 必 须 利 用 线
程 。 所 以 前 面 我 们 是 在为 这 一 节 打 基 础 , 现 在 我 们 已 经 知 道 怎 样 启 动 和 中 止
一个 线 程 , 怎 样 在 方 法 run 中 指 定 线 程 工 作 。 那 么 就 把 它 用到 咱 们 的 动 画 程
序 里 来 吧 !

程 序 18.1
  1. // animate.java

  2. import java.awt.*;


  3. public class animate extends java.applet.Applet
  4. implements Runnable        // 实 现 Runnable 接 口

  5. {

  6.     Image frame[ ];            // 说 明 一 个 Image
  7. 数 组 , 准 备 放 动 画 图 片

  8.     Thread thd;            // 说 明 一 个 Thread ( 线
  9. 程 ) 对 象

  10.     int num;            // 设 置 计 算 帧 数的 计 数 器

  11.     int pause;            // 设 置 每 帧 显 示的 时 间


  12.     public void init( )

  13.     {

  14.         String fps;            // 设 置 每秒 切 换 图 片
  15. 的 张 数

  16.         frame = new Image[17];    // 构 造 Image 数
  17. 组 , 共 包 含 17 个 元 素

  18.         thd = null;                // 初始 化 线 程

  19.         num = 0;            // 计 数 器 置 0

  20.         for (int i = 0; i < frame.length; i++)  
  21. // 加 载 图 片

  22.         frame[i] = getImage(getCodeBase( ), "images/T"
  23. + i + ".gif");

  24.         fps = getParameter("speed"); 
  25.   // 从 HTML 文 件 读 入 参 数 speed , 确 定 放 映 速 度

  26.         if (fps == null)    // 如 果 HTML 中 未指 定 参
  27. 数 , 则 用 省 缺 的 放 映 速 度

  28.         fps = "10";            // 为 每
  29. 秒 10 帧

  30.         pause = 1000 / Integer.parseInt(fps);   
  31. // 计 算 每 帧 图 片 显 示 的 时 间

  32.     }

  33.     public void start( )

  34.     {

  35.         if (thd == null)

  36.         {

  37.             thd = new Thread(this);    // 在 start(
  38. ) 方 法 里 产 生 一 个 新 线 程 , 名 为 thd

  39.             thd.start( );        // 启 动 这个 新 线 程

  40.         }

  41.     }

  42.     public void stop( )

  43.     {

  44.         if (thd != null)

  45.         {

  46.             thd.stop( );        // 在 stop( ) 方 法
  47. 里 中 止 线 程 thd

  48.             thd = null;        // 释 放 线程        
  49. }

  50.     }

  51.     public void run( )

  52.     { while (true)

  53.         { try { Thread.sleep(pause); }    // 让线
  54. 程 睡 眠 每 一 帧 图 片 的 显 示 的 时 间

  55.         catch (InterruptedException e) {}

  56.         repaint( );            // 重 画 窗口

  57.         num = (num + 1) % frame.length;    // 计数
  58. 器 增 1

  59.         }

  60.     }

  61.     public void paint(Graphics g)

  62.     {

  63.         g.drawImage(frame[num], 0, 0, this);   
  64. // 显 示 计 数 器 指 定 的 那 帧 图 片

  65.     }

  66.     public void update(Graphics g)

  67.     {

  68.         paint(g);

  69.     }

  70. }
复制代码


该 程 序 的 HTML 文 件 如 下 所 示 :


< HTML>

< HEAD>

< TITLE>animate< /TITLE>

< /HEAD>

< BODY>

< APPLET CODE = "animate.class" WIDTH
= 130 HEIGHT = 80>

< param name = "speed" value = "5">

< /APPLET>

< /BODY>

< /HTML>

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?[立即注册]

x
 楼主| 发表于 2006-3-3 09:11:33 | 显示全部楼层

第十九讲 动画制作及声音载入(二)

教 学 纲 要


Java 世界 里 最 激 动 人 心 的 时 刻 终 于 到 来 了 , 在 这 一 章 里
你 将 学到 在 主 页 里 播 放 动 画 的 技 巧 , 以 及 载 入 和 播 放 声 音 的 方法 , 掌 握 了 本
章 所 讲 授 的 这 些 技 巧 , 再 加 上 你 脑 子 里 各种 希 奇 古 怪 的 念 头 , 你 就 有 能 力 创
造 出 你 自 己 的 真 正 活灵 活 现 、 有 声 有 色 的 活 动 Web 主 页 来 。
__________________________________________________

先 不忙 看 程 序 运 行 结 果 , 我 敢 打 赌 这 个 程 序 里 一 定 有 好
几 个地 方 你 还 不 太 理 解 , 那 就 让 我 们 先 来 看 看 这 几 条 令 人 不解 的 语 句 :


1. fps = getParameter("speed");

    这 条 语 句 的 意 思 是 从 HTML 文 件 接 受 一个 名 叫 speed
的 参 数 。 很 多 时 候 我 们 希 望 自 己 控 制 程 序 的运 行 情 况 , 在 这 个 程 序 里 我 们 希
望 能 够 用 一 种 比 较 容 易的 方 法 来 改 变 动 画 的 放 映 速 度 , 而 不 是 到 程 序 源 代 码
里直 接 修 改 程 序 里 的 某 条 语 句 , 然 后 重 新 编 译 程 序 。 的 确完 成 这 样 的 修 改 是
工 程 浩 大 的 , 也 不 是 一 般 人 所 能 胜 任的 。 于 是 我 们 就 想 到 了 利 用 参 数 。 只 要
给 定 了 参 数 , 程序 执 行 时 就 会 按 照 给 定 的 参 数 去 执 行 了 。 那 么 Java 是 从那 里
得 到 参 数 的 呢 ? 我 们 都 知 道 , Java 程 序 是 通 过 编 写 HomePage 的 HTML 文 件
加 载 到 WWW 浏 览 器 里 执 行 的 , 自 然 而 然, 我 们 就 想 到 了 让 Java 程 序 到 包 含
了 它 的 那 个 HTML 文 件 里去 读 取 参 数 。 为 了 使 Java 能 够 从 HTML 文 件 里 读 到
参 数 , 必须 满 足 两 个 条 件 :




在 HTML 文 件 里 , 必 须 用 标 签 , 指 定
参数 的 名 称 和 参 数 的 值 。

在 Java 源 程 序 中 , 必 须 用 方 法 getParameter 来 取得
参 数 值 。


这 回 你 该 明 白 为 什 么 HTML 文 件 里 会 多 出 这 样 一句 话 来 name ="speed" value="5">这 句 话 正 是 用 来 告 诉 Java
程 序 “ 放 映 速 度 为 每 秒 5 帧 ”

2. pause = 1000/integer.parseint(fps);

    根 据 我 们 的 定 义 , 在 这 条 语 句 中 的 pause 应 该 是 每
帧 图 片 显 示 的 时 间 , 在 Java 里 时 间 都 是 以 毫 秒为 单 位 的 , 所 以 这 里 1000 毫
秒 也 就 是 1 秒 , 不 难 理 解


每 张 图 片 在 屏 幕 上 停 留 的 时 间 = 1 秒 / 1 秒内 放 映 的 图
片 张 数


    根 据 这 个 算 式 , 理 解 这 条 语 句 就 很 容易 了 , 可 是 为
什 么 还 有 Integer.parseInt(fps) 呢 ? 要 知 道 HTML 里 的 变 量 都 是 字 符 型 的
, 即 使 是 数 字 5 , 它 也 仅 仅 是 一个 写 成 5 这 个 样 子 的 一 个 字 符 , 所 以 fps 一
开 始 就 被 说 明成 字 符 型 , 为 的 就 是 在 这 里 赋 值 时 不 至 于 类 型 不 匹 配 。那 么 既
然 fps 只 是 一 个 字 符 , 我 们 怎 么 能 把 它 放 到 数 学 算式 里 来 进 行 计 算 呢 ? 当 然
要 进 行 类 型 转 换 , 把 fps 这 个 字符 串 类 型 的 值 转 换 成 能 进 行 数 学 运 算 的 整 数
。 Integer.parseInt(fps) 就 是 完 成 这 一 功 能 的 。


3. try {Thread.sleep(pause);}

  catch(InterruptedException e){}


    这 是 什 么 东 西 ? 这 么 复 杂 。 哦 ! 请 你千 万 不 要 看 它
复 杂 就 轻 易 放 弃 。 try 和 catch 只 不 过 是 一 个防 止 意 外 的 保 险 栓 , 把 你 要 进
行 保 险 的 东 西 放 在 try 后 面的 {} 里 , 然 后 把 一 旦 发 生 意 外 要 进 行 的 处 理 写
在 catch 后面 的 {} 里 。 这 和 填 一 张 保 险 单 一 样 简 单 , 在 try 里 填 你 投保 的 东
西 , 在 catch 里 填 入 发 生 意 外 时 你 希 望 保 险 公 司 为你 做 的 事 。


    好 了 , 关 于 try 和 catch 我 们 在 后 面 的 章节 里 还 要
详 细 地 介 绍 。 在 这 个 程 序 里 我 们 把 Thread.sleep(pause) ; 这 条 语 句 投 了
保 , 不 过 没 有 对 它 进 行 什 么 意 外 处 理 ,因 为 catch 里 什 么 也 没 做 。 Thread.sleep(pause)
; 这 条 语 句 又是 什 么 意 思 呢 ? 再 容 易 理 解 不 过 了 , 它 就 是 “ 让 线 程 睡上 一 会
儿 ” , 睡 多 久 呢 ? 每 帧 图 片 显 示 时 间 多 久 , 它 就睡 多 久 。 pause 不 就 决 定 了
每 帧 图 片 显 示 的 时 间 吗 ?


4. num = ( num +1) % frame.length ;


    这 是 图 片 帧 数 的 计 数 器 , 每 放 完 一 帧图 片 , num 就
加 1 。 % 我 们 在 第 四 章 里 已 经 学 过 , 它 表 示取 模 运 算 , 再 说 简 单 一 些 , 就 是
计 算 余 数 。 在 这 里 我 们用 它 来 干 什 么 呢 ? 哦 ! 对 了 , 还 没 有 说 frame.length
呢 , frame 在 前 面 定 义 过 , 它 是 一 个 Image 数 组 , 包 含 了 动 画 的 一 组图 片 ,
frame.length 就 是 这 个 数 组 的 长 度 , 也 就 是 frame 所 包含 的 图 片 张 数 。 明
白 了 每 一 个 参 数 的 意 义 以 后 , 再 来 看看 算 式 吧 , 这 个 算 式 的 意 思 就 是 : 显 示
图 片 的 计 数 值 对图 片 的 总 张 数 取 模 。 为 什 么 要 这 样 做 呢 ? 如 果 不 对 图 片的 总
张 数 取 模 又 会 发 生 什 么 呢 ? 设 想 一 下 , 当 图 片 显 示到 了 最 后 一 张 , 再 没 有 图
片 可 供 显 示 了 , 你 想 让 动 画 再从 头 放 一 遍 , 也 就 是 从 第 一 张 开 始 再 重 新 来 一
遍 。 取 模就 是 完 成 这 个 功 能 的 , 它 让 显 示 的 图 片 可 以 再 次 从 头 开始 。 在 这 个
程 序 里 我 们 一 共 有 17 张 图 片 , 所 以 frame.length 等 于 17 , 当 计 数 器 num
计 到 16 时 , 已 经 没 有 图 片 可 以 显 示了 , ( 注 意 数 组 下 标 都 以 0 开 始 ) 应 该
显 示 第 0 张 , 所 以 num = (16 + 1 ) % 17 = 0 正 好 符 合 要 求 。


    好 啦 ! 现 在 你 对 程 序 的 理 解 应 该 更 清楚 了 。 看 看 程
序 的 运 行 结 果 吧 ! 程 序 运 行 起 来 会 有 一 只顽 皮 的 小 企 鹅 在 窗 口 里 翻 筋 斗 。 当
然 我 们 不 可 能 在 这 里看 到 那 只 会 动 的 小 企 鹅 , 不 过 小 企 鹅 翻 筋 斗 的 每 一 个 动作
都 在 这 里 了 ( 见 图 18.2 ) , 我 们 的 动 画 就 是 快 速 地 切换 这 些 图 片 , 让 它 动
起 来 。



图 18.2 动 画 的 每 一 帧 图 片



不 再 闪 烁 的 动 画


    看 了 上 面 的 程 序 , 你 可 能 会 觉 得 有 些不 尽 如 人 意 ,
小 企 鹅 翻 起 筋 斗 来 总 是 一 闪 一 闪 地 。 虽 然动 起 来 了 , 开 始 一 闪 一 闪 的 动 画 实
在 不 能 令 人 满 意 。 为什 么 我 们 的 小 动 画 会 有 这 种 讨 厌 的 闪 烁 呢 ? 有 没 有 办 法让
它 不 闪 烁 呢 ?


    不 知 道 你 还 记 不 记 得 前 一 章 讲 过 的 repaint 方 法 的
执 行 过 程 , 当 调 用 repaint 时 , 系 统 首 先 调 用 的 是 update, 省 缺 的 update
是 用 背 景 色 把 整 个 窗 口 重 刷 一 次 , 然后 再 调 用 paint 方 法 在 窗 口 里 画 出 要 显
示 的 内 容 。 为 什 么会 发 生 画 面 闪 烁 ? 现 在 就 应 该 比 较 清 楚 了 , 原 因 就 在 于我
们 每 次 调 用 repaint 重 画 窗 口 时 , 都 相 当 于 先 调 用 update 清 除 窗 口 里 的 所
有 画 面 , 然 后 再 调 用 paint 方 法 在 一 张 干净 的 纸 上 显 示 下 一 幅 画 面 。 这 样 重
复 的 清 除 画 面 , 又 重绘 画 面 就 造 成 了 动 画 的 闪 烁 。


    其 实 我 们 在 换 图 片 的 时 候 真 的 需 要 清除 所 有 画 面 再
重 画 它 吗 ? 完 全 没 有 必 要 。 我 们 只 需 要 用下 一 张 图 片 去 覆 盖 上 一 张 图 片 就 可
以 了 。 所 以 在 update 里, 我 们 不 再 需 要 清 除 画 面 , 而 是 直 接 调 用 paint 重
绘 画 面就 可 以 了 。 你 也 许 要 奇 怪 了 , 我 们 的 程 序 里 并 没 有 什 么 update 呀 ?
是 的 , 我 们 上 面 的 程 序 里 的 确 没 有 update 这 个方 法 , 可 是 正 如 我 们 前 面 提
过 的 , update 是 在 调 用 repaint 的 时 候 , 由 repaint 去 自 动 调 用 的 。 如 果
我 们 不 在 程 序 里重 写 一 个 新 的 update , 它 就 会 自 己 去 调 用 系 统 省 缺 的 那 个,
用 背 景 色 先 清 除 整 个 窗 口 。 如 果 你 不 想 要 系 统 省 缺 的那 个 笨 笨 的 update ,
你 只 需 要 在 程 序 里 写 上 自 己 的 update 就 行 了 。


    在 我 们 这 个 程 序 里 只 需 用 下 一 张 图 片去 覆 盖 上 一 张
图 片 , 而 无 需 先 清 除 窗 口 , 所 以 我 们 的 update 就 可 以 省 去 清 除 窗 口 这 一 步
, 直 接 调 用 paint 重 绘 窗 口 。那 么 这 就 在 程 序 里 加 上 我 们 自 己 的 update 方
法 吧 !

    public void update ( Graphics g ) { paint (g)
; }

    好 啦 ! , 闪 烁 的 问 题 就 解 决 了 。 不 信你 试 试 , 把 上 面
一 句 话 加 到 程 序 的 最 后 一 个 } 之 前 , 重新 编 译 一 次 , 看 看 运 行 结 果 是 不 是 好
多 了 呢 ?


连 续 的 筋 斗


    现 在 我 们 的 小 企 鹅 已 经 能 把 筋 斗 翻 得相 当 漂
亮 了 , 可 是 如 果 你 是 个 完 美 主 义 者 的 话 , 可 能 还是 感 到 有 些 美 中 不 足
。 这 只 小 企 鹅 怎 么 只 会 在 原 地 翻 筋斗 ? 能 让 它 连 续 地 翻 几 个 筋 斗 吗 ?
当 然 可 以 。 这 就 是 动画 常 见 的 另 一 种 效 果 , 在 固 定 的 背 景 上 , 一 边 放
映 主 角的 动 作 , 一 边 同 时 改 变 主 角 的 位 置 。 听 起 来 似 乎 挺 复 杂的 , 不
过 实 现 起 来 并 没 有 想 像 的 那 么 难 。 在 这 种 效 果 的动 画 里 , 除 了 前 面 讲
过 的 技 巧 外 , 我 们 所 要 做 的 就 是 加上 重 画 背 景 和 改 变 主 角 位 置 这 两 个
动 作 的 处 理 。


    制 作 这 样 的 动 画 , 除 了 需 要 一 组 连 续动 作 的
图 片 外 , 还 应 该 准 备 一 张 背 景 图 让 我 们 的 动 画 人物 以 此 为 背 景 来 进 行
表 演 。 我 们 想 让 小 企 鹅 连 续 地 翻 上好 几 个 筋 斗 , 就 需 要 在 显 示 图 片 的
同 时 改 变 显 示 的 位 置, 连 续 不 断 地 在 不 同 位 置 画 小 企 鹅 翻 筋 斗 的 图 片
是 不 是就 可 以 让 它 连 续 地 翻 筋 斗 了 呢 ? 还 不 行 。 每 次 显 示 完 上一 帧 图
片 后 , 我 们 还 必 须 用 背 景 图 去 重 画 一 次 背 景 , 然后 再 按 正 确 的 位 置 显
示 下 一 次 图 片 。 如 果 不 这 样 做 , 可以 想 像 , 背 景 图 上 就 会 留 下 每 个 动
作 的 残 迹 。 根 据 前 面的 分 析 , 我 们 需 要 做 的 修 改 实 际 就 在 run 和 paint
这 两 个 方法 里 。 在 run 里 修 改 图 片 显 示 的 位 置 , 在 paint 里 加 入 重 画背
景 图 的 动 作 。 那 么 就 来 看 看 修 改 过 的 程 序 是 什 么 样 子。 程 序 18.2 //
  1. tumble.java

  2. import java.awt.*;

  3. public class tumble extends java.applet.Applet
  4. implements Runnable

  5. {

  6.     Image frame[ ];    // 说 明 一 个 用 来 存 放动
  7. 画 图 片 的 Image 数 组

  8.     Thread thd;    // 说 明 一 个 线 程 对 象

  9.     int num;

  10.     int pause;

  11.     Image backgnd;    // 说 明 背 景 图 片

  12.     int x,x_pos ;    // 说 明 显 示 图 片 的 x 坐标


  13. public void init( )

  14. {

  15.     int i;

  16.     String fps;

  17.     frame = new Image[17];    // 初 始 化 Image
  18. 数组

  19.     thd = null;            // 初 始 化 线 程

  20.     num = 0;            // 初 始 化 计 数 器

  21.     for (i = 0; i < frame.length; i++) 
  22.   // 加载 动 画 图 片     frame[i] = getImage(getCodeBase( ), "images/T"
  23. + i + ".gif");

  24.     backgnd = getImage (getCodeBase( ),"images/backgnd.gif");
  25.   // 加 载 背 景 图 片

  26.     fps = getParameter("speed"); 
  27.   // 设 置 播 放速 度

  28.     if (fps == null)

  29.         fps = "10";

  30.     pause = 1000 / Integer.parseInt(fps); 
  31.   // 计算 每 帧 图 片 显 示 的 时 间

  32. }

  33. public void start( )

  34. {

  35.     if (thd == null)

  36.     {

  37.         thd = new Thread(this);    // 产 生
  38. 一个 新 线 程

  39.         thd.start( );    // 启 动 这 个 新 线 程

  40.     }

  41. }

  42. public void stop( )

  43. {

  44.     if (thd != null)

  45.     {

  46.         thd.stop( );    // 中 止 线 程

  47.         thd = null;    // 释 放 线 程

  48.     }

  49. }

  50. public void run( )

  51. {

  52.     while (true)

  53.     {

  54.         try { Thread.sleep(pause);    // 使
  55. 线程 睡 眠

  56.     }

  57.         catch (InterruptedException e) {};

  58.         repaint( );    // 重 画 窗 口

  59.         num = (num + 1) % frame.length;   
  60. // 为显 示 的 图 片 计 数

  61.         x = ((x+130+10)%(size( ).width+130+70))-130;
  62. // 计 算 下 一 帧 图 片 显 示 的 位 置

  63.         x_pos= size( ).width-x ;    // 调 整
  64. 图片 显 示 的 位 置

  65.     }

  66. }

  67. public void paint(Graphics g)

  68. {

  69.     g.drawImage(backgnd,0,0,this);    // 显
  70. 示 背景 图

  71.     g.drawImage(frame[num], x_pos, 0, this); 
  72.   // 显 示 动 画 图 片

  73.     }

  74.     public void update(Graphics g)

  75.     {

  76.         paint(g);

  77.     }

  78. }
复制代码
   
这 个 程 序 的 HTML 文 件 如 下 所 示 :

< HTML>

< HEAD>

< TITLE>tumble< /TITLE>

< /HEAD>

< BODY>

< APPLET CODE = "tumble.class"
WIDTH = 500 HEIGHT = 80>

< param name = "speed" value
= "5">

< /APPLET>

< /BODY>

< /HTML>


    看 看 程 序 运 行 结 果 , 一 只 会 连 续 翻 筋斗 的 小
企 鹅 高 高 兴 兴 地 在 你 的 主 页 上 玩 开 了 。



图 18.3 程 序 18.2 的 运 行 结 果  


    让 它 自 由 自 在 地 玩 吧 , 我 们 再 来 看 看程 序 。
程 序 18.2 比 程 序 18.1 增 加 了 几 句 话 :

1. 方 法 run 中 的

    x = ((x+130+10)%(size( ).width+130+70))-130;


    一 看 就 知 道 这 是 用 来 改 变 图 片 显 示 位置 的 ,
在 这 个 长 算 式 中 10 是 每 次 小 企 鹅 前 进 的 步 长 , size( ).width 指 的
是 运 行 这 个 Applet 窗 口 的 宽 度 , 此 外 我 们 还 考虑 了 每 一 帧 图 片 的 宽
度 和 窗 口 显 示 预 留 量 , 为 的 是 让 小企 鹅 从 画 面 右 侧 切 入 , 以 免 造 成 突
然 出 现 的 那 种 突 兀 的感 觉 。


2. 方 法 paint 中 的

    g.drawImage(backgnd,0,0,this);

    大 家 对 这 句 话 的 含 义 应 该 再 清 楚 不 过了 , 它 在
这 里 的 作 用 就 是 重 画 背 景 图 。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?[立即注册]

x
 楼主| 发表于 2006-3-3 09:12:53 | 显示全部楼层

第二十讲 动画制作及声音载入(三)

载 歌 载 舞 的 小 企 鹅




    啊 哈 ! 现 在 我 们 已 经 可 以 把 动 画 做 得相 当 不 错 了 ,
不 过 我 们 还 可 以 再 把 它 做 得 尽 善 尽 美 , 总不 能 让 我 们 的 动 画 是 无 声 片 吧 , 加
上 点 儿 声 音 的 确 是 个绝 妙 的 主 意 。 人 们 总 是 在 不 满 足 中 追 求 完 美 , 从 文 字 、图
形 到 动 画 , 虽 然 我 们 干 得 不 错 , 可 还 是 希 望 能 做 得 更好 , Java 恰 恰 为 你 的
精 益 求 精 提 供 了 支 持 , 你 可 以 在 Java 程 序 里 载 入 并 播 放 声 音 文 件 。


    和 Java 只 支 持 Gif 和 Jpg 两 种 图 形 文 件 一样 , 在 有
声 世 界 里 , 它 也 只 支 持 Au 这 一 种 声 音 文 件 的 格式 。 虽 然 这 不 是 一 种 CD 音 质
的 声 音 文 件 , 但 它 已 经 足 以让 你 为 之 欣 喜 若 狂 了 。 设 想 一 下 , 当 别 人 正 在 浏
览 你 的主 页 时 , 突 然 听 见 有 个 声 音 对 他 说 “ 欢 迎 光 临 ” , 那 该是 多 么 出 人 意
料 呀 !


    在 Java 程 序 里 加 载 声 音 文 件 就 如 同 在 你的 录 音 机 里
放 上 一 张 想 听 的 唱 片 一 样 简 单 。 声 音 文 件 的加 载 与 图 片 文 件 的 加 载 非 常 相 似
, 首 先 你 必 须 指 定 一 个包 含 有 声 音 文 件 的 URL , 然 后 用 加 载 声 音 文 件 的 方 法
来 加载 它 。 还 记 得 吗 , 加 载 图 片 时 我 们 用 的 是 getImage 这 个 方法 , 类 似 地 ,
加 载 声 音 我 们 用 到 的 方 法 叫 getAudioClip 。 在这 个 方 法 里 , 和 getImage 一
样 , 我 们 应 该 指 定 这 个 声 音 文件 存 放 的 URL , 当 然 Java 里 的 URL 既 可 以 是
本 地 硬 盘 也 可 以是 网 络 上 的 某 一 台 主 机 , 对 Java 而 言 它 们 是 一 样 的 。 和加 载
图 片 一 样 , 加 载 声 音 文 件 也 有 两 种 格 式

    AudioClip getAudioClip ( URL url ) ;

    AudioClip getAudioClip ( URL url , String name
);

    AudioClip 是 Java 定 义 的 一 个 类 , 用 它 来处 理 和 控
制 声 音 这 种 特 殊 的 数 据 对 象 。 使 用 它 就 可 以 方便 地 对 声 音 文 件 的 播 放 进 行 控
制 。

例 如 : 要 加 载 一 个 名 为 background.au 的 声 音文 件 , 并 把
它 赋 给 名 为 bg_snd 的 AudioClip 类 型 的 变 量 , 我们 只 需 这 样 写 :

    AudioClip bg_snd = getAudioClip ( getCodeBase(
) , " background.au" );


    加 载 了 声 音 文 件 以 后 , 接 下 来 就 是 播放 它 。 和 录 音
机 一 样 Java 里 也 用 Play 、 Loop 、 Stop 来 控 制唱 片 的 播 放 和 暂 停 。 它 的 使
用 录 音 机 一 样 简 单 , 你 只 需要 用 AudioClip 类 里 提 供 的 play( ) 、 loop( )
和 stop( ) 方 法 就 可以 很 方 便 地 控 制 它 。


    假 如 你 只 想 播 放 声 音 一 次 , 那 你 就 使用 方 法 play(
) , 在 程 序 里 这 样 写 :

    bg_snd .play ( ) ;

运 行 这 条 语 句 的 时 候 , Java 就 会 像 你 按 下了 录 音 机 上 的
Play 键 一 样 开 始 播 放 声 音 , 当 这 个 声 音 文件 播 放 完 以 后 , 它 就 会 自 动 停 止



    你 也 许 希 望 有 一 个 循 环 播 放 的 背 景 音乐 , 不 用 人 去
干 预 它 就 能 一 遍 又 一 遍 地 循 环 播 放 所 加 载的 那 个 声 音 文 件 。 在 程 序 里 写 上 下
面 这 句 话 你 的 这 个 愿望 就 能 实 现 。

    bg_snd . loop ( ) ;

    要 是 你 觉 得 它 吵 得 厉 害 , 不 想 再 让 它出 声 了 , 对 录 音
机 你 是 怎 么 做 的 呢 ? 按 Stop 键 。 在 Java 里也 一 样 , 你 只 需 要 像 下 面 这 样 使
用 方 法 stop( ) 就 可 以 让声 音 立 即 停 下 来 。

    bg_snd . stop ( ) ;

    好 啦 ! 学 习 了 声 音 文 件 的 加 载 和 播 放, 我 们 终 于 可 以
给 我 们 的 小 企 鹅 翻 筋 斗 加 上 背 景 音 乐 了, 准 备 好 你 的 音 箱 了 吗 ? 载 歌 载 舞 的
小 企 鹅 很 快 就 要 出场 了 !

程 序 18.3

  1. // tumble.java

  2. import java.awt.*;

  3. import java.applet.AudioClip;    // 引 入 AudioClip
  4. 程 序 包


  5. public class tumble extends java.applet.Applet
  6. implements Runnable

  7. {

  8.     Image frame[ ];

  9. Thread thd;

  10. int num;

  11. int pause;

  12. Image backgnd;        // 说 明 作 为 背 景 图 片的 Image
  13. 对 象

  14. int x,x_pos ;

  15. AudioClip bg_snd ;    // 说 明 用 来 放 背 景 音 乐的 AudioClip
  16. 对 象


  17. public void init( )

  18. {

  19.         int i;

  20. String fps;

  21. frame = new Image[17];

  22. thd = null;

  23. num = 0;

  24. for (i = 0; i < frame.length; i++)    // 加 载
  25. 动画 图 片

  26. frame[i] = getImage(getCodeBase( ), "images/T"
  27. + i + ".gif");

  28. backgnd = getImage (getCodeBase( ),"images/backgnd.gif");  
  29. // 加 载 背 景 图 片

  30. bg_snd = getAudioClip(getCodeBase( ),"audio/backsound.au");  
  31. // 加 载 背 景 音 乐

  32. fps = getParameter("speed");

  33. if (fps == null)

  34. fps = "10";

  35. pause = 1000 / Integer.parseInt(fps);    // 计 算
  36. 每一 帧 图 片 显 示 的 时 间

  37. }

  38. public void start( )

  39. {

  40.         bg_snd.loop ( );    // 循 环 播 放 背 景音 乐

  41.         if (thd == null)

  42.         {

  43.             thd = new Thread(this);    // 产生 线 程

  44.             thd.start( );    // 启 动 线 程

  45.         }

  46. }



  47. public void stop( )

  48. {

  49.         if (thd != null)

  50.         {

  51.             thd.stop( );    // 中 止 线 程

  52.             thd = null;

  53.         }

  54.         if (bg_snd != null)

  55.             bg_snd.stop( );    // 暂 停 背 景音 乐

  56. }

  57. public void run( )

  58. {

  59.         while (true)

  60. {

  61.             try { Thread.sleep(pause); }    // 图 片 显 示 期 间 , 让 进
  62. 程 睡 眠

  63.             catch (InterruptedException e) {}

  64.             repaint( );    // 重 画 窗 口

  65.             num = (num + 1) % frame.length;    // 对 显 示 帧 数 计 数

  66.             x = ((x+130+5)%(size( ).width+250))-130;   // 计 算 下
  67. 一 帧 图 片 显 示 的 位 置

  68.             x_pos= size( ).width-x ;

  69.         }

  70.     }

  71.     public void paint(Graphics g)

  72.     {

  73.         g.drawImage(backgnd,0,0,this);    // 显示 背 景 图 片

  74.         g.drawImage(frame[num], x_pos, 0, this);   // 显 示 动 画 图


  75.     }

  76.     public void update(Graphics g)

  77.     {

  78.         paint(g);

  79.     }

  80. }
复制代码



    这 个 Java 程 序 的 HTML 和 程 序 18.2 的 HTML 一样 , 所 以 你 完 全 可 以 拷
贝 上 一 个 程 序 的 HTML 文 件 , 而 无需 做 什 么 修 改 。 运 行 程 序 时 , 先 把 你 的 音
箱 打 开 , 你 将会 看 到 程 序 里 的 小 企 鹅 在 背 景 音 乐 的 伴 奏 下 一 个 接 一 个地 翻 筋
斗 。


    在 这 个 程 序 里 , 我 们 用 loop 来 播 放 背 景音 乐 , 所 以 只 要 加 载 了 它 , 音
乐 就 会 一 直 不 停 地 响 下 去。 即 使 用 户 已 经 离 开 了 这 个 主 页 。 这 对 于 用 户 而 言
是 很不 礼 貌 的 , 所 以 我 们 在 方 法 stop( ) 里 加 上 了 下 面 两 句 话来 中 止 背 景 音
乐 的 播 放 。

    if (bg_snd != null)

    bg_snd.stop( );


    最 后 我 们 应 该 知 道 , 声 音 文 件 的 播 放和 控 制 是 通 过 AudioClip 类 实 现
的 , 所 以 凡 是 会 出 声 音 的 Java 程 序 开 头 都 应 该 引 入 java.applet.AudioClip
这 个 程 序 包 。 也 就是 说 , 程 序 开 始 都 应 该 有 这 句 话 :

    import java.applet.AudioClip ;


    今 天 就 到 此 为 止 吧 , 你 终 于 可 以 一 边喝 咖 啡 一 边 欣 赏 自 己 做 出 来 的 载
歌 载 舞 的 小 动 画 , 好 好地 休 息 一 下 了 。


小 结


    学 习 完 今 天 的 课 程 , 本 书 已 经 接 近 尾声 , 你 已 经 学 会 了 Java 编 程 的 大
部 分 技 巧 , 接 下 来 的 事就 是 用 你 已 经 掌 握 的 Java 知 识 , 去 实 现 你 脑 子 里 各
种 稀奇 古 怪 的 想 法 , 做 出 让 人 惊 叹 的 主 页 来 。 最 后 我 再 对 今天 所 学 的 内 容 作
一 个 小 结 。




制 作 动 画 之 前 , 你 应 该 先 准 备 好 一 组 图 片 ,你 的 动 画 就 是 从 这 一 组 图 片
中 产 生 出 来 的 。

制 作 动 态 效 果 的 程 序 , 你 必 须 用 到 多 线 程 ,多 线 程 程 序 是 通 过 实 现 Runnable
接 口 得 到 的 。

按 照 固 定 的 步 骤 , 一 步 一 步 地 写 好 start( ) 、 stop( ) 和 run( ) 就
可 以 完 成 多 线 程 程 序 。

在 start( ) 里 , 产 生 新 的 线 程 , 我 们 用 它 来 播放 动 画 。 用 stop( ) 中
止 线 程 。 在 run( ) 里 写 播 放 动 画 的 代码 。

在 程 序 里 加 上 自 己 的 update 方 法 就 可 以 消 除 动画 里 的 闪 烁 现 象 。

连 续 翻 筋 斗 的 小 企 鹅 是 通 过 一 边 显 示 动 画 图片 , 一 边 改 变 显 示 位 置 实 现
的 。

在 动 画 里 加 上 背 景 音 乐 真 是 再 绝 妙 不 过 了 , getAudioClip 使 你 能 够 加
载 Au 格 式 的 声 音 文 件 , 然 后 我 们 用 AudioClip 类 里 的 play 、 loop 和 stop
来 控 制 它 的 播 放 。
 楼主| 发表于 2006-3-3 09:14:28 | 显示全部楼层

第二十一讲 网络功能(一)

酷素材
教 学 纲 要


Java 为我 们 提 供 了 强 有 力 的 网 络 功 能 , 也 正 是 由 于 它 的 强 大 的网 络 功 能 的 支 持 , Java 才 得 到 大 家 如 此 的 青 睐 。 不 信 你去 试 试 , 开 发 类 似 的 网 络 程 序 用 其 他 编 程 语 言 比 用 Java 复 杂 得 多 。
____________________________________________________________________


Java 语 言 是 运 用 于 网 络 环 境 的 一 种 编 程 语 言
, Java 的 程 序 要能 在 网 络 上 的 不 同 地 方 运 行
, 这 样 就 要 求 Java 程 序 执 行时 , 必 须 有 能 力
取 得 网 络 上 的 各 种 资 源 和 数 据 , 和 服 务器
建 立 各 种 传 输 通 道 , 把 自 己 的 数 据 传 输 到
网 络 各 处 。 Java 为 我 们 提 供 了 强 有 力 的 网 络
功 能 , 也 正 是 由 于 它 的强 大 的 网 络 功 能 的
支 持 , Java 才 得 到 大 家 如 此 的 青 睐 。不 信 你
去 试 试 , 开 发 类 似 的 网 络 程 序 用 其 他 编 程
语 言 比用 Java 复 杂 得 多 。


    Java 所 提 供 的 网 络 功 能 可 以
分 为 三 类 :用 URL 访 问 网 络 资 源 、 Socket 方 式
、 数 据 报 方 式 。 其 中 Socket 和 数 据 报 方 式 比
较 复 杂 , 我 们 只 介 绍 URL 的 有 关 内 容 。











Java 中 的 URL 类



    URL 也 就 是 Uniform Resourse Locator (
统 一 资源 定 位 器 ) , 如 果 你 用 过 WWW 浏 览 器
, 一 定 知 道 URL 。 每次 想 要 访 问 网 络 上 的 某
个 地 方 , 首 先 要 填 写 它 的 URL 。 顾名 思 义 ,
URL 用 于 表 示 网 络 资 源 的 地 址 。 网 络 上 的 资
源 都有 它 固 定 的 地 址 , 使 用 时 , 必 须 首 先
知 道 它 的 URL , 通 过 URL 指 定 的 方 法 获 取 网 络
资 源 。 网 络 资 源 的 URL 就 如 同 我们 每 个 人 的
住 址 , 我 们 记 住 了 朋 友 的 住 址 才 能 登 门 拜
访, 网 络 资 源 也 一 样 , 我 们 知 道 了 它 们 的
“ 住 址 ” 即 URL ,才 能 访 问 到 它 们 。 例 如 从
网 上 获 取 Java 开 发 工 具 , 我 们曾 经 访 问 过 Sun
公 司 的 Java Web 网 点 , 它 的 URL 为 : http: //
www.Javasoft.com , 从 这 里 你 可 以 看 到 许 多 与 Java
有 关 的 文 档。











有 规 律 的 URL 结 构



    如 果 你 经 常 使 用 WWW 浏 览 器
的 话 , 一 定记 录 了 许 多 URL , 是 不 是 已 经 发
现 了 URL 的 结 构 规 律 ? URL 的 结 构 分 为 两 部 分
: 传 输 协 议 和 资 源 名 称 , 中 间 用 “ : // ” 分
隔 开 。 传 输 协 议 说 明 访 问 资 源 时 使 用 的 网
络 协 议。


    典 型 的 传 输 协 议 有 http 、 ftp
还 有 gopher 、 file 、 news 等 。


    资 源 名 称 的 格 式 与 所 使 用
的 传 输 协 议有 关 , 通 常 由 下 列 结 构 格 式 中
的 一 个 或 几 个 组 成 :




主 机 名 称 ( host name ) : 资 源 所
在 的 主 机 的 名称 。 主 机 名 称 由 几 个 域 组
成 , 各 个 部 分 之 间 由 “ . ” 分隔 开 。 各 部
分 的 顺 序 类 似 于 英 语 中 的 地 址 书 写 方 式
, 较大 的 单 位 写 在 后 面 。 一 般 最 末 尾 的
域 , 即 一 级 域 代 表 国家 和 地 区 , 依 此 类
推 , 第 二 级 域 代 表 部 门 , 其 他 的 域 代表
个 人 的 一 些 信 息 。

文 件 名 ( file name) : 资 源 在 机 器
上 的 完 整 名 字。 这 里 的 文 件 名 并 不 是 简
单 的 名 字 , 它 要 包 括 文 件 的 完整 的 路 径
名 , 这 样 我 们 才 能 直 接 通 过 文 件 名 访 问
到 一 个文 件 。

端 口 号 ( port number) : 连 接 时 所
使 用 的 服 务 器端 口 号 。 查 看 一 下 你 收 集
的 URL , 许 多 都 没 有 端 口 号 , 因为 通 信 协
议 一 般 都 已 经 规 定 好 连 接 时 使 用 的 端 口
号 , 所以 这 部 分 常 被 省 略 。

参 考 点 ( reference ) : 资 源 中 的
特 定 位 置 , 用来 标 识 一 个 文 件 中 特 定 的
偏 移 位 置 。 通 过 参 考 点 我 们 可以 对 一 个
文 件 中 感 兴 趣 的 部 分 创 建 URL 对 象 。


    实 际 上 , 我 们 用 到 的 绝 大 部
分 URL 地 址 的资 源 名 称 只 包 括 主 机 名 称 和 文
件 名 , 图 19.1 中 分 析 一 个我 们 熟 悉 的 URL 的 结
构 , 它 属 于 最 常 用 的 类 型 :

图 19.1 URL 地 址 结 构










URL 类 有 四 种 构 造 方




    Java 中 专 门 设 计 了 URL 类
java.net.URL , URL 类 所 产 生 的 对 象 就 指 定 了 一 个
网 络 资 源 的 地 址 , 也 就 代表 了 URL 所 指 定 的
网 络 资 源 。 URL 类 定 义 了 四 种 不 同 的 构造 方
法 , 用 户 说 明 对 象 时 根 据 需 要 任 意 选 取 。


    1. URL(String URLaddress)


    首 先 介 绍 的 是 一 种 最 简 单
的 构 造 方 法, 这 种 构 造 方 法 把 网 络 资 源 的
URL 地 址 作 为 参 数 , 以 字 符串 的 形 式 直 接 传
入 方 法 内 。


    让 我 们 使 用 URL 地 址 “ http: //
www.javasoft.com/java/index.html ” 创 建 一 个 对 象 , 可 以
用 如 下 的 方 法 :


    URL htmlfile = new URL("http: //
www.javasoft.com/java/index.html");


    这 种 构 造 方 法 是 在 已 知 一
个 URL 地 址 后, 直 接 把 它 作 为 参 数 创 建 一 个
URL 对 象 。


    2. URL(URL URLaddress,String refer)


    这 是 一 种 类 似 于 “ 段 地 址
” 和 “ 偏 移量 ” 的 地 址 表 示 方 法 。 大 部 分
情 况 下 我 们 可 以 利 用 已 有的 URL 地 址 信 息 ,
结 合 要 访 问 的 另 一 种 资 源 的 有 关 信 息 ,确
定 一 个 新 的 资 源 。


    例 如 某 个 应 用 程 序 要 访 问
存 放 在 同 一目 录 下 的 一 组 HTML 文 件 , 首 先 创
建 一 个 完 整 的 URL 地 址 ,表 示 HTML 文 件 所 在 的
目 录 , 以 后 每 次 只 需 使 用 已 创 建 的完 整 URL
地 址 和 文 件 名 , 就 可 以 创 建 新 的 URL 对 象 访
问 另外 的 文 件 。 这 里 的 URL 地 址 作 为 “ 段 地
址 ” , 文 件 名 作 为 “ 偏 移 量 ” 。


    下 面 我 们 用 这 种 构 造 方 法
对 两 个 在 同一 目 录 下 的 URL 创 建 对 象 :


URL dictory = new URL("http: // www.javasoft.com/nav/read/");

URL htmlfile1 = new URL(dictory , "docindex.html");

URL htmlfile2 = new URL(dictory , "products.html");


    我 们 为 网 点 http:// www.javasoft.com
的 目 录 /nav/read/ 下 的 两 个 文 件 docindex.html 和
products.html 创 建 URL 对象 , 首 先 创 建 作 为 “ 段 地
址 ” 的 URL 地 址 , 然 后 以 文 件 名作 为 “ 偏 移
量 ” , 创 建 要 求 的 URL 对 象 。 这 种 方 法 允 许
我们 使 用 参 考 点 , 从 文 件 不 同 的 位 置 开 始
创 建 URL 对 象 。


    实 际 上 第 一 种 构 造 方 法 可
以 用 第 二 种方 法 实 现 , 只 要 取 “ 段 地 址 为
null , 整 个 URL 地 址 作 为 ” 偏 移 量 :

URL htmlfile = new URL(null,"http: //
www.javasoft.com/java/index.html");


    3. URL(String protocol,String host,int
port,String file)


    这 种 构 造 方 法 使 用 也 比 较
简 单 , 只 需按 顺 序 填 写 URL 地 址 的 各 部 分 信
息 : 传 输 协 议 、 主 机 名 称、 端 口 号 和 文 件
名 即 可 创 建 URL 对 象 。


    这 种 构 造 方 法 中 没 有 提 供
参 考 点 参 数, 所 以 不 允 许 使 用 参 考 点 , 我
们 只 能 对 整 个 文 件 创 建 URL 对 象 。


    下 面 的 例 子 中 使 用 URL 地 址
“ http:// www.opentext.com:8080/omw.html ” 创 建 一 个 对 象


URL htmlfile = new URL("http", "www.
opentext.com",8080, "omw.html");


    我 们 已 经 知 道 许 多 URL 地 址
并 没 有 端 口号 , 这 些 URL 创 建 对 象 时 可 以 使
用 下 面 的 第 四 种 构 造 方 法。


    4. URL(String protocol,String host,String
file)


    这 种 构 造 方 法 的 使 用 与 第
三 种 相 似 ,适 合 于 没 有 端 口 号 的 URL 地 址 。
同 第 三 种 方 法 一 样 , 不 允许 使 用 参 考 点 。
下 面 的 例 子 中 我 们 创 建 了 一 个 与 方 法 一相
同 的 URL 对 象 。

URL htmlfile = new URL("http", "www.javasoft.com",
"java/index.html");


    如 果 创 建 URL 对 象 时 有 错 误
, 如 URL 地 址参 数 不 正 确 , 传 输 协 议 不 符 合
要 求 等 , 构 造 方 法 会 输 出 MalformedURLException 例
外 , 我 们 在 这 一 章 的 例 子 中 都 用 了 例外 处
理 try 和 catch , 先 别 说 你 不 认 识 它 们 , 它 们
不 会 影 响你 对 程 序 的 理 解 。 本 书 后 面 的 章
节 中 会 讲 到 例 外 处 理 方法 。











URL 类 的 基 本 方 法



    URL 类 中 定 义 了 许 多 简 单 实
用 的 小 方 法, 我 们 可 以 利 用 它 们 进 行 一 些
有 关 URL 的 操 作 。


    1. 获 取 URL 信 息




getProtocol( ) : 获 取 URL 中 的 传 输 协
议 , 返 回 值为 String 。

getHost( ) : 获 取 URL 中 的 主 机 名 称
, 返 回 值 为 String 。

getPort( ) : 获 取 URL 中 的 端 口 号 ,
返 回 值 为 int , 如 果 一 个 URL 地 址 没 有 端 口
号 , 返 回 值 为 -1 。

getFile( ) : 获 取 资 源 的 文 件 名 ,
返 回 值 为 String 。

getRef( ) : 获 取 URL 中 的 参 考 点 ,
返 回 值 为 String , 如 果 一 个 URL 地 址 没 有 参
考 点 , 返 回 值 为 null 。





上 面列 出 的 五 个 小 方 法 分 别
用 于 获 取 URL 地 址 结 构 的 有 关 信 息, 我 们
通 过 一 个 例 子 来 看 看 它 们 的 使 用 方 法 。


程 序 19.1


// 创 建 如 下 的 源 程 序
sample.java

import java.net.URL; // 引 入 类

import java.net.MalformedURLException;


class sample

{

    public static void main(String args[])

    {

        URL sampleURL = null;


        try

        {

            sampleURL = new
URL("http: // www.opentext.com:8080/omw.html"); // 创 建
URL 对 象

        }


        catch(MalformedURLException e) //
异 常 处理

        {

           
System.out.println("MalformedURLException:"+e);}

           
System.out.println("Protocol: "+sampleURL.getProtocol( ));
// 显 示 结 果

           
System.out.println("Host Name: "+sampleURL. getHost( ));

           
System.out.println("Port Number: "+sampleURL.getPort( ));

           
System.out.println("File Name: "+sampleURL.getFile( ));

           
System.out.println("Reference: "+sampleURL.getRef( ));

        }

}


    这 是 一 个 Java 应 用 程 序 ,
因 为 程 序 中 包含 了 如 : public static void main ( ) {
… … } 这 条 语 句 。 前 面已 经 讲 过 Java 应 用
程 序 不 需 要 HTML 文 件 来 进 行 加 载 就 可 以独
立 执 行 。


    如 果 使 用 JDK 作 为 开 发 环
境 , 其 编 译 和运 行 过 程 如 下 :

C:\JAVA\EXAM>javac sample.java

C:\ JAVA\EXAM >java sample


    如 果 使 用 Symantec Cafe , 编 译
和 运 行 过 程和 Applet 一 样 ( 详 见 第 三 章 ) 。
输 出 结 果 显 示 在 Output 窗 口中 。


    程 序 19.1 运 行 结 果 为 :

Protocol:      http

Host Name:     www.opentext.com

Port Number:   8080

File Name:     /omw.html

Reference:     null


   


    程 序 19.1 运 行 结 果 输 出 URL
地 址 的 传 输协 议 、 主 机 名 称 、 端 口 号 和
文 件 名 , URL 没 有 参 考 点 , 输出 为 null 。


    2. 将 URL 的 内 容 转 成 字 符



    建 立 好 URL 对 象 以 后 , 有
两 种 方 法 可 以将 它 的 内 容 转 成 字 符 串 :

String toString( )

String toExternalForm( )


    下 面 的 程 序 19.2 说 明 了 这
两 种 方 法 的 用法 :


程 序 19.2

// change.java

import java.net.URL;

import java.net.MalformedURLException;

class change

{

    public static void main(String args[])

    {

        URL url = null;

        try

        {

          url = new URL("http: //
www.obscure.org/~jaws/htmltoolkit.html"); // 创 建 URL 对


        }

        catch(MalformedURLException e) //
异 常 处理

        {

       
System.out.println("MalformedURLException:"+e);}

        System.out.println("The URL is:
"+url.toString( )); // 显 示 结 果

        System.out.println("The URL is:
"+url.toExternalForm( ));

        }

}


    编 译 和 运 行 过 程 如 下 :

C:\JAVA\EXAM>javac change.java

C:\JAVA\EXAM>java change


程 序 19.2 运 行 结 果 为 :

The URL is: http: //
www.obscure.org/~jaws/htmltoolkit.html

The URL is: http: //
www.obscure.org/~jaws/htmltoolkit.html


    从 程 序 运 行 结 果 我 们 可
以 看 到 , 两 种方 法 实 现 了 同 样 的 功 能 ,
将 URL 地 址 转 换 成 字 符 串 。


    3. 比 较 两 个 URL 的 数 据 方
法 sameFile 能 够告 诉 你 两 个 URL 的 数 据 是 否 相
等 :

    boolean sameFile(URL other)

通 过 下 面 的 程 序 19.3 可 以 明 白 方
法 sameFile 的 使 用 。


程 序 19.3

// 创 建 源 程 序 Test.java :

import java.net.URL; // 引 入 类

import java.net.MalformedURLException;

class Test

{

    public static void main(String args[])

    {

    URL url1 = null,url2 = null,url3 = null;


    try

    {

    url1 = new URL("http: //
www.obscure.org/~jaws/htmltoolkit.html"); // 创 建 URL 对


    url2 = new URL("http: //
www.obscure.org/~jaws/htmltoolkit.html");

    url3 = new URL("http: //
www.ziff.com/~eamonn/crash_course.html");

    }

    catch(MalformedURLException e) // 异 常
处 理

    {

   
System.out.println("MalformedURLException:"+e);}


    System.out.println("The first url1:
"+url1); // 显 示 结 果

    System.out.println("The second url2:
"+url2);

    System.out.println("The third url3:
"+url3);


    System.out.println("(url1 == url2)
is "+url1.sameFile(url2)); // 显 示 结 果

    System.out.println("(url1 == url3) is
"+url1.sameFile(url3));

    System.out.println("(url2 == url3) is
"+url2.sameFile(url3));

    }

}


编 译 和 运 行 的 过 程 如 下 :

C:\java\exam>javac Test.java

C:\java\exam>java Test

程 序 19.3 运 行 结 果 为 :

The first url1: http: //
www.obscure.org/~jaws/htmltoolkit.html

The second url2: http: //
www.obscure.org/~jaws/htmltoolkit.html

The third url3: http: //
www.ziff.com/~eamonn/crash_course.html

(url1 == url2) is true

(url1 == url3) is false

(url2 == url3) is false
 楼主| 发表于 2006-3-3 09:17:12 | 显示全部楼层

第二十二讲 网络功能(二)

酷素材
通 过 URL 利 用 网 上 资 源


    Java 开 发 环 境 提 供 URL 类 是
为 了 我 们 更方 便 地 利 用 网 上 资 源 , 一 个 URL
类 创 建 的 对 象 就 代 表 了 某一 个 网 络 资 源 。
当 一 个 URL 对 象 建 立 好 后 , 我 们 就 可 以 比较
容 易 地 取 得 这 个 URL 位 置 的 数 据 。


    下 面 我 们 介 绍 两 种 简 单 的
通 过 URL 利 用网 上 资 源 的 方 法 , 通 过 URL 获 取
一 幅 图 象 , 通 过 URL 读 取网 络 资 源 的 数 据 。
如 果 有 兴 趣 , 你 可 以 修 改 下 面 的 程 序, 或
编 写 自 己 的 新 程 序 , 实 现 更 多 的 功 能 。


送 你 一 幅 美 丽 的 图 片


    使 用 URL 可 以 给 我 们 带 来 网
络 上 美 丽 的图 象 。 想 知 道 方 法 吗 ? 其 实 这
样 的 例 子 比 较 多 , 因 为 这里 用 到 的 方 法 非
常 适 合 我 们 理 解 。


程 序 19.4

  1. // images.java

  2. import java.awt.*; // 引 入 类 及 类 库

  3. import java.applet.Applet;

  4. import java.net.*;


  5. public class images extends Applet // 定 义
  6. applet 主类

  7. {

  8.     Image image;

  9.     public void init( )

  10.     {

  11.     try{ // 异 常 处 理

  12.     URL graphURL ; // 创 建 URL 对 象

  13.     graphURL = new URL("http: // www.sun.com/datacenter/products/starfire/images/logo.gif
  14. ");

  15.     image = getImage(graphURL); // 获 取 图 象

  16.     }

  17.     catch(MalformedURLException e)

  18.     {

  19.    
  20. System.out.println("MalformedURLException:"+e);}

  21.     }

  22.     public void paint(Graphics g) // 定 义 方
  23. 法 paint( )

  24.     {

  25.     g.drawImage(image,0,0,200,200,this); // 显
  26. 示 图象

  27.     }

  28. }
复制代码



其 HTML 文 件 如 下 :

< HTML>

< HEAD>

< TITLE>class images < /TITLE>

< /HEAD>

< BODY>

< APPLET CODE = "images.class"WIDTH = 300
HEIGHT = 200></applet>

< /BODY>

< /HTML>


    在 支 持 Java 的 网 络 浏 览 器
上 运 行 该 程 序, Java Applet 就 会 给 你 带 来 这 幅
美 丽 的 图 片 ( 图 19.2 ) :



图 19.2 程 序 19.4 运 行 结 果


方 法 drawImage( ) 的 参 数 分 别 代 表
什 么 ?

    是 由 类 java.awt.Graphics 定 义 的 ,
Graphics 类 定 义 了 四 种 drawImage( ) 方 法 , 我 们 选
择 了 其 中 的 一 种 :

    public abstract boolean drawImage(Image
img,intx,int y,int width,int height,ImageObserver observer)

    其 中 img 表 示 要 显 示 的 图 象
; ( x,y )表 示 图 象 显 示 位 置 的 左 上 角 的 坐
标 ; width 表 示 图 象 的 宽度 ; height 表 示 图 象
的 高 度 ; observer 表 示 用 于 实 现 ImageObserver 界 面
的 对 象 , 我 们 一 般 取 this 。


    程 序 结 构 很 简 单 , 首 先 在
方 法 init( ) 中创 建 一 个 URL 对 象 , 并 利 用 方 法
getImage( ) 获 取 图 象 , 然 后在 方 法 paint( ) 中 利
用 类 java.awt.Graphics 提 供 的 显 示 图 象 的方 法
drawImage( ) , 显 示 图 象 。


    如 果 我 们 把 这 个 Java applet 放
到 浏 览 器中 运 行 , 图 象 的 获 取 发 生 在 第 一
次 访 问 含 有 该 Java applet 的 主 页 , 只 要 不 退
出 浏 览 器 , 每 次 光 顾 这 个 主 页 时 , Java
applet 只 完 成 显 示 图 象 的 过 程 。


    方 法 getImage( ) 是 在 哪 定 义 的
? 为 什 么找 不 到 它 的 定 义 ?

    方 法 getImage( ) 并 不 是 在 Java
applet 中 直接 定 义 的 , 类 java.applet.Applet 为 我 们
提 供 了 方 法 getImage( ) , getImage( ) 以 包 含 图 象
的 URL 地 址 作 为 参 数 , 获 取 网 络的 图 象 资 源




通过 数 据 流 读 取 资 源 数 据


    我 们 与 网 络 上 的 文 件 就 像 我 们 与 住
在另 一 个 城 市 中 的 朋 友 一 样 , 我 们 要 拜 访
另 一 个 城 市 的 朋友 , 两 个 城 市 之 间 必 须 有
一 条 道 路 。 那 么 网 络 资 源 也 一样 , 我 们 要
访 问 网 络 资 源 , 就 得 先 在 我 们 的 机 器 与
资 源之 间 修 一 条 “ 路 ” , 也 就 是 建 立 一 条
通 信 链 路 。


    数 据 流 实 际 就 是 数 据 的 一 种 通 信 通
道, 包 括 数 据 的 起 点 和 终 点 。 例 如 我 们 要
把 网 络 上 的 资 源信 息 读 入 到 本 地 机 器 中 的
一 个 文 件 FILE1 中 , 那 么 如 图 19.3 所 示 , 信 息
的 通 道 就 是 一 个 数 据 流 , 它 的 起 点 是 网
络 资源 , 终 点 是 文 件 FILE1 。



图 19.3 网 络 中 的 数 据 流


    简 单 的 读 出 资 源 数 据 可 以 由 方 法
openStream( ) 实 现 。 使 用 方 法 openStream( ) 可 以 将
资 源 数 据 转 化 为 数 据流 , 为 网 络 资 源 和 URL
对 象 之 间 建 立 一 条 通 信 链 路 。 下 面是 一 个
通 过 URL 使 用 网 络 资 源 的 例 子 :

程 序 19.5

  1. // useURL.java

  2. import java.net.*; // 引 入 类 库

  3. import java.io.*;

  4. class useURL // 定 义 类 useURL

  5. {

  6.   public static void main(String args[])

  7.   {

  8.   try

  9.   {

  10.   URL resource = new URL("http: //   www.javasoft.com/java/index.html");
  11. // 创 建 URL 对 象

  12.   String oneline; // 下 一 条 语 句 建 立 数 据 流

  13.   DataInputStream stream = new DataInputStream(resource.openStream(
  14. ));

  15.   while((oneline = stream.readLine( ))! = null) // 将数 据 一
  16. 行 行 读 入 , 存 入 字 符 串 oneline

  17.   {System.out.println(oneline);} // 将 数 据 输 出 到屏 幕

  18.   stream.close( ); // 关 闭 数 据 流

  19.   }

  20.   catch(MalformedURLException e){ // 异 常 处 理

  21.   System.out.println("MalformedURLException:"+e);}

  22.   catch(IOException IOe){

  23.   System.out.println("IOException:"+IOe);}

  24.   }

  25. }
复制代码

    在 这 个 程 序 中 我 们 首 先 创 建 一 个 URL
对象 , 使 用 URL 类 提 供 的 方 法 openStream( ) 得 到
输 入 流 类 InputStream 的 对 象 。


    DataInputStram 是 由 包 含 在 java.io 中 的 一
种输 入 流 , 它 必 须 连 接 到 其 他 的 输 入 流 上
才 能 使 用 。 本 例中 我 们 通 过 下 面 的 语 句 将
它 连 接 到 InputStream 上 , 建 立 数据 流 :
DataInputStream stream = new DataInputStream(resource.openStream( ));


    建 立 数 据 流 之 后 , 使 用 类 DataInputStream
提 供 的 方 法 readLine 从 文 件 中 一 行 行 地 读 出
数 据 , 返 回 值存 放 到 字 符 串 变 量 oneline 中 。
while 循 环 语 句 控 制 程 序 流程 , 读 出 一 行 ,
在 屏 幕 上 输 出 一 行 , 直 到 文 件 结 束 , 用方
法 close( ) 关 闭 数 据 流 。


    运 行 程 序 useURL.java , 我 们 可 以 看 到
文件 的 内 容 一 行 一 行 地 显 示 到 屏 幕 上 。


小 结


    Java 为 我 们 提 供 了 强 有 力 的 网 络 功
能 ,我 们 在 这 里 只 讨 论 Java 的 一 些 简 单 的
网 络 功 能 , 主 要 介绍 以 下 几 个 方 面 的 内 容





·URL 的 结 构 有 一 定 的 规 律 性 , 由 传 输 协
议 和 资源 名 称 两 部 分 组 成 , 中 间 用 “ :
// ” 分 隔 开 。

·Java 语 言 提 供 了 URL 类 java.net.URL , 为 我 们
使 用 URL 访 问 网 络 资 源 定 义 了 许 多 方 法


·URL 类 有 四 种 构 造 方 法 , 我 们 可 以 根 据
需 要 选择 其 中 一 种 。

·URL 类 提 供 了 许 多 简 单 地 方 法 : 获 取 URL
信 息 ,将 URL 的 内 容 转 成 字 符 串 以 及 比 较
两 个 URL 的 数 据 等 方 法, 通 过 例 程 序 我 们
可 以 很 清 楚 地 了 解 它 们 的 使 用 方 法 。

本 章 我 们 只 介 绍 了 简 单 地 通 过 URL 类 访
问 网 络资 源 的 方 法 , 类 java.applet.Applet 提 供
的 方 法 getImage( ) 能 够利 用 URL 对 象 获 取 网 络
上 的 图 象 。 读 取 网 络 资 源 数 据 之 前, 建
立 数 据 流 。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?[立即注册]

x
 楼主| 发表于 2006-3-3 09:21:49 | 显示全部楼层

第二十三讲 面向对象的例外处理

教 学 纲 要

·用 面 向 对 象 的 方 法 进 行 例 外 处 理  

·运 行 时 例 外 和 非 运 行 时 例 外  

·简 单 的 例 外 处 理

——————————————————————————————————


面 向 对 象 的 例 外 处 理


什 么 是 例 外 、 例 外 处 理


    例 外 就 是 在 正 常 情 况 以 外 的 事 件 。 Java 之 中 的
例 外 是 指 程 序 运 行 中 发 生 的 异 常 事 件 , 这 些 异 常事 件 将 阻 止 程 序 的 正 常 运
行 。 比 如 出 现 了 数 组 越 界 、 用户 输 入 错 误 等 等 。 而 顾 名 思 义 , 例 外 处 理 就
是 对 这 些 例外 进 行 处 理 。


    所 有 的 高 级 计 算 机 编 程 语 言 里 都 有 判断 是 否 出 现
了 例 外 的 语 句 , 每 个 好 的 计 算 机 程 序 都 会 有对 例 外 进 行 处 理 的 程 序 段 。 只
不 过 在 不 同 的 计 算 机 编 程语 言 里 面 , 对 例 外 的 称 呼 不 同 , 例 如 有 的 语 言 里
所 讲 的错 误 处 理 , 其 实 就 等 同 于 Java 里 面 的 例 外 处 理 。 这 就 像诸 葛 亮 先 生
有 两 个 名 字 , 孔 明 是 他 诸 葛 亮 也 是 他 , 还 有人 称 呼 他 为 诸 葛 先 生 … … , 只
是 称 呼 不 同 罢 了 , 意 义 是一 样 的 。


抛 弃 之


    在 许 多 高 级 语 言 中 都 是 通 过 使 用 if 语句 来 判 断 是
否 出 现 了 例 外 , 并 进 行 处 理 的 。 Java 作 为 一个 完 全 基 于 面 向 对 象 的 语 言
, 例 外 处 理 也 是 采 用 面 向 对象 的 方 法 。 在 一 个 方 法 的 运 行 过 程 中 如 果 发 生
了 例 外 ,则 这 个 方 法 将 生 成 一 个 代 表 该 例 外 的 对 象 , 并 把 它 提 交给 正 在 运
行 这 个 方 法 的 系 统 。 我 们 把 这 个 过 程 称 为 抛 弃一 个 例 外 。


    就 像 抛 弃 这 个 球 一 样 , 把 它 给 抛 掉 了。 抛 弃 一 个
例 外 的 过 程 就 和 我 们 平 时 工 作 中 碰 到 了 特 殊情 况 无 法 解 决 , 需 要 写 一 份 报
告 交 把 这 个 棘 手 的 问 题 上报 上 级 主 管 部 门 一 样 。


捕 获 之


    系 统 在 运 行 的 时 候 查 找 处 理 提 交 给 它的 例 外 的 方
法 , 这 个 过 程 称 为 捕 获 一 个 例 外 。 这 就 和 法官 判 案 时 查 找 相 应 的 法 律 条 文
的 过 程 是 一 样 的 。


优 越 性


    1. 利 用 以 上 这 些 方 法 处 理 例 外 , 使 得例 外 处 理 的
程 序 代 码 与 普 通 的 程 序 代 码 不 再 混 为 一 体 ,减 少 了 编 程 序 的 工 作 量 , 同 时
也 增 加 了 程 序 可 读 性 。


    2. 利 用 面 向 对 象 的 方 法 来 处 理 例 外 ,可 以 对 各 种
不 同 的 例 外 事 件 进 行 分 类 , 然 后 再 处 理 之 ,从 而 具 有 了 良 好 的 接 口 和 层 次
性 。


    3. 利 用 类 的 层 次 性 既 可 以 区 分 不 同 的例 外 分 别 处
理 , 也 可 以 把 具 有 相 同 父 类 的 多 个 例 外 统 一处 理 , 具 有 相 当 的 灵 活 性 。


    由 以 上 几 点 可 知 , Java 的 这 种 面 向 对 象的 例 外 处
理 机 制 为 那 些 具 有 动 态 运 行 特 性 的 复 杂 程 序 提供 了 强 有 力 的 控 制 方 式 。


    以 上 这 些 优 越 性 背 下 来 就 可 以 了 , 到时 候 可 以 用
来 在 孩 儿 们 面 前 炫 耀 一 下 自 己 的 知 识 渊 博 。


与 例 外 处 理 相 关 的 类


    用 面 向 对 象 的 方 法 来 进 行 例 外 处 理 首先 必 须 建 立
类 的 层 次 。 如 图 20.1 所 示 , 类 Throwable 是 最 顶层 的 , 只 有 它 的 子 类 才
可 以 作 为 一 个 例 外 被 抛 弃 。


运 行 时 与 非 运 行 时 例 外  


    Java 有 运 行 时 例 外 和 非 运 行 时 例 外 之 分。


    所 谓 运 行 时 例 外 就 是 由 系 统 在 Java 程 序运 行 的 过
程 中 检 测 到 的 例 外 , 例 如 除 零 溢 出 ( 除 数 为 零导 致 的 错 误 ) 、 数 组 越 界 等
。 由 于 它 们 可 能 在 程 序 的 任何 位 置 发 生 , 而 且 谁 也 无 法 在 程 序 运 行 以 前 计
算 出 它 们会 发 生 多 少 次 , 所 以 Java 语 言 编 译 器 允 许 Java 程 序 不 对 它进 行
处 理 。


    除 此 之 外 的 其 他 例 外 则 被 称 为 非 运 行时 例 外 。



图 20.1 例 外 处 理 — — 类 的 层 次  


    用 户 自 己 定 义 的 例 外 都 是 非 运 行 时 例外 。 然 而 并
非 所 有 非 运 行 时 例 外 都 是 用 户 自 己 定 义 的 例外 。


    所 谓 用 户 自 己 定 义 的 例 外 , 就 是 你 在编 写 程 序 的
时 候 在 你 的 程 序 里 面 定 义 的 那 些 例 外 , 以 便使 得 你 的 程 序 具 有 更 高 的 可 靠
性 , 不 会 轻 易 地 出 差 错 。


    Java 编 译 器 要 求 必 须 捕 获 或 声 明 所 有 的非 运 行 时
例 外 。 对 于 用 户 自 定 义 例 外 , 这 是 十 分 显 然 的; 否 则 , 系 统 就 不 知 道 这 些
用 户 自 定 义 的 例 外 的 特 性 。知 己 知 彼 才 能 百 战 百 胜 。

简 单 的 例 外 处 理  


    运 行 时 例 外 的 处 理


    先 看 看 下 面 这 两 个 例 子 。

程 序 20.1

public class REP{

  public static void main(String args[ ]) {

    int AE = 1/0; // AE 等 于 1 除 以 0 , 将 导 致除 0
溢 出 例 外

    }

  }


程 序 20.2

public class REP{

  public static void main(String args[ ]) {

    int i = 0;

    int AE = 1/i; // AE 等 于 1 除 以 i , 而 i 等于 0
, 也 将 导 致 除 0 溢 出

    }

  }  


    在 程 序 20.1 和 程 序 20.2 中 都 出 现 了 除 数为 0 导
致 的 “ 除 0 溢 出 ” 例 外 , 这 属 于 运 行 时 例 外 。 此 时, 运 行 程 序 的 系 统 会 自
动 把 生 成 的 例 外 对 象 交 给 缺 省 的( 也 就 是 默 认 的 ) 例 外 处 理 程 序 , 在 计 算
机 屏 幕 上 显 示出 这 个 例 外 的 内 容 及 发 生 此 例 外 的 位 置 。 在 JDK 环 境 下 运行
这 两 个 例 子 程 序 。 ( 有 关 JDK 开 发 环 境 的 介 绍 请 参 见 《开 发 环 境 》 一 章 )


    程 序 20.1 的 运 行 结 果 为 :

    c:\java\exam >javac REP.java

    REP.java:3: Arithmetic exception.

        int AE = 1/0;

            ^

    1 error


    可 见 , 程 序 在 编 译 的 时 候 编 译 器 就 指出 了 错 误 。
此 程 序 不 能 通 过 编 译 。 无 法 生 成 可 以 运 行 的文 件 。


    程 序 20.2 的 运 行 结 果 是 :

    c:\java\exam>javac REP.java

    c:\java\exam>java REP

    java.lang.ArithmeticException: / by zero

        at REP.main(REP.java:4)


    程 序 20.2 虽 然 通 过 了 编 译 , 编 译 器 没 有指 出 有 错
误 , 从 而 生 成 了 可 以 运 行 的 程 序 文 件 , 但 是 该程 序 在 运 行 时 系 统 指 出 出 现
了 例 外 。


非 运 行 时 例 外


    我 们 也 是 先 看 一 个 例 子 :

程 序 20.3

  1. class MyE extends Exception{ // 定 义 一 个 例 外 类
  2. MyE

  3.     private int detailA,detailB;

  4.     MyE(int a,int b){

  5.         detailA = a;

  6.         detailB = b;

  7.         }

  8.     public String toString(){

  9.         return "MyException : "+detailA+"<"+detailB;

  10.         }

  11.     }


  12. public class ED{ // 定 义 一 个 类 ED

  13. static void compare(int a,int b) throws MyE {

  14.     System.out.println("***************************");

  15.     System.out.println("call compare("+a+","+b+")");

  16.     if (a

  17.         throw new MyE(a,b);

  18.     System.out.println("normal exit : "+a+">
  19. = "+b);

  20.     }


  21. static void callcompare(int a,int b){

  22.     try{

  23.         compare(a,b);

  24.       } catch(MyE e){

  25.             System.out.println("Catch "+e);

  26.                 }

  27.         finally{

  28.             System.out.println("return from
  29. callcompare()");

  30.             }

  31.     }


  32. public static void main (String args[ ]){

  33.         callcompare(10,5);

  34.         callcompare(5,5);

  35.         callcompare(5,10);

  36.         }

  37. }
复制代码



    程 序 20.3 抛 弃 了 自 己 的 例 外 。 上 例 对 两个 整 数 a
和 b 进 行 了 比 较 ( compare ) , 当 a ( = b 时 程 序 正常 运 行 , 当 a((b 时
程 序 抛 弃 例 外 MyException 。







在 JDK 里 例 20.3 的 运 行 结 果 如 下 :

    c:\java\exam>java ED


    ***************************

    call compare(10,5)

    normal exit : 10> = 5

    return from callcompare()

    ***************************

    call compare(5,5)

    normal exit : 5> = 5

    return from callcompare()

    ***************************

    call compare(5,10)

    Catch MyException : 5<10

    return from callcompare()  


例 外 的 抛 弃 、 捕 获 和 声 明  


    除 对 运 行 时 例 外 可 以 不 做 处 理 外 , 例外 处 理 还 有
以 下 几 种 方 法 :




使 用 throws 子 句 生 命 例 外 ;

定 义 自 己 的 例 外 类 , 并 用 throw 语 句 来 抛 弃 它;

使 用 try-catch-finally 语 句 捕 获 例 外 。


抛 弃 例 外

    在 Java 语 言 中 捕 获 一 个 例 外 之 前 , 必 须有 一 段 Java
代 码 生 成 一 个 例 外 对 象 并 把 它 抛 弃 。 抛 弃 例外 的 代 码 可 以 是 你 自 己 Java
的 程 序 , JDK 中 的 某 个 类 , 或者 是 Java 运 行 时 系 统 。 这 就 像 在 蓝 球 场 上
打 球 一 样 , 你 若想 接 到 一 个 球 , 就 必 须 有 人 先 抛 出 这 个 球 , 不 管 这 人 是中
锋 , 还 是 后 卫 , 亦 或 是 对 方 球 员 。 同 理 , 如 同 所 有 人抛 球 都 必 须 用 手 一 样
, 无 论 是 你 自 己 的 程 序 还 是 运 行 时系 统 , 都 必 须 使 用 throw 语 句 来 抛 弃 例
外 。


    例 如 , 在 例 20.3 的 compare 方 法 中 就 使 用了 throw
语 句 来 抛 弃 一 个 例 外 :


    throw new MyE(a,b);

其 中 MyE 是 Exception 的 一 个 子 类 。



  


    class MyE extends Exception{ // class MyException
}

由 throw 抛 弃 的 例 外 必 须 是 Throwable 类 或 其 子类 的 对
象 。


声 明 例 外


    在 很 多 情 况 下 , 生 成 例 外 的 方 法 并 不需 要 处 理 它
, 而 是 用 throws 子 句 来 声 明 它 , 以 向 上 传 递 。如 例 20.3 中

    static void compare(int a,int b) throws MyE
{

这 样 就 在 compare 方 法 中 声 明 了 例 外 MyE 。


    一 个 方 法 中 也 可 以 同 时 声 明 多 个 例 外, 只 需 throws
在 后 列 出 所 有 要 声 明 的 例 外 即 可 。 例 如


    static void Proc ( ) throws MyE , ArithmeticException{

    … …

    }


捕 获 例 外


    捕 获 例 外 需 使 用 try-catch-finally 语 句 。


    在 例 20.3 的 callcompare 方 法 中 , try 语 句 在
{} 中 指 定 了 一 段 代 码 , 该 代 码 可 能 会 抛 弃 几 个 例 外 ; 其后 的 catch 用 于
处 理 这 些 例 外 ; finally 则 提 供 了 统 一 的 出口 。


  1. static void callcompare(int a,int b){

  2.     try{

  3.         compare(a,b);

  4.     }

  5.         catch(MyE e){

  6.             System.out.println("Catch "+e);

  7.             }

  8.         finally{

  9.             System.out.println("return from
  10. callcompare()");

  11.             }

  12.     }
复制代码



程 序 20.4
  1. import java.awt.*;

  2. import java.applet.*;


  3. class MyE extends Exception{ // class MyException

  4.     private int detailA,detailB;

  5.     MyE(int a,int b){

  6.         detailA = a;

  7.         detailB = b;

  8.             }

  9.     public String toString(){

  10.         return "MyException : "+detailA+"<"+detailB;

  11.             }

  12.      


  13. }


  14. class Cons{ // 设 置 一 个 常 数 , 让 它 代 表 两 条线 之 间
  15. 的 距 离

  16.     final int jmp = 13;

  17.     }


  18. public class ED extends Applet{ // class Exception
  19. Demo

  20.     static void compare(int a,int b,Graphics g,int
  21. Ln,int col) throws MyE {

  22.       Cons jump = new Cons();

  23.       g.drawString("***************************",col,Ln);

  24.       g.drawString("call compare("+a+","+b+")",col,Ln+jump.jmp);

  25.       if (a

  26.         throw new MyE(a,b);

  27.       g.drawString("normal exit :"+a+">
  28. = "+b,col,Ln+2*jump.jmp);

  29.         }


  30. static void callcompare(int a,int b,Graphics
  31. g,int Ln,int col){

  32.   Cons jump = new Cons();

  33.     try{

  34.         compare(a,b,g,Ln,col);

  35.       }

  36.         catch(MyE e){

  37.         g.drawString("Catch "+e,col,Ln+2*jump.jmp);

  38.             }

  39.       finally{

  40.             g.drawString("return from callcompare()",col,Ln+3*jump.jmp);

  41.             }

  42.     }


  43. public void paint (Graphics g){

  44.     Cons jump = new Cons();

  45.     int Ln;

  46.     int col;

  47.     Ln = 10; col = 20;

  48.     callcompare(10,5,g,Ln,col);

  49.     Ln = Ln+5*jump.jmp;

  50.     callcompare(5,5,g,Ln,col);

  51.     Ln = Ln+5*jump.jmp;

  52.     callcompare(5,10,g,Ln,col);

  53.       }

  54.     }
复制代码



    程 序 20.4 是 程 序 20.3 的 Applet 形 式 , 它 的运 行
结 果 如 图 20.2 所 示 。



图 20.2 程 序 20.4 的 执 行 结 果


几 件 值 得 注 意 的 事 情




自 定 义 的 例 外 类 的 类 名 通 常 可 以 以 Exception 结尾
。 例 如 :

MyException , MyArithmeticException 等 。

对 于 运 行 时 例 外 可 以 不 捕 获 、 声 明 , 而 提 交运 行 时
系 统 处 理 。

在 捕 获 或 声 明 例 外 时 , 要 选 取 合 适 类 型 与 层次 的 例
外 。

处 理 例 外 既 可 以 在 方 法 内 捕 获 并 处 理 , 也 可以 提 交
上 层 方 法 处 理 。

使 用 finally 语 句 可 为 例 外 处 理 提 供 统 一 的 出 口,
通 常 可 在 finally 语 句 中 进 行 资 源 清 除 工 作 , 如 关 闭 已打 开 的 文 件 等 。


小 结



·Java 采 用 面 向 对 象 的 例 外 处 理 机 制 减 小 了 编 程量 , 增 加 了 灵 活 性 , 增 强 了 程 序 的 可 读 性 和 可 靠 性 , 有利 于 编 写 具 有 动 态 运 行 特 性 的 复 杂 程 序 。

·对 非 运 行 时 例 外 必 须 捕 获 或 声 明 。

·对 于 自 定 义 的 例 外 类 , 通 常 作 为 类 Exception 的 子
类 , 而 不 作 为 类 Error 的 子 类 。 因 为 类 Error 通 常 用 于系 统 内 严 重 的 硬
件 错 误 。

·抛 弃 的 例 外 必 须 是 Throwable 类 或 其 子 类 的 对 象。

·注 意 区 分 throw 和 throws 的 用 法 :

  throw 用 于 抛 弃 例 外 ;

  throws 用 于 声 明 例 外 。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?[立即注册]

x
发表于 2006-12-18 23:26:03 | 显示全部楼层
好是好,不过看的累啊
发表于 2006-12-19 00:20:21 | 显示全部楼层
好长  我晕~~~
发表于 2007-8-16 07:33:38 | 显示全部楼层
学习!!!
回复 支持 反对

使用道具 举报

发表于 2007-8-23 14:33:15 | 显示全部楼层
好啊~#kt..jcwcn.com@
回复 支持 反对

使用道具 举报

发表于 2007-9-2 22:10:44 | 显示全部楼层
收藏以下啊,以后看!
回复 支持 反对

使用道具 举报

发表于 2007-10-29 21:32:38 | 显示全部楼层

java

我也想学 但是好象很难啊 拼命啊#@jcwcn@@#
回复 支持 反对

使用道具 举报

发表于 2007-11-20 08:24:44 | 显示全部楼层
好长啊,不错,谢谢分享
回复 支持 反对

使用道具 举报

发表于 2008-1-13 02:46:42 | 显示全部楼层
(^#@^ (^#@^
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | [立即注册]

本版积分规则

2345