创 建 用 户 组 件 |
|
让 我 们 来 看 一 下 产 生 一 个 专 用 的 组 件, 重 用 它 们 和 在 内 部 事 件 处 理 中 保 持 你 的 应 用 级 别 代 码 的 简 洁 是 多 么 容 易!
使 用Java API 提 供 的 的 标 准 用 户 界 面 元 素, 许 多 应 用 程 序 就 可 以 很 好 的 完 成 很 多 工 作。 必 要 时, 程 序 员 可 以 把 这 些 元 素 组 合 成 更 高 级 复 杂 的 界 面。 然 而, 如 果 增 加 处 理 组 件 集 合 和 事 件 处 理 来 获 得 高 级 用 户 界 面 功 能( 如 象 一 个 字 体 选 择 器 这 样 的 单 一 概 念 的 用 户 事 件), 那 么 在 应 用 级 的 事 件 处 理 将 变 得 十 分 麻 烦。 让 我 们 看 看 上 面 例 子, 我 们 考 虑 一 个 需 要 字 体 选 择 器 的 应 用 程 序, 为 了 实 现 这 种 功 能, 我 们 需 要 三 个 分 离 的 组 件 来 分 别 取 得 字 体 的 名 称, 风 格 和 字 体 的 大 小。 应 用 程 序 的 事 件 处 理 代 码 必 须 具 备 这 三 个 组 件 的 筛 选 器。 这 就 是 整 个 内 部 事 件 的 跟 踪 处 理。 相 反 如 果 我 们 构 建 一 个 不 同 于 上 面 的 字 体 选 择 器, 那 么 这 种 固 有 内 部 事 件 处 理 就 被 隐 藏 了 起 来。 这 个 应 用 程 序 只 需 捕 捉 到 一 个 字 体 选 择 器 事 件 对 象, 事 件 的 目 标 将 是 示 例 字 体 选 择 器 对 象 本 身 - - 这 是 一 个 多 么 简 洁 的 方 法。 非 常 明 显 的, 用 户 组 件 的 一 个 重 要 牲 是 能 够 在 应 用 中 隐 藏 细 节 的 能 力, 但 是 可 重 复 使 用 也 是 导 致 构 造 一 个 用 户 组 件 的 原 因。 当 你 发 现 你 需 要 一 遍 又 一 遍 的 实 现 某 种 特 别 的 功 能, 你 就 会 想 要 为 这 一 工 作 构 造 一 个 用 户 组 件 了, 更 进 一 步 的 话, 你 可 以 把 重 复 使 用 的 专 门 界 面 元 素 结 合 到 用 户 组 件 包(custom component package) 中 去, 使 得 这 个 类 库 在 一 组 开 发 者 中 特 别 容 易 重 用。 现 在, 在 你 为 每 个 可 能 的 组 件 变 化 编 写 代 码 之 前, 我 必 须 提 到 保 留 一 个 关 于 用 户 组 件 的 警 告。 当 你 正 在 开 发applet 时 候, 你 的 用 户 组 件 类 库 必 须 被 下 载。 这 是 因 为 它 们 不 是 所 有Java 虚 拟 机 的 局 部 可 用 的 内 核API 的 一 部 分: 但 是 只 要 你 的applet 不 用 很 多 的 用 户 类, 你 不 用 担 心 这 类 问 题, 但 是 如 果 最 佳 的 下 载 时 间 是 紧 要 的, 那 么 你 必 须 十 分 确 定 这 种 功 能 提 高 的 必 要 性。 用 户 组 件 中 的 事 件
处 理 Event 对 象 包 含 了 一 些 参 数( 现 在 普 遍 是 用 适 当 类 型 的arg 参 数
传 递 事 件。 然 后 应 用 程 序 可 以 查
看 哪 一 个 组 件 产 生 了 这 一 事 件,
将 书 写 组 合 框 事 件 处
理 代 码 正 如 你 从 如 下 片 断 看 到 的,comboBox 继
承 了 import java.awt.*; package my.components; public class ComboBox extends Panel { TextField text; List list; public ComboBox() { text = new TextField(); list = new List(); list.setMultipleSelections(false); setLayout(new BorderLayout()); add("North", text); add("Center", list); } // end constructor 我 们 注 意 到 这 里 是 public void addItem(String item) { list.addItem(item); } 创 建 组 合 框 的 应 用 程 序 使 用 这
个 类 的 现 在 让 我 们 看 一 下 类 中 真 正 有 趣 的 部 分 - - 事 件 处 理: public boolean handleEvent(Event e) { if ((e.id == Event.ACTION_EVENT) && (e.target == text)) { postEvent(new Event(this, Event.ACTION_EVENT, text.getText())); } else if (e.id == Event.LIST_SELECT) { text.setText(list.getSelectedItem()); text.requestFocus(); } else if (e.id == Event.KEY_ACTION) { if ((e.key == Event.UP) && (list.getSelectedIndex() > 0)) { list.select(list.getSelectedIndex() - 1); text.setText(list.getSelectedItem()); } if ((e.key == Event.DOWN) && (list.getSelectedIndex() <list.countItems())) { list.select(list.getSelectedIndex() + 1); text.setText(list.getSelectedItem()); } } else if (e.id="=" Event.MOUSE_ENTER) { text.requestFocus(); } return(super.handleEvent(e)); } // end handleEvent } // end ComboBox 在 方 法 当 用 户 点 中 了 列 表 条 目, 那 么 它 被 放 置 在 文 本 框 中, 然 后 得 到 一 个 输 入 焦 点, 如 果 用 户 按 下 了 向 上 或 向 下 箭 头 键, 则 选 择 列 表 的 条 目 就 发 生 变 化, 文 本 框 就 设 置 成 新 的 值。MOUSE_ENTER 事 件 是 被 监 视 的, 文 本 框 被 自 动 的 给 予 输 入 焦 点, 使 组 件 更 方 便 用 户 的 使 用, 这 就 意 味 着 用 户 在 使 用combo Box 时 不 用 击 中 任 何 地 方。 当 用 户 在 文 本 框 中 按 下 回 车 键,
那 意 味 着 已 经 做 出 了 最 后 的 选
择, 当 前 值 做 为 传 送 事 件 被 送 往
调 用 应 用 程 序。 一 个 新 的 带 有 目
标 是 Event(Component target, int Event.id, Object arg); 使 用combo Box 的 应 用 程 序 将 检 查ACTION_EVENT, 通
过 实 现 我 们 所 学 的 import java.awt.*; import java.applet.*; import my.components.ComboBox; public class Test extends Applet { TextArea textarea; public void init() { setLayout(new BorderLayout()); ComboBox cb = new ComboBox(); cb.addItem("One"); cb.addItem("Two"); cb.addItem("Three"); cb.addItem("Four"); cb.addItem("Five"); Label l = new Label("This is a test of the combo box..."); Panel p = new Panel(); p.setLayout(new GridLayout(2, 3)); p.add(new Button("One")); p.add(new Button("Two")); p.add(new Button("Three")); p.add(new Button("Four")); p.add(new Button("Five")); p.add(new Button("Six")); textarea = new TextArea(); add("East", cb); add("Center", textarea); add("North", l); add("South", p); } // end init public boolean handleEvent(Event e) { if ((e.id == Event.ACTION_EVENT) && (e.target instanceof ComboBox)) { textarea.appendText("ComboBox yielded: " + (String)e.arg + "\n"); } return(super.handleEvent(e)); } // end handleEvent } // end Test 让 我 们 看 一 下 这 儿 发 生 了 什 么。 首 先, 创 建 了 组 合 框, 加 入 了 条 目。 接 着 组 件 加 入 到 小 应 用 程 序 中, 就 象 加 入 其 它 组 件 一 样。( 把 用 户 组 件 分 组 放 入 单 独 的 程 序 包package 中, 使 得 它 们 可 以 被 其 它 程 序 员 轻 易 使 用。) 如 果 你 想 创 建 一 个 真 正 可 重 用 的 库, 使 你 的API 和 核 心API 一 样, 我 建 议 你 使 用 java 文 档 生 成 器(javadoc documentation generator) 要 求 的 注 解 格 式。 学 以 致 用 |