话说java模拟器怎么让辐射4游戏画面居中中显示

如题,其他不多说,直接上代码!
package com.himarking.
import java.awt.T
import javax.swing.JF
@SuppressWarnings("serial")
public class AppWindows extends JFrame {
// 得到显示器屏幕的宽高
public int width = Toolkit.getDefaultToolkit().getScreenSize().
public int height = Toolkit.getDefaultToolkit().getScreenSize().
// 定义窗体的宽高
public int windowsWedth = 600;
public int windowsHeight = 600;
public AppWindows() {
// 设置窗体可见
this.setVisible(true);
// 设置窗体位置和大小
this.setBounds((width - windowsWedth) / 2,
(height - windowsHeight) / 2, windowsWedth, windowsHeight);
public static void main(String[] args) {
new AppWindows();
阅读(...) 评论()本帖子已过去太久远了,不再提供回复功能。为 Nokia S60 智能手机开发基于 eSWT 的应用程序
开始之前关于本教程在本教程中,我们将在 eSWT 的基础上开发一个简单的数独(Sudoku)游戏应用程序。首先,我们将了解 eSWT 框架、它的 API 和架构。然后将了解如何获得并配置完成任务所需的工具 — 即 Eclipse SDK 和 Mobile Tools for Java(MTJ),以及 Nokia 的 S60 Platform SDK。之后将在 Eclipse 中创建一个 MIDlet 项目并使用 eSWT API 开发游戏。最后,我们将构建并打包最终的产品,并将它部署到 S60 Platform SDK 提供的基于软件的移动电话模拟器。本教程涉及以下主题:S60 Platform 和 eSWT 概述从 Nokia 站点获得 S60 Platform SDK设置 Eclipse SDK 和 Mobile Tools for Java (MTJ)创建 MIDlets使用 eSWT API 编程将 MIDlet 部署到 S60 模拟器先决条件本教程面向的读者是熟悉 Eclipse IDE 的 Java 开发人员。熟悉 Standard Widget Toolkit (SWT) 也很有帮助,但不是必要条件。不需要具备嵌入式 Java 编程经验。 系统需求Java 2 Standard EditionJava 2 Standard Edition V5 或更高版本可以从 Sun Microsystems 获得。Eclipse Ganymede在 Eclipse Foundation 可以找到 Eclipse V3.4 平台。Eclipse 绑定了多个版本。为了方便,请下载 Eclipse IDE for Java Developers 或 Eclipse IDE for Java EE Developers。Eclipse Mobile Tools for Java (MTJ)在 Eclipse Foundation 可以找到最新版本的 Eclipse Mobile Tools for Java (MTJ), V0.9。Nokia S60 Platform SDK, 3rd Edition在 Forum Nokia 可以找到 Nokia S60 Platform SDK, 3rd Edition with Feature Pack 2。本教程展示如何安装 SDK。Microsoft Windows XP 或 Windows Vista®Nokia S60 Platform SDK 只能在 Windows 上操作,因此,不能使用 Mac OS X 或 Linux® 开发 S60 Platform 应用程序。Forum Nokia 中有一些开发人员声称他们成功地在 Wine 上运行了 SDK,但本教程不对此进行讨论。从
小节下载这些技术(Microsoft Windows 除外)。S60 平台、eSWT、Java ME 和 MIDlets本节将完成一些基础工作。首先您将了解有关 S60 平台和 eSWT 的一些背景,然后再了解 Java Platform, Micro Edition 和 MIDlet 实现。S60 平台架构S60 平台以前称为 Series 60,是面向高级移动电话(即智能手机)的应用程序平台。它运行在各种移动电话使用的 Symbian OS 操作系统之上。S60 最初由 Nokia 开发,后来 Samsung、Panasonic 和 LG 等其他移动电话供应商获得了 S60 的许可。注意,虽然 S60 本身并不是开源的,但人们最近正准备积极地开放 Symbian OS 的源代码。S60 包含一个标准应用程序套件、用户界面框架和中间件组件。应用程序包括电话、消息传递、Web 浏览、多媒体、个人信息管理、办公应用程序、移动设备管理等等。由于使用了灵活的设计并纳入了标准的库,S60 可以支持第三方应用程序和扩展的开发。图 1 展示了 S60 平台的高层架构概览。图 1. S60 平台架构软件供应商可以使用各种编程语言和技术针对 S60 平台开发应用程序。除 C/C++ 只外,也可以使用 Java Mobile Information Device Profile (MIDP) V2.0 或使用 Python、Adobe Flash 和其他高级 Web 浏览器技术创建 Web 部件。S60 平台为供应商互操作性提供了便利,因为它使用了由 Open Mobile Alliance (OMA) 开发的大量开放规范,比如 OMA Multimedia Messaging 和 OMA Digital Rights Management (DRM)。每个 S60 平台发行版称为一个版本(edition)。此外,版本的小升级以及特定于设备的升级将作为特性包发布。目前,最新的 S60 平台发行版是第 5 版本。然而,附带 Feature Pack 2 的第 3 版是第一个支持 eSWT 的发行版。它也可以用于更多手机中。通常来讲,新的版本只能安装到新发布的手机上;现有设备不能升级到最新版本。然而,升级到更新的特性包是可以的。因此,本教程将使用第三版 FP2 作为目标部署平台。 Eclipse 的移动 Java 应用程序Eclipse 可能最为人熟知的一点是它是一流的集成开发环境(IDE)。不过,Eclipse IDE 还包含了大量可重用技术。其中一些技术表现为工具,比如 Java Development Tools (JDT) 和 Plug-in Development Environment (PDE)。另一些是运行时技术,例如 Equinox Framework(Eclipse 的 OSGi 运行时实现)和 Standard Widget Toolkit (SWT)。实际上,正是 SWT 让 Eclipse 实现了本地感观。SWT 被看作是 Java Swing 的替代者,Swing 是包含在 Java 标准中的 GUI 框架。当人们认为 Swing 不再适合作为高级 IDE 的 GUI 技术后,SWT 应运而生。SWT 的独特之处在于它实际上是一个围绕操作系统本地部件工具箱的 Java 包装器。这一特点不仅使基于 SWT 的应用程序具有本地应用程序(非 Java)的感官,并且还极大地提高了性能,因为本地部件库可能会针对其目标操作系统进行优化。eSWT 的结构SWT 的嵌入式版本(即 eSWT)实际上是用于资源受限环境中的 SWT。eSWT 实现了 SWT API 的子集,并且实现了用于移动设备的移动扩展。SWT(以及 eSWT)的基本概念是部件。部件是 UI 中的最小单位。窗口、对话框、按钮、工具栏、菜单项、表、树和表以及树条目都属于部件。能够接收事件的部件称为控件。比如,实例、窗口、对话框、按钮、表和树都属于控件,而菜单、表和树条目则不是。大部分 SWT 部件都直接从操作系统提供的等效功能获得支持。也就是说,部件的绘制、事件、行为和逻辑都委托给一个本地库,这个本地库随后使用目标操作系统的本地 API。有些部件不能用于特定的平台,这些部件是 “模拟的”,或者说是自定义绘制的。因此,SWT 只能用于那些已经存在特定于平台的 SWT 实现的平台。然而,由于 SWT 仔细地维护其 API 以及跨平台和版本间的行为兼容性,它通常可以在一个或多个其他平台上重用基于 SWT 的、针对一个平台开发的 UI 组件。一个典型的基于 SWT 的 UI 由一个部件树组成。每个部件包含在其父部件中(顶级部件除外,因为它不需要父部件)。在树的最顶层,通常有一个表示窗口的 shell。该窗口的客户区由一个组合区(composite)表示,这是窗口 shell 的子元素。组合区又包括其他控件,比如标签、文本控件和按钮。组合区使用 Layout 类控制其子元素的位置。控件能够响应用户和 OS 事件。每种控件都会记录它所支持的事件。客户区可以针对特定事件为控件注册侦听器。比如,一个 KeyListener 可以注册到一个控件,以便在控件接收到来自用户的键盘事件时接收到一个 KeyEvent。客户区甚至会截取控件的 PaintEvent,直接在控件的屏幕表面进行绘制。然而,这通常是多余的,因为部件的本地外观就已经满足需求。一种用于自定义绘制的控件是 Canvas,它不会提供本地的外观表示。在响应控件的 PaintEvent 时,实现者可能使用由 Graphical Context (GC) 类提供的大量基本图元 API(graphical-primitive API),比如,绘制线条、文本等等。Graphical Context (GC) 类的实例可以从 PaintEvent 获得。由于每个 SWT 部件都表示一个稀有的 OS 资源,因此 API 要求您在使用完部件后立即销毁它。所以,必须记住在合适的时间调用部件的 dispose() 方法。如果不这样做,很可能导致资源泄漏。对于非部件资源,比如颜色和字体,也必须在不再使用后处理掉。所有部件操作 — 创建部件、事件处理和销毁 — 都是在一个显示(display)上下文中执行。display 是进入 SWT 的运行时入口点。一个典型的基于 SWT 的应用程序将创建一个单一的 display 实例,构造想要的 UI 并实现 UI 事件循环。事件循环不断轮询 display 以发现到来的 OS 消息并把这些消息分配到它们预期的接收者(比如控件),直到收到停止的指令。执行这个过程的线程称为 display 线程。所有 SWT 交互必须发生在该线程内。如果另一个线程希望与 SWT 交互(除了个别例外),它必须将一个 Runnable(执行所需的功能)传递给使用 display 的 syncExec(Runnable) 和 asyncExec(Runnable) 方法的线程。这些请求将排成队列并在 display 的事件循环内部处理。eSWT 和 Java ME在针对移动设备开发软件时,您一定要意识到嵌入式软件通常会存在资源限制。移动 Java 应用程序也不例外。除了各种分辨率和颜色的小屏幕外,嵌入式应用程序必须解决内存较少、处理能力弱、电量少以及输入设备受限等问题。根据目标平台的功能,Java Platform, Micro Edition (Java ME) 可以使用多种配置。目标平台对可用的运行时服务、API 和语言级别施加限制。配置包括一个 Java 虚拟机(JVM)和一组常用于某类设备的 API。概要文件是一组特定于配置的 API,针对同类设备中范围更小的一类设备。Connected Limited Device Configuration (CLDC) 和 Mobile Information Device Profile (MIDP) 是最常部署于移动设备的配置。它主要针对只能留出 128-512 KB 空间运行 Java 进程的平台。图 2 展示了 CLDC 和 MIDP 在 Mobile Information Device (MID) 架构栈中的位置。图 2. 使用 CLDC 和 MIDP 的 MID 架构eSWT 和桌面版 SWT 的不同之处是,前者只要有 CLDC/MIDP 就可满足需求,而后者至少需要 Java Connected Device Configuration (CDC) V1.0 以及 Foundation Profile (FP) V1.0。CDC 所针对的环境应至少具备 2 MB RAM 并且至少有 2.5 MB ROM 可用于 Java。这一特性使 eSWT 可以部署到更多移动设备上,这些设备通常会提供 Java CLDC/MIDP 支持,而不是 CDC/FP。需要使用 CDC/FP 作为最低配置的运行时环境,这一要求也使 eRCP 无法运行在 S60 上。因此,基于 S60 的应用程序可以使用 eSWT,但是不能使用完整的 eRCP。图 3 描述了 eSWT 的高层架构以及它在底层本地平台 Java CLDC/MIDP 和移动应用程序(MIDlets)中的位置。图 3. eSWT 在 Java CLDC/MIDP 栈中的位置CLDC 开发还意味着只拥有有限的 API 集。虽然 CDC 的目标是能够与 Java 2, Standard Edition (J2SE) V1.3.1 在 API 方面兼容(至少在基本运行时 API 方面),但是 CLDC 只能提供一个小得多的 API 子集(比如,Java Collections 在 CLDC 下是不可用的)。因此,将 J2SE 应用程序迁移到 CLDC 通常会更加困难。幸运的是,SWT API 在设计时就考虑到这一点,并没有引用在 CLDC 中不可用的类或接口。MIDlets由于受到目标平台的限制,针对 MIDP 概要文件编写的应用程序必须构造为其生命周期由框架管理的组件。MIDP 应用程序的入口点是 MIDlet。MIDlet 指扩展抽象类 javax.microedition.midlet.MIDlet 的类。具体的 MIDlet 子类必须事先三个抽象方法:startApp()、pauseApp() 和 destroyApp(boolean)。这三个方法分别由框架在 MIDlet 生命周期的不同点调用。同时,MIDlet 必须提供一个公共的无参数构造函数。清单 1 展示了一个骨架 MIDlet 实现。清单 1. 骨架 MIDlet 实现package org.eclipse.eswt.
import javax.microedition.midlet.MID
import javax.microedition.midlet.MIDletStateChangeE
public class Sudoku extends MIDlet {
protected void startApp() throws MIDletStateChangeException {
// TODO Auto-generated method stub
protected void pauseApp() {
// TODO Auto-generated method stub
protected void destroyApp(boolean unconditionally)
throws MIDletStateChangeException {
// TODO Auto-generated method stub
}在第一次构建 MIDlet 时,它处于停止状态。当主机的应用程序管理软件决定启动 MIDlet 时,它将调用 startApp() 方法。此时,应用程序将变为活跃状态。稍后,应用程序管理器选择停止 MIDlet,这时将调用它的 pauseApp() 方法。在中断后,应用程序将释放所有临时资源并变为消极状态。在活跃和停止状态下,应用程序可能会收到对 destroyApp(boolean) 的调用,要求它停止工作。布尔参数表示该请求是否是无条件的。在终止后,应用程序将变为消极状态并释放所占有的全部系统资源。抽象 MIDlet 类提供方法允许扩展程序检查它的权限(checkPermission(String)),从管理软件获得应用程序属性(getAppProperty(String)),并通知状态管理器改变状态,比如重新开始(notifyResumed())或销毁(notifyDestroyed())。MIDlet 还可以向平台发出请求来访问任何 URL(platformRequest(String));处理这些 URL 的方式与平台无关;最后,MIDlet 可以在处于停止状态时请求切换到活跃状态(比如,在接收某些外部事件后),方法是调用 resumeRequest()。MIDlets 通常被打包为 JAR 文件。然而,一个 MIDlet JAR 必须在其清单文件(META-INF/MANIFEST.MF)中包含某些特殊条目,这些条目描述了 JAR 中包含的 MIDlets。必需的属性包括 MIDlet 名称(MIDlet-Name)、版本(MIDlet-Version)和供应商(MIDlet-Vendor)。其他可选的属性包括 JAR 中每个 MIDlet 的类名(MIDlet-&n&,其中 “n” 从 1 开始并在每加入一个 MIDlet 时加 1),所需的 Java ME 配置(MicroEdition-Configuration)和概要文件(MicroEdition-Profile)。这些属性可以根据需要选择,因为它们可以通过一个外部 Java Application Descriptor (JAD) 提供。JAD 文件是 MIDlet JAR 文件附带的一个可选文本文件。目标平台使用它来判断所附带的 JAR 是否包含兼容的 MIDlet;只有在满足所有先决条件后才能下载实际的 JAR。JAD 文件支持 MIDlet JAR 清单文件中包含的相同属性。除了一个匹配的 MIDlet-Name、MIDlet-Version 和 MIDlet-Vendor 之外,JAD 文件还必须包含它所描述的 JAR 文件的 URL(MIDlet-Jar-URL)和大小(MIDlet-Jar-Size)。设置开发环境谈到软件开发效率 — 不管是面向桌面、嵌入式设备还是 Web — 通常情况下,工具是一个关键因素。幸运的是,有很多有效的工具可以帮助我们编写基于 eSWT 的应用程序,并且它们常常是免费的。 Nokia S60 Platform SDK要针对 S60 平台开发软件,第一个必备工具箱就是 Nokia 的 S60 平台 SDK(参见 )。这个工具箱提供了工具、库和文档,可以帮助开发运行在 S60 平台和 Symbian OS 上的应用程序。同时提供 C/C++ 和 Java 开发支持。然而,与本教程最相关的特性是提供了丰富功能的手机模拟器,它能够运行在实际的手机中运行的软件。模拟器允许您在一个模拟的部署环境中开发和测试软件,因此不需要购买额外的硬件。SDK 可从 Nokia 网站免费下载获得。不过,Nokia 要求您首先注册为 Forum Nokia 的成员。Forum Nokia 为移动软件开发人员提供了大量资源,包括文档、帮助、用户讨论板和开发工具箱。Forum Nokia 成员也是免费注册的。一旦注册成为 Nokia Forum 成员后,您就可以下载所需的 SDK。S60 平台 SDK 分为几种不同的版本:C++ 版、Java 版和综合版。最理想的选择是综合版,因为它提供了您所需的一切内容。因此,您应当下载的 SDK 为 S60 third edition SDK for Symbian OS, Feature Pack 2 V1.1。将所下载的 ZIP 压缩文件提取到一个临时目录并启动 SDK 安装程序(setup.exe)。图 4. S60 平台 SDK 安装程序安装过程开始不久后,您会收到一条消息,表示为了正常工作,必须安装 Perl V5.6.1。您可以忽略这条消息,因为在本教程中使用 SDK 时不需要用到 Perl。然而,您可以选择下载和安装最新的 Active Perl 并按照指令重新启动安装过程,否则,单击 Yes 继续。接受许可协议后,您可以保留所有默认选择的选项,直到完成全部安装。图 4 所示的屏幕截图显示了安装程序的安装类型和最终屏幕。注意,在系统询问时,不需要将 SDK 集成到 Eclipse IDE 中。后面将设置 Eclipse IDE,并且,最终的集成只是将 SDK 的文档插件安装到 Eclipse(该文档也可以作为独立应用程序提供)。在提示安装 CSL Toolchain(GCCE)时,选择 No;因为 Java 开发不需要安装它。最后,忽略任何与 Perl 相关的警告。安装完?后,将发现在开始菜单中为您的程序添加了一个 S60 Developer Tools 菜单。您可以尝试启动 3rd Edition FP2 SDK & V1.1 & Emulator 来检验安装是否成功。您需要模拟器在工作条件下运行您开发的代码。Eclipse SDK 和 Mobile Tools for Java (MTJ)安装好 S60 平台 SDK 后,可以继续设置 IDE。可以使用现有的 Eclipse SDK 安装,只要它是 V3.3.2 或更高版本。Ganymede Service Release 1(即 Eclipse SDK V3.4.1)是最新的 Eclipse 稳定版(参见 )。您可以从 Eclipse 网站下载它的 ZIP 文件,然后提取到所选的目录中。Eclipse 启动程序(eclipse.exe)将位于 eclipse 目录。注意,Eclipse 需要使用最近的 Java Runtime Environment(V1.5 或更高版本)才能正常工作。如果还没有安装的话,可以从 Sun Microsystems 的网站下载(参见 )。目前,Java 的最新稳定版是 V1.6。请根据 Sun 网站上提供的安装说明安装。虽然 Eclipse SDK 非常适合开发普通的 Java 应用程序,但是仅使用 Eclipse SDK 不会为移动应用程序开发提供太大的帮助。然而,最近出现的一组新的开发工具可以为 Eclipse IDE 提供这方面的功能。Mobile Tools for Java(即 MTJ)是 Eclipse 发起的 Device Software Development Platform (DSDP) 项目的一个比较新的子项目(参见 )。虽然 MTJ 不久前才发布了它的第一个发行版(V0.9),但是它已经非常成熟,因为它是非常成功的 Eclipse ME 项目(不是由 Eclipse Foundation 发起)的延续,后者大概在 2003 年左右发布。MTJ 允许您编写运行在 Java Micro Edition 上的 Java 应用程序。具体来讲,它为创建 Java ME MIDlet 提供了向导和编辑器。它还允许您控制 Java ME 打包的各个方面,并使您使用各种模拟器或实际的移动设备运行和调试 MIDlet。它还支持大量移动 SDK。您可以将 MTJ 直接安装到 Eclipse SDK 中,只需要将 Update Manager 指向 MTJ 的更新站点。另外,可以下载 MTJ 的 zip 压缩文件并将其提取到 Eclipse SDK 安装目录(即 eclipse 目录的父目录)。注意,您需要的包是 MTJ Runtime V0.9。图 5. 从 S60 平台 SDK 导入设备安装好 MTJ 后,您必须根据 S60 平台 SDK 的需求配置它:启动 Eclipse IDE 并打开一个空的工作空间,然后切换到新的 Java ME 透视图。通过单击 Window & Preferences 开始编辑您的首选参数。在 Preferences 对话框中,选择 Java ME&Device Management。这将显示已安装的移动 SDK 并且 SDK 目前应该是空的。单击 Import 按钮。在 Import Devices 对话框中,指定 S60 Platform SDK 安装的路径(比如 c:\S60)。Devices 表中应当会发现并显示一个 S60Emulator 和 S60Device,如图 5 所示。单击 Finish 导入它们。回到 Preferences 对话框,在页面的上方应当选择了 S60 Platform SDK 并且表中列出了新发现的设备。将 S60Emulator 勾选为默认设备。为了进一步简化 Java ME 开发,需要对首选参数进行一些调整:在 Preferences 对话框中,选择 Java ME。将 Debug Server Time-out 调整为 90000。在左侧选择 Java & Debug。取消选择 Suspend execution on uncaught exceptions and Suspend execution on compilation errors。将 Debugger 超时设置为 30000 并将 Launch 超时设置为 60000。调整后的 Java Debug 首选参数应当如图 6 所示。单击 OK 以保存这些首选参数。图 6. 调整后的 Java Debug 首选参数现在可以开始开发移动数独游戏了。编写数独游戏安装并配置好所有必需工具后,就可以开始开发数独游戏了(从
部分获得源代码)。您可能不太熟悉数独游戏,它是近年来非常流行的与逻辑有关的数字游戏。它由一个包含 9 行 9 列的网格组成。游戏的意图是使用 1 到 9 的数字填充网格,使每一个数字在每行、每列以及每个 3×3 的小方块中(共 9 个)只出现一次。在开始游戏时,网格中已经填好了部分数字(足够提供最初的约束集)。预填充的单元格是不可修改的。 我们并不打算从头开始编写所有的代码,您可以使用任意一个可免费获得的实现作为出发点。Eclipse Examples 项目提供了一个构建在 Eclipse RCP 上的实现。更好的出发点是使用 DSDP 项目资源库中同一示例的 eSWT 版本。虽然简单数独游戏的代码并不复杂,但是使用现有的实现允许您侧重于与本教程有关的任务,比如修改代码以在 CLDC 上运行或使用 eSWT API。创建数独 MIDlet要将 Java 应用程序部署到 S60 平台上,必须将应用程序构建并打包成一个 MIDlet 套件。Eclipse MTJ 允许您使用一个简单向导来创建新的 MIDlet 项目。在 Java ME 透视图中,单击 File & New & MIDlet Project。输入一个适当的项目名(比如 sudoku)并确保指定了正确的 Target Device(即将 S60 Platform SDK 作为 SDK,并将 S60Emulator 作为 Device)。图 7 展示了使用示例值填充的向导页面。在单击 Finish 后,应当能看到在工作台中打开了 Application Descriptor 编辑器。 图 7. New MIDlet 项目向导Application Descriptor 编辑器用于编辑项目的 JAD 文件。在最开始,只有 overview 页面填充了数据,如图 8 所示。如果需要的话,您可以修改 MIDlet 名、供应商和版本。单击编辑器中的 Application Descriptor 选项卡将显示 JAD 文件的文本视图。图 8. MIDlet 的 Application Descriptor 编辑器下一个逻辑步骤就是创建实际的 MIDlet 类。在 Project Explorer 中,右键单击 MIDIlet 项目中的 src 文件夹并从上下文菜单中选择 New & Java ME MIDlet。输入适当的包名(比如 sudoku)并指定 MIDlet 的类名(比如 Sudoku)。图 9 展示了填充好的向导页面。单击 Finish 后,向导将创建一个骨架 MIDlet 应用程序。同时,新创建的 MIDlet 被添加到 Application Descriptor。您可以在编辑器的 MIDlet 页面中进行检验。图 9. 新的 MIDlet 向导在开始使用 eSWT 之前,需要先编写代码来实现数独游戏的逻辑。使用 eRCP Sudoku 示例作为出发点,您需要使用类来模拟游戏状态。比如,Cell 表示一个单个网格单元格。它有一个当前值(即 1 到 9 之间的任意值);值为 0 的单元格是空格。Cell 是可以 “提供” 的,这表示它可以在游戏开始时被预先填充,并且不能被用户修改。如果 Cell 所在的行、列和小方块都是有效的,那么它就被认为是 “有效的”。最后,一个 Cell 还可以提供一组有效值,这组值实际上就是该 cell 的行、列和方块的现有值以外的其他任何值。其他模型类包括 Column、Row 和 Box,每一个类都很简单地表示了它们代表的含义。Column 表示网格中 9 个垂直单元格。如果 Column 中没有包含重复的值,那么它就是有效的。类似地,Row 表示网格中 9 个水平的单元格,并且在不包含重复值时是有效的。Box 表示游戏板上没有重叠的 3x3 单元格区域。同样,它在不包含重复值时是有效的。SudokuBoard 类是 Cell、Column 和 Row 的容器。它跟踪无效的 Columns、Rows 和 Boxes(如果不存在无效值则游戏板是有效的)。当填满所有空 Cells 之后,游戏结束。SudokuBoard 还提供了访问游戏板各部分的方法,比如按照列和行号访问 Cell,以及确定某个 Cell 属于哪个 Box。SudokuBoard 类还支持一种简单的通知机制:只要它们实现了 SudokuBoardStateListener 接口,希望获得有关游戏板变化通知的对象可以在游戏板中注册为侦听器。这种机制可用于将游戏的逻辑从 UI 中分离出来。最后,SudokuGame 充当游戏模型的入口点。它提供了创建新游戏板的方法,并获得游戏板工厂(board factory)和可用的求解程序。SudokuBoardFactory 是游戏板生成器算法的一个抽象。类似地,SudokuBoardSolver 是数独求解程序算法的一个抽象。一个简单的回溯求解程序的实现通过生成器和求解程序提供。SudokuBoard 还使用一种通知机制(通过经过注册的 SudokuBoardChangeListener)向玩家通知游戏的变化,比如在创建新游戏板时。在比较 eRCP 示例中修改后的代码和原始的实现时,会注意到代码针对 CLDC 进行了部分重构。具体来讲,使用 Java Collection 类的代码全部被重构为使用更加简单的 Vector 类。同样,所有使用 Iterator 的地方也被转换为使用 Enumeration。使用 eSWT 编写 UI目前为止,您还没有遇到任何用到 eSWT 的地方。示例代码实现了很好的关注点分离。您已经了解到所有 eSWT 部件都位于一个 disply 上下文中。创建单个 Display 实例的线程将变成 display 线程,并且所有 eSWT API 调用都需要从该线程中发出。除了创建部件和控件外,display 线程的任务还包括处理所有接收到的事件和消息。当 display 消失后,该线程将终止,应用程序也将停止。由于 MIDlet 的生命周期由框架管理,您无法创建自己的 display 并在 MIDlet 的 startApp() 方法中实现自己的 UI 事件循环。这样做实际上会抢占属于应用程序管理器的调用线程,并将一直阻塞该线程直到您的应用程序完成为止。因此,MIDlet 必须创建一个单独的线程并使用它作为专用的 display 线程。返回 MIDlet 类,您必须在第一次调用 startApp() 方法时创建并启动一个新的 Thread 实例。该线程的 run 方法最适合创建并实现 UI 事件循环。清单 2 展示了这一过程。 清单 2. 带有 eSWT display 线程和 UI 事件循环的初始 MIDlet 实现public class Sudoku extends MIDlet implements Runnable {
private MobileS
protected void startApp() throws MIDletStateChangeException {
if (thread == null) {
thread = new Thread(this);
thread.start();
public void run() {
display = new Display();
shell = new MobileShell(display);
shell.setLayout(new FillLayout());
shell.setText("Sudoku");
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
} finally {
display.dispose();
notifyDestroyed();
protected void pauseApp() {
// do nothing
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
display.asyncExec(new Runnable() {
public void run() {
if (!shell.isDisposed())
shell.close();
}该 display 线程的 run 方法首先创建 Display 及其顶级 shell。MobileShell 类可用于替代标准 SWT shell,因为它提供了特定于手机的功能,比如状态文本、全屏模式和动态裁剪。新创建的 shell 可以用作整个应用程序中使用的所有其他部件和图形的容器。最值得一提的是,游戏的 UI 是使用 SudokuView 类实现的,它负责在启动时创建必要的 widgetry 并在终止线程时处理资源。因此,您必须实例化该类并让它创建自己的部件,方法是调用它的 createPartControl(Composite) 方法,将顶级 shell 作为容器传递。清单 3 展示了这一过程。清单 3. 在处理 shell 时实例化 SudokuView 并处理它final SudokuView view = new SudokuView();
view.createPartControl(shell);
view.setFocus();
shell.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent event) {
view.dispose();
});准备好必要的部件后,必须为用户提供退出游戏的方法。Command 类就提供了这种功能;它使您能够将一个选择侦听器挂接到手机的标准按钮之一。Exit 按钮最适合作为退出命令。在调用该命令后(即按下按钮),将会关闭顶级 shell。清单 4 展示了创建 Exit 命令的代码片段。清单 4. 创建 Exit 命令Command exitCmd = new Command(shell, Command.EXIT, 0);
exitCmd.setText("Exit");
exitCmd.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent event) {
// do nothing
public void widgetSelected(SelectionEvent event) {
shell.close();
});完成了部件创建和命令配置后,您可以打开 shell 并运行标准的 UI 事件循环。只要 shell 没有被处理(即被关闭),您应当读取并传递 UI 事件(通过调用 display 的 readAndDisplay() 方法)。如果该方法返回 false,需要将 display 变为休眠状态(通过调用 sleep()),这样它将一直处于等待状态,直到新出现的事件唤醒它。在处理顶级 shell 时,您应当销毁 display 并退出线程。通常,应用程序会在用户?择关闭它时结束运行。然而,如果作为 MIDlet 运行,应用程序管理器可能也会要求应用程序终止运行(例如为了释放某些资源等等)。因此,MIDlet 的 destroyApp(boolean) 方法应当告诉 display 线程它应该终止运行。一种方法就是向 display 线程发送一条消息,要求它关闭其顶级 shell,从而停止事件循环,销毁 display 并终止线程。如清单 2 所示,这种 MIDlet 实现非常通用并且可以支持完全不同的应用程序,只需使用独立的、类似 SudokuView 的类将实现的所有 UI 结构和用户事件处理封装起来。实际上,SudokuView 类负责创建绘制数独游戏板所需的部件,创建额外的命令让用户控制游戏并连接事件侦听程序以处理键盘事件,以及负责重新调整屏幕大小和重新绘制屏幕。这种模式是我们重构 eRCP 数独示例的结果,使它在一个 eRCP 视图上显示游戏,而不是在顶级 shell 上显示(但是独立的容器概念一样适用)。鉴于数独游戏的图形特性,它的 UI 将通过 Graphical Context (GC)
图元绘制,比如线、背景和文本。eRCP 的实现已经提供了三种 “drawer” 类 — 用于绘制单独单元格的 CellDrawer、用于绘制方块区的 BoxDrawer 和用于绘制整个数独游戏板的 BoardDrawer。DrawingContext 类用于管理图形资源,比如绘制应用程序使用的颜色和字体。绘制游戏板包括绘制 9 个方块区和全部 81 个单元格。游戏板还会跟踪并绘制突出显示的单元格 — 用户当前与之交互的单元格。绘制方块区只需要使用一种背景色填充矩形(分别使用 GC 的 setBackground(Color) 和 fillRectangle(int, int, int, int))。最后,绘制单元格包括使用 drawRectangle(int, int, int, int) 绘制单元格的框,以及使用 drawText(String, int, int, int) 绘制单元格的当前值。文本字体使用 setFont(Font) 设置,而单元格的前景色使用 setForeground(Color) 设置。突出显示的(悬浮式)单元格使用不同的颜色和更粗的线绘制,并且使用较小的文本在单元框中输出它们的可用值。清单 5 展示了 CellDrawer 的 drawCell 方法的主体。清单 5. CellDrawer 的 drawCell 方法使用 GC API 绘制单元格public void drawCell(GC gc, DrawingContext context) {
if (cell.isMarked()) {
gc.setBackground(context.getMarkedCellColor());
gc.fillRectangle(left, top, cellSize, cellSize);
} else if (!cell.isValid()) {
gc.setBackground(context.getInvalidCellColor());
gc.fillRectangle(left, top, cellSize, cellSize);
gc.setLineWidth(1);
gc.setForeground(context.getFrameColor());
gc.drawRectangle(left, top, cellSize, cellSize);
if (!cell.isEmpty()) {
if (cell.isGiven())
gc.setFont(context.getStaticCellFont(cellSize / 3));
gc.setFont(context.getCellFont(cellSize / 3));
String text = String.valueOf(cell.getValue());
Point textExtent = gc.textExtent(text);
gc.drawText(text, left + (cellSize - textExtent.x) / 2,
top + (cellSize - textExtent.y) / 2,
SWT.DRAW_TRANSPARENT);
} finally {
gc.setFont(null);
}用于绘制游戏板的 GC 是通过在画布(canvas)部件上实现 PaintListener 才得到的。SudokuView 类将这个控件创建为顶级 shell 的直接子元素。它还将 PaintListener 连接到控件。在处理画布部件的绘制事件时,将绘制游戏板。绘制事件提供对图形上下文的访问。 用户与游戏的交互式是通过 KeyListener 和另外一个命令处理的。KeyListener 用于在用户按下方向导航按钮(上、下、左、右)时在游戏板中导航。它还处理数字键盘 — 按下一个数字将把当前突出显示的单元格设置为该值。select 命令在用户按下 Select 按钮时(位于导航键盘的中部)起作用。它将当前突出显示的单元格的值加 1。清单 6 显示了如何将一个事件侦听器链接到画布部件来处理键盘输入。清单 6. KeyListener 代码片段显示了如何响应箭头导航 canvas.addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
Cell hoverCell = drawer.getHighlightedCell();
if (hoverCell == null)
if (e.character == SWT.BS || e.character == SWT.DEL) {
hoverCell.clear();
} else if (Character.isDigit(e.character)) {
hoverCell.setValue(e.character - '1' + 1);
} else if (e.keyCode == SWT.SHIFT) {
hoverCell.mark();
} else if (e.keyCode == SWT.ARROW_LEFT) {
Cell cell = hoverC
int column = cell.column==0 ? 8 : cell.column-1;
cell = board.getCell(cell.row, column);
} while (cell.isGiven());
drawer.highlightCell(cell);
canvas.redraw();
...尝试运行应用程序现在您已经编写好了所有必需的代码,您可以在 S60 平台 SDK 提供的手机模拟器中尝试运行应用程序(但是,请确保这时没有运行模拟器)。构建、打包应用程序和部署到模拟器中Eclipse、MTJ 和 S60 SDK 使这些任务变得非常简单。在 Application Descriptor 编辑器中,选择 overview 页面并单击 Debugging 区段中的 Launch as emulated Java ME MIDlet in Debug mode。这将创建一个名为 Sudoku 的调试启动配置并启动它。注意只需单击一次该链接,因为它在每次单击时都会创建一个新的启动配置。您可以从 Debug History 中选择相同的启动配置。注意,启动程序将负责完成所有必要的打包工作。图 10. S60 平台 SDK 展示了模拟器启动过程应用程序启动后,可以看到出现了一个新的 SDK 窗口,显示了这一过程,如图 10 所示。在这期间,SDK 启动模拟器并在其中打开 Debug Agent 应用程序。这个代理将等待调试器连接并处理 MIDlet 安装和启动。您将看到这一过程将记录到模拟的手机屏幕上。当完成整个过程后(将超过 1 分钟的时间),应当会看到您的应用程序出现在模拟的屏幕中。图 11 展示了运行中的 Sudoku 应用程序的屏幕截图。注意,需要关闭模拟器来重新启动应用程序。只需要重新启动 Sudoku 启动配置,SDK(以及模拟器中运行的 Debug Agent)将完成其余的工作。同时注意重新启动只使用了很短的时间。图 11. 运行在 S60 模拟器上的 Sudoku和启动特定的 MIDlet 不同的是,您可以将项目作为一个模拟的 Java ME JAD 进行启动。方法是使用 Application Descriptor 编辑器的 overview 页面中的 Launch as emulated Java ME JAD 链接创建另一个启动配置。这一启动配置与第一个启动配置不同,因为您不需要指定启动哪个 MIDlet 类;JAD 文件就是用于此目的。 最后,您可以使用 MTJ 构建和打包 Sudoku 游戏,以便部署到真实的移动设备上,在 Application Descriptor 编辑器的 overview 页面中,单击 packaging 区段中的 Create package。这将在项目的已部署文件夹中创建所需的 JAR 和 JAD 文件。然后可以将这些文件发布到手机用户可以使用的 Web 服务器上。用户随后就可以将数独游戏安装到他们的手机中,方法就是使用移动 Web 浏览器打开 JAD 文件。结束语在本教程中,您了解了 Eclipse 专门为移动设备提供的部件工具箱 eSWT。您也了解了 eSWT 如何帮助您利用 S60 平台的威力,这种平台可以安装在各种各样的手机中。您开发了一个非常简单的数独游戏,但是它演示了为 S60 平台编写基于 eSWT 的应用程序所需的步骤。Eclipse SDK 和 Mobile Tools for Java 极大地简化了这一过程。使用 S60 平台 SDK 进行开发,您不需要实际购买手机就可以在模拟环境中开发和测试应用程序。
下载资源 (os-eclipse-eswt-sudoku_src.zip | 288KB)相关主题 提供了有关 S60 的所有信息。Sun Developer Network (SDN) 提供了有关
查看 ,获得使用 Eclipse Mobile Tools for Java (MTJ) 的入门帮助。
项目源代码库,包括示例 eRCP Sudoku 项目。
查阅大量有关
的文档、教程、演示和录像。 V5 或更高版本可从
的最新版 V0.9。
和 Feature Pack 2。
找到最新的 。
查看 “”。
从 Eclipse Foundation 下载 。
浏览 developerWorks 上的所有 。
您是 Eclipse 新用户吗?请阅读 developerWorks 文章 “” 以了解它的起源和架构,以及如何用插件扩展 Eclipse。
通过查阅 IBM developerWorks 的
提高您的 Eclipse 技能。
添加或订阅评论,请先或。
有新评论时提醒我
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Open sourceArticleID=374732ArticleTitle=为 Nokia S60 智能手机开发基于 eSWT 的应用程序publish-date=}

我要回帖

更多关于 java模拟器安卓版 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信