LWUIT是j2me中使用广泛的UI库。LWUIT提供了ResourceEdit工具打包资源文件。这个资源文件可以包括主题、字体、图片、动画等。在基于LWUIT库的j2me程序启动时,资源文件被读取解析并导入内存的数据结构中。
LWUIT的资源文件的格式是固定的。前两个字节(用j2me中的short表示)记录了该资源文件中的资源数量。之后的部分被划分成了多个资源块,这个资源块的数量由前两个字节决定。在每个资源块中,第一个字节是magic number,记录了该资源的类型。紧跟着的是一个UTF字符串,记录了该资源的名称。UTF字符串后面部分的内容结构则与资源类型有关。
以主题为例,我用ResourceEdit加入一个命名为hello的theme,并在这个theme中,设置了List.bgSelectionColor和Form.bgColor的值。它的二进制结构如下所示:
第一、二字节:00 01;表示这个资源文件中包含了一个资源块。
第三字节:F2;这是一个magic number;表示这个资源块是主题。
第四字节:00 05 68 65 6C 6C 6F;这是一个UTF字符串:“hello”;也就是这个theme的名称。
以上部分是通用的结构;以下部分是主题相关的结构;
00 02;记录了该主题资源块中一共有2项。
00 15 73 74 2E 62 67 53 65 6C 65 63 74 69 6F 6E 43 6F 6C 6F 72;这是一个UTF字符串;即List.bgSelectionColor;
00 00 00 00;记录了这个项对应的值;
00 0C 46 6F 72 6D 2E 62 67 43 6F 6C 6F 72;这是一个UTF字符串;即Form.bgColor;
00 00 00 00;记录了这个项对应的值;
这是主题资源文件的结构。LWUIT提供了Resource类读取并解析这个二进制文件并写入LWUIT现有的内存结构中。
使用LWUIT后,内存中资源相关的有两个Hashtable,一个叫resource,一个叫resourceTypes。
resourceTypes中记录了id---type对;即资源的名称与资源的类型。例如上面的hello和0xF2。
resource记录了id-Hashtable对;即资源的名称与资源的hashtable。例如上面的hello与它所对应的Hashtable。
这个Hashtable中记录了attribute与值。
List.bgSelectionColor-------0x0000
Form.bgColor-----------------0x0000
这个Hashtable的构建是在Resource类中的loadTheme方法中完成的,在这个方法中也可以看到主题中的attribute值是固定的。
而前面的两个Hashtable的设置则是在Resource类中的setResource方法中实现的。
以上所有的操作都在一个语句中完成:
Resources r1 = Resources.open("/javaTheme.res");
将这些结构中的数据导入主题中则是在另一个语句中实现的:
UIManager.getInstance().setThemeProps(r1.getTheme(r1.getThemeResourceNames()[0]));
Resource.getThemeResourceNames方法实际上是遍历Hashtable resourceTypes,找到所有主题ID,以String[]的形式返回。
而Resource.getTheme则根据传入的string,在Hashtable resource中找到对应的Hashtable。
最后,UIManager的setThemeProps方法将这个记录了Attribute和值的Hashtable注入到主题中去。
在Theme管理中,LWUIT会给构建一个Hashtable,给表中的每个attribute默认一个值。而setThemeProps则是将传入的Hashtable与默认的表比较并修改默认的表。最后,会创建一个style。