用 C 风格编写 Java SE






3.26/5 (17投票s)
用于为 MPU 编写 C 语言程序的手机 Java 语言软件。
Java C 风格编程。

1. 文章的主要思想。
本文旨在展示如何使用经典的 C 语言风格在 Java 语言上进行编程。这种方法的实际重要性典型示例是带有 J2ME 的手机,您必须使用 Java。这种方法例如适用于微处理器 (MPU) 程序员,他们大多使用经典的(或面向过程的)单线程 C 语言程序来编程这些设备,而无需学习 Java 语言。
这个目标的实现基于两点:
这种风格被称为 Java-Rapid 编程接口,因为它使 C 程序员只需很少的额外 Java 知识就能快速为 Java 手机创建应用程序。有关适用于许多平台(Win32、Linux、WinCE、DOS 和 ReactOS)的 Rapid 接口的更多信息,您可以在 此处找到。本文中建议的库主要用于将手机编程为微控制器的显示器,但您可以添加额外的命令来扩展 Java-Rapid 的应用范围。所有源代码均可用。
需要注意的是,尽管您的程序将使用 Java 语言(如果您愿意,可以在其中添加任何 Java 构造),但实际上您的程序语法将与经典 C 语言非常接近。
2. Java-Rapid 程序接口的实际使用
实际上,Java-Rapid 编程接口由两个 Java 源代码文件组成:rapid.java 和 rapcanvas.java。您必须将它们复制到您的项目源代码目录。Rapcanvas.java 包含子例程:private void run() - 这是 C 语言区域:您可以在其中以及附近使用 C 风格语言编写算法。您只能在同一文件中使用 C 风格的子例程。以下章节:2.1...2.4 适用于没有 Java 编程经验的程序员,其中详细解释了如何实际使用 Java-Rapid 编译 jar 文件。有经验的程序员可以跳过这些章节。首先,您必须安装用于开发 J2ME Midlet 的标准软件。为此目的有几个免费分发软件包。这里我们将考虑其中两个最典型的。
2.1 KToolBar。
KToolBar 是 Sun Microsystems 创建 Midlet 的标准免费软件。它没有自己的文本编辑器,因此无法自动跳转到源代码文件中的错误位置。
1. 通过选择菜单选项:新建项目来创建项目。项目名称可以随意(它将是 jar 文件的名称),但 Midlet 类名称必须是精确的:Rapid(以大写字母开头)。在 API 选择(您可以在创建新项目时输入,或者如果选择 设置 选项,则稍后输入)中。选择 自定义 并选择 配置文件 并设置与您的手机对应的配置,例如:MIDP 2.0,CLDC 1.1。在 可选 中选择以下各项:
如果您在此部分做出错误选择,您可能会在没有错误的情况下编译您的应用程序,但在手机上启动它时,您可能会收到错误消息,例如:错误应用程序。此处讨论的所有应用程序都在典型的非顶级性能手机 SonyEricsson K550 上进行了测试,该手机具有 MIDP 2.0、CLDC 1.1、176*220 像素屏幕。
2. 找到创建项目所在的文件夹。它始终位于 KToolBar 文件夹的 Apps 子文件夹中(在 KToolBar 中没有其他位置)。但是,Sun KToolBar 的此文件夹隐藏在 Documents and Settings\User\j2mewtk 中,对于 SonyEricsson KToolBar,它位于应用程序的基本文件夹中。将 Java-Rapid 的两个基本文件:rapid.java 和 rapcanvas.java 复制到您的项目 src 子文件夹(创建项目后必须为空)中。
3. 使用文本编辑器(例如 EditPlus)在 rapcanvas.java 中找到子例程 public void run()(它必须是空的),并在其中添加您的 Java-Rapid 应用程序(例如从下载中获取的任何示例应用程序)。保存文件。现在一切准备就绪,可以构建应用程序。
4. 使用 KToolBar 的 构建 选项构建应用程序(KToolBar 有一个有用的选项 清除控制台,用它来删除以前的信息)。如果遇到错误,请纠正它们。KTollBar 会提供检测到错误的行号和错误类型。您可以使用文本编辑器轻松找到这一行。实际上,在处理项目时,两个程序必须同时打开:EditPlus 和 KToolBar。纠正错误后,不要忘记保存文件,然后才能再次使用 KToolBar 的 构建 选项。修复所有错误后,使用菜单选项:项目/打包/创建包 来创建 jar 文件。
5. 您可以使用 运行 选项进行模拟来测试您的应用程序,但这仅适用于简单程序。然后将 jar 文件上传到手机(参见 2.3 节)并在实际平台上继续测试。jar 文件将位于 bin 子文件夹中。
2.2 NetBeans。
NetBeans 速度很慢,但它具有在线语法检查功能,这对初学者来说非常方便。
1. 使用菜单选项:文件/新建项目/移动/MIDP 应用程序 创建一个新的空项目(取消选中 创建 Hello MIDlet)。选择 Midlet 的名称和目录 (NetBeans 允许这样做)。选择必须与您的手机对应的配置,例如 CLDC-1.1, MIDP-2.0。这非常重要,否则您的 Midlet 将无法在手机上工作(模拟器会工作)而没有任何提示。
2. NetBeans 将创建项目目录。子目录 src 将为空。将 rapid.java 和 rapcanvas.java 两个文件复制到其中。关闭/重新打开您的项目以刷新项目的源文件。您应该在项目的 src 文件中看到新文件。
3. 选择 菜单选项 项目属性/应用程序描述符/MIDlet/添加。不要更改任何内容(如果您更改了,您的工作在最后阶段将导致 安装失败)!它必须是:
选择“确定”并退出此选项。
4. 在 RapCanvas.java 文件中找到子例程 Run()。这是您必须用 Rapid 编写应用程序的地方。如果需要,您可以在其后添加子例程。不建议对 RapCanvas.java 文件的其他地方进行任何更改。建议首次从下载中复制示例并编译它们。
5. 按 构建 按钮并编译您的应用程序。可能会发现错误。纠正您的文本。然后按 运行 在仿真中运行您的应用程序。
6. 最后将 jar 文件上传到您的手机。它位于您项目的 bin 子目录中。
2.3 通过蓝牙将 jar 文件上传到手机
如果您的手机有蓝牙(并且如果您想与微控制器通信,您就需要它),您可以使用此连接,而无需任何额外的硬件和电缆。
1. 使用 BlueSoleil 软件。 在 PC 上运行 BlueSoleil。打开手机上的蓝牙。您的手机应该被检测到(双击橙色 地球 以将设备检测为环绕 地球 轨道上的卫星)。与 PC 建立连接。在 BlueSoleil 中,右键单击您的手机并选择 刷新服务,然后选择 建立连接/文件传输。使用标准的拖放操作发送您的 jar 文件(不要忘记在手机上确认联系)。
2. 使用标准 MS Windows 蓝牙软件。 打开程序(必须事先设置好与手机的连接)。选择 发送文件 选项,在第一个窗口中选择您的手机,在下一个窗口中选择要发送的文件。您的 jar 文件将被上传到任何可用文件夹(上传期间 游戏 和 应用程序 文件夹不可用)。如果存在同名文件,手机会询问您是否覆盖它(但实际上它通常不会覆盖文件,而是像 UNIX 操作系统一样在末尾添加带有 ..._2, ..._3 等后缀的新文件)。手机的文件系统不如 Windows 好,因此通常要查看新文件,您必须重新进入文件夹。运行 jar 文件。此时它会将您的应用程序安装到“禁止”应用程序文件夹。选择 游戏 或 应用程序 文件夹并安装您的应用程序。这不是透明操作,因为手机软件可能会在没有任何提示的情况下拒绝安装(只是输出 操作失败)。最常见的原因是,当您创建项目时,您的设置与手机的设置不符。在安装过程中,手机会问您重要问题,例如 保留现有数据? 这个问题意味着:J22ME 为应用程序设置分配了一些服务内存。其中包含您使用 快速保存 命令保存的内容。如果您选择 是,所有设置都将保留。只有在那之后,您才会被要求启动您的应用程序。在手机上调试应用程序时,手机最重要的键是 菜单事件 键(标记为 2 个矩形)。它的作用类似于 Windows 的 Ctrl/Alt/Del,并提供强制关闭挂起应用程序的功能。如果您没有此键,调试应用程序将是可疑的。
2.4 为 Java-Rapid 启用 EditPlus 文本编辑器。
如果您正在使用 KToolBar 软件,建议使用 EditPlus 编辑器。此编辑器有 Java-Rapid 的特殊文件可供下载。从 www.editplus.com 下载 EditPlus 发行版并安装。将 java.asp 和 java.stx 文件替换为为 Java-Rapid 制作的特殊文件。建议将 java-rapid.hlp 文件复制到该目录。运行 EditPlus。在菜单选项中:工具/配置用户工具/添加工具/帮助文件。输入菜单文本:帮助,命令:使用文件浏览器查找 Java-Rapid 帮助文件 (java-rapid.hlp)。现在,源文件中的所有 Java-Rapid 命令都将显示为绿色。将光标移动到绿色单词并按 Ctrl/1,您将获得该命令的上下文帮助。要获得自动完成功能,请输入 Java-Rapid 命令的名称和空格。要查找括号对,请使用 搜索/选择括号。
3. 下载,示例。
下载源代码和示例 - 77 KB
下面的下载包括以下文件。
HellowWorld.rap - 最简单的程序。它非常简单,其代码可以在这里展示:
public void run()
{ printf("Hello World");
Wait(-1);
exit();
}
4. JAVA-RAPID 应用程序的结构。
程序的一般结构基于以下方法。所有外部事件(如按键、选择菜单选项等)都会将全局变量 EventID 更改为某些预设的数值。零表示没有事件。在程序中,您必须组织一个或多个工作循环,在其中分析 EventID(并执行应用程序所需的所有其他任务)。Java-Rapid 中主子例程的文本可以如下所示:
public void run()
{ int x,y,cod.........
String buf=new String();
.........
Menu(.........
QuitEvent(999); // 预设退出事件
KeyEvent(998,0); // 预设按键事件
//------- 工作周期 ---------------
while(EventID !=999)
{ switch(EventID)
{
Case 998: EventID=0; cod=Inkey();.........break;
..........................................
}
//-- 独立于系统事件部分 --------
..............................
Wait(1); // 对于单线程非常重要
}
exit();
}
public String Sub(int x, byte[] y, String Z)
{ String str=new String();
......................
return str;
}
J2ME 中的子例程与 C 语言类似,但存在一些差异:
5. Java 变量
可用变量类型与 C 语言不同。在 C 区域中,您必须使用 Java 变量。它们如下:
变量声明如下:
short n;
byte[] data=new byte[128];
String text=new String();
String[] SA=new String(32);
EventID - Java-Rapid 的特殊系统变量。EventID 具有固定名称(您不能更改)并且是全局的。用户必须在程序开始时声明某些系统事件(例如按键或选择菜单项)的 EventID 值。如果没有事件,EventID 为零。在工作循环中,您必须控制 EventID 的值。
6. Java-Rapid 命令。
6.1 类型转换。
6.2 数学函数
6.3 系统命令
属性列表
"rap_version"
"DxFont"
"DyFont"
"DxScreen"
"DyScreen"
"isDoubleBuffer"
"MemTotal"
"MemFree"
还支持 Java 命令 System.getProperty(prop) 的所有属性;这些属性可能因不同的手机而异。参数 prop 的示例:
"microedition.configuration",
"microedition.profiles",
"bluetooth.api.version",
"microedition.media.version",
"supportTrueColor",
"microedition.commports"
其中
tau - 延迟,单位毫秒
Wait(-1) - 等待直到按下任意键
此命令在 Java-Rapid 中非常重要,因为它会停止当前线程并让其他线程执行其工作。建议将其包含在工作循环中,并设置最小延迟:Wait(1);
Java-Rapid 命令与 C 语言不同,例如:
printf("text1"+var1+"text2"+var2);
其中
var1,var2 - 任意类型变量的名称(它们的打印格式自动设置)。
text1,text2 - 固定文本(字符串字面量)。它们可以包含 \n 表示回车。
此命令具有无限滚动屏幕的可能性,采用所谓的 DOS 或 控制台 风格,非常方便。
如果屏幕上还输出了某些图形基元
1) 它们不会随文本一起滚动;
2) 文本将始终输出在图形之上
如果在 printf 命令的变量列表中第一个参数是数字,您必须在其前面输入空字符串字面量:
int x;
........
printf(""+x);
其中
x, y - 像素坐标。0,0 点对应于输出文本第一个字符的左上角。
命令对当前屏幕上的输入数量有限制(不考虑滚动出屏幕的行)- 100 个条目。命令的语法与 C 语言一致。
其中
name - 由几个单词组成,顺序不限(大小写敏感)
"Syst[em]" - 系统,
"Mono[space]" - 等宽
"Cou[rier]" - 等宽
"Prop[ortional]" - 比例
"Ari[al]" - 比例
"B[old]" - 粗体
"I[talic]" - 斜体
"U[nderline]" - 下划线
大小:1- 小,2-中,3-大
字符的实际大小取决于手机型号。某些字体可能在您的手机上不可用。
示例:Font(2,"Prop BI");
字体将作用于所有屏幕。
从命令返回 - 按 Enter 键。DelBack - 键可用。您可以多次使用此命令,例如:
printf("\nYear ==>"); gets(buf1);
printf("\nMonth ==>"); gets(buf2);
printf("\nDay ==>"); gets(buf3);
其中
XY[0]=x, XY[1]=y - 坐标。
其中
nota - MIDI 记谱法中的标准音符编号 1,..., 127
duration - 持续时间,单位毫秒
level - 音量 0....100
void QuitEvent(int iEvent)- 如果您尝试关闭应用程序,将发生退出事件
void KeyEvent(int KeyDownEvent,int KeyUpEvent)- 按键按下和释放事件。
您还必须在菜单命令中设置事件 ID
6.4 日期和时间
其中
TT[0]=小时,
TT[1]=分钟,
TT[2]=秒
其中
DD[0] -年
DD[1] - 月 (1,2...12)
DD[2] - 日 (1,2....31)
此命令在此实现中仅适用于东半球。
在某些手机(例如 SonyEricsson)中,没有内部机制可以自动设置 DST,您必须进入系统菜单手动更改。
其中
DD[3]={yy,mm,dd}
TT[3]={dd,mm,ss}
儒略日从格林威治时间 2000 年 1 月 1 日 12:00:00 开始。用于天文学。儒略日对地球上所有点都相同。
其中
DD[0] - 年 (>=1906)
DD[1] - 月 (1.....12)
DD[2] - 日 (1.....31)
返回 - (星期日=0, 星期一=1,....)
如果日期错误(例如 2000 年 5 月 32 日),则 week < 0
其中
DD[0] - 年 (>=1906)
DD[1] - 月 (1.....12)
DD[2] - 日 (1.....31)
返回 - 一年中的天数
此命令便于日期比较。例如,您需要选择 2 月 15 日至 3 月 15 日之间的事件。
Java-Rapid 中的一年中的天数与日期相关,3 月 1 日在闰年和非闰年中将具有相同的数字。
6.5 标准 C 字符串操作
-1 表示不相同
其中
SA - 字符串数组
命令执行后,字符串数组中的字符串将被替换。
其中
Str - 源字符串
i - 查找单词的起始位置
由于这里没有返回 i,请使用以下算法获取所有单词:
while(text1 !=null)
{ text1=GetWord(text,i);
if(text1!=null)
{ printf("\n"+text1);i=i+Strlen(text1)+1;
}
else printf("\n=== Finish ===");
}
6.6 标准文件操作
int open(String name,"W");
同时只能打开两个文件:一个用于读取,一个用于写入。
返回打开文件的句柄
其中
h - 从 open 命令打开的文件句柄
buf - 要写入的缓冲区名称(要写入的数据只能是字节数组)
n - 要写入的字节数
int read(int h,byte[] buf,int n)- 读取 n 个字节
其中
h - 从 open 命令打开的文件句柄
buf - 要读取到的缓冲区名称
n - 要读取的最大字节数
返回 - 读取的字节数。
返回=-1 - 文件结束
或读取错误
数据只能读取到字节数组,n 是请求的字节数,返回的是实际读取的字节数。
其中
path0 - 搜索的起始目录,例如 "e:/Other/"。如果您想从顶部搜索,请使用 "/"。这里没有使用 J2ME 的完整名称,例如:file:///,而只使用了部分 - 类似于 Windows OS。open 命令也是如此。需要提及的是,并非 J2ME 中的所有目录都可用。不同型号的手机有不同的文件系统。例如,SonyEricsson 设备有字母:
c:/ - 主内存
e:/ 可移动闪存
返回 null - 意味着拒绝选择文件。
6.7. 保存/恢复
命令使用 J2ME 的 RecordStore 机制。您可以为每个应用程序保存和恢复任意数量的 Java 字符串。它们没有名称,只有记录编号:0,1,...。您可以添加和更新它们。即使您通过安装新版本来更新应用程序,如果您拒绝“删除应用程序数据”等选项,记录也可能不会被删除。将 str 保存到 RecordStore 中记录编号为 j 的记录。
如果 RecordStore 之前未创建,它将被创建。
如果 j < jmax,则 j 记录将被更新,否则将向 RecordStore 末尾添加新记录,并返回其编号。
如果 j=-1 - RecordStore 将被删除。删除 RecordStore 的另一种方法是,当您通过新安装更新应用程序时,选择 删除应用程序数据 选项。
获取记录 j。如果 j>=jmax,您将得到 null
6.8 蓝牙操作
蓝牙操作基于与文件操作相同的命令组:open、close、read、write。您将使用 SPP(串行端口协议)配置文件。其中 attrib - 带有属性的字符串。对于服务器,例如:attrib="authenticate=false;encrypt=false;name=RFCOMM Server"
h=ComOpen(ComName,attrib)- 以已知主机名打开 COM 端口作为客户端 您必须输入由 6 位十六进制数字(即 12 个符号:0,1...9,A,...F)组成的服务器名称。
对于客户端在 Windows XP 下的 USB 蓝牙加密狗:attrib="2;master=false;encrypt=true;authenticate=true"
BT调制解调器(通过RS-232或UART与微处理器连接)同理
attrib=":1;master=true;encrypt=true;authenticate=true"
属性中的第一个符号是远程设备上的端口号或通道号。这是属性字符串中最重要的项(您无需编写其余部分,因为将采用默认值)。其值取决于您要连接的特定设备及其软件。Java-Rapid 无法确定此值,建议使用试错法。搜索范围不大:可能的值为 1、2、3。对于简单的蓝牙调制解调器,它是 1,因为它们只支持一个(SPP)协议。对于带有 BlueSoleil 的 PC 上的蓝牙,COM 端口 A 可以是 2,COM 端口 B 可以是 3(这两个值都有效)。有关更多详细信息,请参阅下载中的文档。
在 Java-Rapid 中,您只能有一个连接。
其中
data - 用于接收数据的字节数组缓冲区(其大小必须足够大) n - 要读取的字节数(0 表示读取所有可用字节)。
返回 - 实际接收的字节数。
6.9 图形命令
其中
iC - 清除后屏幕的颜色索引
其中
iColor1 - 字符的颜色索引
iColor2 - 背景颜色索引。
您可以使用 16 种索引颜色用于文本、文本背景、画笔(线条)和画刷(填充)。默认颜色值如下,但您可以更改它们。
0 黑色,1 深蓝色,2 深绿色,3 深青色,4 深红色,5 深紫色,6 浅灰色(非棕色),7 灰色,8 深灰色,9 浅蓝色,10 浅绿色,11 浅青色,12 浅红色(洋红色),13 浅紫色,14 黄色,15 白色
当您使用图形命令:line、rectangle、ellipse、curve 时,上述颜色将用于画笔和画刷。
其中
iColor - 颜色索引 (0…15)
R,G,B - 颜色分量 (0..... 255)
其中
Nx,Ny - X 轴和 Y 轴上的分区数量
命令只会绘制基线网格,不带文本。
其中
X,Y - 包含 X 和 Y 像素坐标的数组
n - 点数
iC - 颜色索引。
其中
ix1,iy1,ix2,iy2 - 线条点的像素坐标
iC - 颜色索引
其中
ix,iy,idX,idY - 矩形左上角坐标和像素大小
iPen - 边框颜色索引
iBrush - 画刷颜色索引。
其中
x1,y1 - 弧的起点
x2,y2 - 弧的终点
d - 弧的偏转 (double)
r=(d*d+L*L/4)/(2*d)
L - 弦长
iC - 颜色索引
其中
U - 要趋势的值数组 (int[5])
将趋势移动到下一步。这里的趋势完全占据屏幕,并且只有像素比例。您必须始终使用 5 个通道。它可以是信号和固定电平。当您使用趋势时,您不能使用任何其他图形基元(如 Line)
6.10 标准控件
如果标题很长,它将以跑马灯模式输出。
Q - 包含问题的字符串数组
A - 包含默认答案的字符串数组
n - 问题数量 (n<=5)
返回 - 包含答案的字符串数组。建议:长时间按手机按键以获得更好的命令效果。
Q - 带标题的字符串
A - 带默认答案的字符串
n - 文本缓冲区的最大大小
返回 - 带有答案的字符串
mode=mode1+mode2;
mode1: 0- MessageBox 显示 5 秒后自动关闭
10- MessageBox 有一个“确定”按钮
20- MessageBox 有两个按钮:“确定”、“取消”
mode2=1 - 信息
2 - 确认
3 - 警告
4 - 警报
5 - 错误
模式 2 的区别在于音乐支持。
返回 1 - 按下了“是/确定”按钮
-1 - 按下了“取消”按钮
i - 进度参数的当前值
imax - 进度参数的最大值。
要打开 ProgressBar,您必须使用 Progress(title,0,imax);
要关闭 ProgressBar,您必须使用 Progress(title,imax,imax);
ProgressBar (Gauge) 在全屏独立窗口中输出。它有两行文本和进度条。
顶部字符串:通用标题 (当 i=0 时的标题)
底部字符串:当 i>0 时,来自 title-argument 的当前事件信息
Texts - 包含项目文本的字符串数组。
Ids - 包含项目 EventID 的 int 数组
n - 项目数量
菜单会自动创建,每个手机型号可能以不同方式实现。例如,SonyEricsson 将第一个项目放在左侧软键下,所有其他项目放在右侧软键下,总标题为 其他
示例
String Text[]={"Exit","Open","Save"};
int IDs[]={ 999, 200, 201};
Menu(Texts,IDs,3);
命令占据整个屏幕并返回所选字符串数组子字符串的索引
title - 组合框窗口的标题
SA - 字符串数组名称
n - SA 中要输出的字符串数量
命令返回选定字符串的编号。
命令占据整个屏幕并返回所选字符串数组子字符串的索引
title - 组合框窗口的标题
SA - 字符串数组名称
n - SA 中要输出的字符串数量
命令返回所选项目的记录集
0-元素:选定项目的数量,然后是选定的索引。