<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Windy Ocean</title>
	<atom:link href="http://www.iclipp.com/blog/modo/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.iclipp.com/blog/modo</link>
	<description>Still waters run deep.</description>
	<lastBuildDate>Sat, 17 Jul 2010 03:01:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>《LWUIT 开发者指南》第十一章：资源</title>
		<link>http://www.iclipp.com/blog/modo/?p=3324</link>
		<comments>http://www.iclipp.com/blog/modo/?p=3324#comments</comments>
		<pubDate>Mon, 05 Jul 2010 02:11:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[j2me]]></category>
		<category><![CDATA[notes]]></category>
		<category><![CDATA[jwuit]]></category>

		<guid isPermaLink="false">http://www.iclipp.com/blog/modo/?p=3324</guid>
		<description><![CDATA[

11.1 资源元素

11.1.1 建立资源包

11.1.1.1 建立资源
11.1.1.2 载入资源


11.1.2  图像资源
11.1.3 索引图像
11.1.4 字体

11.1.4.1 系统字体
11.1.4.2 动态字体


11.1.5 本地化（L10N）
11.1.6 主题


11.2 LWUIT Theme Creator

11.2.1 图像和动画
11.2.2 字体
11.2.3 本地化
11.2.4 主题

11.2.4.1 例子：添加一个新主题
11.2.4.2 修改主题的属性
11.2.4.3 数据
11.2.4.4 自定义预览面板
11.2.4.5 已知问题







《LWUIT 开发者指南 LWUIT Developer Guide》
LWUIT 允许使用下列资源：

图像资源
动态字体
本地化包（L10N Bundle）
主题

资源可以作为一个包（一个可以在设备上载入和使用的二进制文件）发布。一个包可以在一个文件中组合几种不同资源类型，因此简化了发布过程和改善压缩比率。LWUIT 支持两种建立资源包的方法：

使用一组 Ant 任务
或者图形化的主题建立工具（请参见 【Theme Creator】）

11.1 资源元素
下面的章节详细讲述了五种资源类型以及它们以何种方式与资源包机制关联。
11.1.1 建立资源包
可以在应用程序标准构建过程中使用 Ant 建立资源包。资源文件必要时将已存在的文件转换为资源包。一个应用程序可以有任意数量的资源文件。
一个资源文件被完整地载入内存（受 Java ME IO 的限制），因此你应该根据应用程序流程的需要对资源进行分组。这将允许应用程序只载入某个给定窗体或用例所需的资源，以节省内存用于其他窗体或用例需要的资源。
11.1.1.1 建立资源
为了建立一个 Resource，在你的 build 文件里使用类似于下例子示的代码：
&#60;taskdef
  classpath="editor.jar"
  classname="com.sun.lwuit.tools.resourcebuilder.LWUITTask"
  name="build" /&#62;
&#60;build dest="src/myresourceFile [...]]]></description>
			<content:encoded><![CDATA[<div class="toc">
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-">11.1 资源元素</a></p>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-1-">11.1.1 建立资源包</a></p>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-1-1-">11.1.1.1 建立资源</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-1-2-">11.1.1.2 载入资源</a></li>
</ol>
</li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-2-">11.1.2  图像资源</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-3-">11.1.3 索引图像</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-4-">11.1.4 字体</a>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-4-1-">11.1.4.1 系统字体</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-4-2-">11.1.4.2 动态字体</a></li>
</ol>
</li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-5-l10n">11.1.5 本地化（L10N）</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-6-">11.1.6 主题</a></li>
</ol>
</li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-2-lwuit-theme-creator">11.2 LWUIT Theme Creator</a>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-2-1-">11.2.1 图像和动画</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-2-2-">11.2.2 字体</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-2-3-">11.2.3 本地化</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-2-4-">11.2.4 主题</a>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-2-4-1-">11.2.4.1 例子：添加一个新主题</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-2-4-2-">11.2.4.2 修改主题的属性</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-2-4-3-">11.2.4.3 数据</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-2-4-4-">11.2.4.4 自定义预览面板</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-2-4-5-">11.2.4.5 已知问题</a></li>
</ol>
</li>
</ol>
</li>
</ol>
</div>
<p><span id="more-3324"></span></p>
<p><a href="http://www.iclipp.com/blog/modo/?page_id=3302">《LWUIT 开发者指南 LWUIT Developer Guide》</a></p>
<p>LWUIT 允许使用下列资源：</p>
<ul>
<li>图像资源</li>
<li>动态字体</li>
<li>本地化包（L10N Bundle）</li>
<li>主题</li>
</ul>
<p>资源可以作为一个包（一个可以在设备上载入和使用的二进制文件）发布。一个包可以在一个文件中组合几种不同资源类型，因此简化了发布过程和改善压缩比率。LWUIT 支持两种建立资源包的方法：</p>
<ul>
<li>使用一组 Ant 任务</li>
<li>或者图形化的主题建立工具（请参见 【Theme Creator】）</li>
</ul>
<h3 id="toc-11-1-">11.1 资源元素</h3>
<p>下面的章节详细讲述了五种资源类型以及它们以何种方式与资源包机制关联。</p>
<h4 id="toc-11-1-1-">11.1.1 建立资源包</h4>
<p>可以在应用程序标准构建过程中使用 Ant 建立资源包。资源文件必要时将已存在的文件转换为资源包。一个应用程序可以有任意数量的资源文件。</p>
<p>一个资源文件被完整地载入内存（受 Java ME IO 的限制），因此你应该根据应用程序流程的需要对资源进行分组。这将允许应用程序只载入某个给定窗体或用例所需的资源，以节省内存用于其他窗体或用例需要的资源。</p>
<h5 id="toc-11-1-1-1-">11.1.1.1 建立资源</h5>
<p>为了建立一个 Resource，在你的 build 文件里使用类似于下例子示的代码：</p>
<pre class="brush:xml;light:false;">&lt;taskdef
  classpath="editor.jar"
  classname="com.sun.lwuit.tools.resourcebuilder.LWUITTask"
  name="build" /&gt;
&lt;build dest="src/myresourceFile .res"&gt;
  &lt;image file="images/myImage.png" name=”imageName” /&gt;
&lt;/build&gt;</pre>
<p>你可以把几种额外的资源类型加入 build 标签。这些可选的资源标签在本章后面的章节中讲述。</p>
<h5 id="toc-11-1-1-2-">11.1.1.2 载入资源</h5>
<p>使用类似下面所示的代码把资源载入你的应用程序：</p>
<pre class="brush:java;highlight:[];">Resources res = Resources.open(“/myresourceFile.res”);
Image i = res.getImage(“imageName”);</pre>
<h4 id="toc-11-1-2-">11.1.2  图像资源</h4>
<p>LWUIT 里有几种图像类型，它们中的大多数既能单独存储在 JAR 文件里，也能打包放进资源包内。</p>
<p>使用下面的代码载入 JAR 文件里存储的图像：</p>
<pre class="brush:java;highlight:[];">Image image = Image.createImage("/images/duke.png");</pre>
<p>Image 标签支持下列属性：</p>

<table id="wp-table-reloaded-id-31-no-1" class="wp-table-reloaded wp-table-reloaded-id-31">
<tbody>
	<tr class="row-1 odd">
		<td class="column-1">name</td><td class="column-2">资源的名字（默认是文件名）</td>
	</tr>
	<tr class="row-2 even">
		<td class="column-1">file</td><td class="column-2">用于这个图像的文件（必须）</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">indexed</td><td class="column-2">True 或 false，表示是否存储一个索引图像（Indexed Image）。默认值是 False（请参考下面的索引图像）</td>
	</tr>
</tbody>
</table>

<p>一旦被载入，图像就可以用作组件的背景，甚至可以作为一个能够包含图像的组件的图标。</p>
<p>可以使用<a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-3-">索引图像</a>里的示例代码把图像打包放进资源包。</p>
<h4 id="toc-11-1-3-">11.1.3 索引图像</h4>
<p>图像在程序运行时会占用大量内存。例如，一个作为 320&#215;240 分辨率 1.6 百万色手机背景的不想将占用 320&#215;240x4 字节（307200 字节 = 300 KB）。</p>
<p>某些设备只给 Java 分配了 2Mb 的 RAM，同时还具有高分辨率和高发色数，因此应用程序只有很少的空间可以使用。索引图像使用调色板绘制，而不是把图像保存为一组 Alpha，Red，Green 和 Blue（ARGB）数据，索引图像基于如下的设想：一个图像里的颜色不会多余256种（如果有更多颜色，Ant 任素将尝试适当降低颜色数，这样做会对是一些细节）。一个有 256 或更少色彩的图像可以用一个字节数组及一个整数数组（不大于 256&#215;4=1KB）来表示，因此可以减少大约百分之 70 的 RAM 占用！</p>
<p>例如，假设上面提到的图像使用了所有的 256 中颜色，它占用的内存将会是 320&#215;240+1024（77824 字节 = 76 KB），或者说节约了百分之 74.7 的空间！因为这种做法能够显著地节省内存占用，因此它在低端设备上特别受欢迎。</p>
<p>使用索引图像的缺点如下：</p>
<ul>
<li>因为索引图像在绘制时需要对每一个像素进行查询，因此绘制速度较慢。这在绘制复杂元素的时候可以觉察到速度的下降，但在现代设备上（甚至在比较低端的设备上）并不明显。</li>
<li>必须使用资源包来存储索引图像，因为没有所有 Java ME 设备都能支持的索引图像标准存储格式。</li>
<li>在运行时把图像转换为索引图像的速度可能非常慢，甚至可能失败（如果发色数很高的话），这就是为什么要在构建阶段选择索引图像比较有利的原因。</li>
<li>因为索引图像保存的时候没有被压缩，因此资源文件的尺寸看起来比较大（在设备上需要的保存空间也较大），但是，实际使用时 JAR 文件里索引图像的压缩比例很高，因此实际上它压缩后所占用的空间要小于相同的 PNG 图像）。</li>
</ul>
<p>更多有关内容可以参考 IndexedImage API 文档。因为索引图像从 Image 类派生，因此它们可以很好地在程序中代替 Image 类对象并保持兼容。</p>
<p>注意：索引图像不能变动（immutable），建立后不能被修改，因此象 getGraphics() 这样的方法不能正确工作。请查阅 API 文档来验证合适的功能。</p>
<h4 id="toc-11-1-4-">11.1.4 字体</h4>
<p>LWUIT 库支持位图字体（Bitmap Font），系统字体，以及可加载字体（Loadable Font）：</p>
<ul>
<li>系统字体使用基本的原生字体，基于通用 MIDP 字体。更多内容请参见 install-dir/docs/api/lwuit 下的 Font API 文档。</li>
<li>位图字体在桌面上生成作为图像文件的字体。这些图像可以用于在不需设备特殊支持的情况下绘制桌面高质量字体。</li>
<li>可载入字体支持使用名字甚至 TrueType 字体文件指定字体，如果底层操作系统支持这些字体，就会建立字体对象。</li>
</ul>
<p>所有字体都能用于主题文件并用 LWUIT 的 Font 类表示。</p>
<h5 id="toc-11-1-4-1-">11.1.4.1 系统字体</h5>
<p>使用三个基本参数可以定义一个系统字体：</p>

<table id="wp-table-reloaded-id-35-no-1" class="wp-table-reloaded wp-table-reloaded-id-35">
<tbody>
	<tr class="row-1 odd">
		<td class="column-1">Face</td><td class="column-2">有效值是 FACE_SYSTEM, FACE_PROPORTIONAL 和 FACE_MONOSPACE</td>
	</tr>
	<tr class="row-2 even">
		<td class="column-1">Style</td><td class="column-2">有效值是 STYLE_PLAIN, STYLE_ITALIC, STYLE_BOLD。</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">Size</td><td class="column-2">有效值是 SIZE_SMALL, SIZE_MEDIUM, SIZE_LARGE。</td>
	</tr>
</tbody>
</table>

<p>使用下面的代码建立一个系统字体：</p>
<pre class="brush:java;highlight:[];">Font.createSystemFont(Font.FACE_SYSTEM,
                      Font.STYLE_BOLD,
                      Font.SIZE_MEDIUM);</pre>
<p>使用下面的代码建立一个粗/斜体字体样式：</p>
<pre class="brush:java;highlight:[];">Font.createSystemFont(Font.FACE_SYSTEM,
                      Font.STYLE_BOLD | Font.STYLE_ITALIC,
                      Font.SIZE_MEDIUM);</pre>
<h5 id="toc-11-1-4-2-">11.1.4.2 动态字体</h5>
<p>不同的平台提供不同的字体支持，例如，手机通常只支持系统字体和位图字体，而电视通常支持 TrueType 字体，但对位图字体的支持不佳。LWUIT 支持在资源中定义字体，允许资源适配不同设备。为了实现可移植性，如果底层系统支持某个可加载字体，LWUIT 允许指定它，并允许打包位图以进一步提高可移植性。作为后备，总是会定义一个系统字体，这样就可以在系统不支持原生字体或开发者不想使用位图字体的时候使用这个系统字体。也可以使用下面的格式利用 Ant 任务定义一个字体：</p>
<pre class="brush:xml;light:false;">&lt;build dest="src/myresourceFile.res"&gt;
     &lt;font logicalName=”SansSerif” name=”myFont” size=”20” /&gt;
&lt;/build&gt;</pre>
<p>字体的 Ant 任务支持下列属性：</p>

<table id="wp-table-reloaded-id-36-no-1" class="wp-table-reloaded wp-table-reloaded-id-36">
<tbody>
	<tr class="row-1 odd">
		<td class="column-1">name</td><td class="column-2">从资源文件载入的字体名称（可选：默认是逻辑名或文件名）</td>
	</tr>
	<tr class="row-2 even">
		<td class="column-1">charset</td><td class="column-2">默认是英语字母，数字和常用符号。应包含一个字体支持的所有字符的列表。例如，如果一个字体用于大写字符，它应该保留空间用于定义字符集“ABCDEFGHIJKLMNOPQRSTUVWXYZ”</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">src</td><td class="column-2">在使用一个文件时的字体文件。默认是 TrueType 字体。</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">size</td><td class="column-2">字体的尺寸（浮点值）</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">bold</td><td class="column-2">默认是 False。指示字体是否为粗体。</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">trueType</td><td class="column-2">默认是 True。只在使用 src 属性时才有意义。如果设置为 False，将使用 Type 1 字体。</td>
	</tr>
	<tr class="row-7 odd">
		<td class="column-1">antiAliasing</td><td class="column-2">默认是 True。如果设置为 False，字体将有锯齿（aliased）。</td>
	</tr>
	<tr class="row-8 even">
		<td class="column-1">logicalName</td><td class="column-2">字体的逻辑名，同 Java SE java.awt.Font 中的定义：Dialog, DialogInput, Monospaced, Serif 或 SansSerif。</td>
	</tr>
	<tr class="row-9 odd">
		<td class="column-1">createBitmap</td><td class="column-2">默认是 True。如果设置为 False，将不建立这个字体的位图版本。</td>
	</tr>
</tbody>
</table>

<h4 id="toc-11-1-5-l10n">11.1.5 本地化（L10N）</h4>
<p>资源包支持本地化资源，允许开发者在资源文件里存储“键-值”对。本地化包使用 Java 属性文件格式，只支持 USASCII 字符。要输入其他语言的字符，可以使用特殊的编辑器（例如 NetBeans）或与 Ant 任务一同使用 JDK native2ascii 工具来转换文件。</p>
<p>使用下面的代码建立一个资源包：</p>
<pre class="brush:xml;light:false;">&lt;build dest="src/myresourceFile.res"&gt;
   &lt;l10n name="localize"&gt;
      &lt;locale name="en" file="l10n/localize.properties" /&gt;
       &lt;locale name="iw" file="l10n/localize_iw_IL.properties" /&gt;
   &lt;/l10n&gt;
&lt;/build&gt;</pre>
<p>使用下面的语法格式载入本地化资源：</p>
<pre class="brush:java;highlight:[];">Hashtable h = bundle.getL10N("localize", "en");</pre>
<p>这个哈希表包含了资源包里定义的资源键值对，简化了本地化工作。LWUIT 通过 <strong><code>UIManager.setResourceBundle(Hashtable) </code></strong>方法支持自动自动本地化。这样做将在建立一个本地化资源时安装一个全局资源包，因此允许替换整个 UI 语言而不需要手工查询资源包。</p>
<h4 id="toc-11-1-6-">11.1.6 主题</h4>
<p>This section discusses how themes work as resources. See Chapter 8 and Chapter 10 to both of these chapters in-depth discussions of styles and theming in LWUIT.</p>
<p>这一节讨论如何把主题作为资源使用。更多关于 LWUIT 样式和主题的深入内容请参考【第八章】和【第十章】。</p>
<p>A theme can be defined using a key value properties file containing selectors and values. A selector can be defined as an attribute value, optionally with a component name prepended to it for narrowing the selection further.</p>
<p>可以使用一个包含选择器（Selector）以及值的键值属性文件定义一个主题。一个选择器可以被定义为一个属性值，可选地，在属性前加上一个组件名作为前缀来进一步缩小选择范围。</p>
<p>The value of an entry in the theme depends on the type of the entry, some entries such as bgImage expect an image object and some entries such as Font expect a font definition. Most entries just expect numbers. For example, this is a typical snippet from a theme:</p>
<p>主题中某个条目的值取决于这个条目的类型，某些条目例如 bgImage 的值是一个图像对象，某些条目例如 Font 的值则是一个字体定义。大多数条目的值就是数字。例如，下面是一个主题中的常见片段：</p>
<pre class="brush:plain;light:false;">sel#fgColor= 0017ff
font= systemSmall
Form.bgImage=myBackground
Form.font=Serif
SoftButton.bgColor= ff
SoftButton.fgColor= ffffff</pre>
<p>使用下面的代码把这个主题加入一个资源：</p>
<pre class="brush:xml;light:false;highlight:[7];">&lt;build dest="src/myresourceFile .res"&gt;
   &lt;font logicalName="Serif" bold="true" /&gt;
   &lt;font createBitmap="false" name="systemSmall"
        system="FACE_SYSTEM ; STYLE_PLAIN; SIZE_SMALL" /&gt;
   &lt;image file="images/background.png" name="myBackground"
        pack="true" /&gt;
   &lt;theme file="themes/myTheme.conf" name="myTheme" /&gt;
&lt;/build&gt;</pre>
<p>可以使用下面的代码安装这个主题：</p>
<pre class="brush:java;highlight:[];">UIManager.getInstance().setThemeProps(res.getTheme(myTheme));</pre>
<p><div class="note"><div class="noteclassic">这里的 myTheme 是一个由给定主题的属性构成的哈希表。</div></div></p>
<h3 id="toc-11-2-lwuit-theme-creator">11.2 LWUIT Theme Creator</h3>
<p>&#8230; &#8230;</p>
<p>Theme Creator 能够完成 Ant 任务能够完成的工作，只有一个限制：在 Theme Creator 里，主题使用的所有<strong>位图字体</strong>必须在主题内部定义，主题不能引用其他资源文件里定义的<strong>位图字体</strong>。</p>
<p>Theme Creator 支持<a href="http://www.iclipp.com/blog/modo/?p=3324#toc-11-1-">资源元素</a>里描述的六种资源类型。</p>
<p>&#8230; &#8230;</p>
<h4 id="toc-11-2-1-">11.2.1 图像和动画</h4>
<p>图像和动画可以用于<strong>主题</strong>或 LWUIT <strong>应用程序</strong>。Theme Creator 支持图像（JPEG，PNG）和动画 GIF。图像和动画可以使用 &#8230; 按钮来替换。</p>
<p>标准图像也可以被索引。索引图像在最终应用程序里占用的空间更小，因此占用的内存也更小，但是绘制它需要更长的时间而且只支持 256 中颜色。当你点击 Indexed 图像单选按钮时，将检验颜色的数目。如果颜色多于 256 种颜色，应用程序将尝试减少发色数（将给出画质选项）。一个好方法是在包含图像前使用图像编辑工具来对它们进行索引。</p>
<p><div class="note"><div class="notetip">注意：Alpha 通道（除完全透明的情况）在和索引图像一同使用时可能会出现问题。</div></div></p>
<h4 id="toc-11-2-2-">11.2.2 字体</h4>
<p>Theme Creator 可以使用设备特定字体或从任何桌面系统字体生成位图字体。&#8230; &#8230;</p>
<p>&#8230; &#8230;</p>
<p>为了建立位图字体，必须选择“Create Bitmap”复选框。确定指定了这种字体里你所需要的字符（默认是英文大小写字母、数字及符号）。注意：从字体中挑选的字符越多，字体占用设备的 RAM 就越多。位图字体内建了反锯齿（Anti-aliasing）功能。但在 Java 5 下运行时，Theme Creator 有两个反锯齿选项：Off 表示这个位图字体里没有反锯齿功能，Simple 表示标准反锯齿功能。</p>
<h4 id="toc-11-2-3-">11.2.3 本地化</h4>
<p>A localization resource can be edited by assigning key/value pairs to use within the application. A key can be mapped to a <span style="color: #ff0000;">resource name</span> (<strong><span style="color: #ff0000;">?</span></strong>) in any locale.</p>
<p>可以通过分配键值对使用本程序来编辑本地化资源。一个键可以映射到任何 Locale 的一个资源名。</p>
<p>&#8230; &#8230;</p>
<h4 id="toc-11-2-4-">11.2.4 主题</h4>
<p>为了修改主题资源，可以设置选择器和主题资源为适当的值来生成漂亮的 UI。当建立新主题时，将显示一个包含选择器和资源的表格（开发者需要的关于主题的更深入内容请参见【第十章】）。</p>
<p>要修改主题，在左边选择一个选择器并点击 Edit 按钮。你可以使用 Add 按钮在主题中添加新选择器。要修改一个已经存在的选择器，选择它并双击或按下 Edit 按钮。</p>
<h5 id="toc-11-2-4-1-">11.2.4.1 例子：添加一个新主题</h5>
<p>&#8230; &#8230;</p>
<p><div class="note"><div class="noteclassic">不带限定前缀的选择器的设定值将作为默认值应用于主题的所有子元素，除非这个子元素的这个选择器被单独设定。</div></div></p>
<p>&#8230; &#8230;</p>
<p>关于选择器的更多内容请参考【第八章】和【第十章】。</p>
<h5 id="toc-11-2-4-2-">11.2.4.2 修改主题的属性</h5>
<p>&#8230; &#8230;</p>
<p><div class="note"><div class="noteclassic">如果选择“Live Highlighting”复选框，在选择表格里的某项主题属性时，相应的属性将在最右边的预览窗口里闪烁，便于你了解当前元素是什么。</div></div></p>
<p>&#8230; &#8230;</p>
<h5 id="toc-11-2-4-3-">11.2.4.3 数据</h5>
<p>数据（Data）通常被开发者而不是设计者使用。</p>
<p>在这个部分里可以放入任何文件，以便开发者在运行时访问它们。这一部分（甚至当数据文件是图像或字体时）对其他部分的功能没有任何影响。</p>
<h5 id="toc-11-2-4-4-">11.2.4.4 自定义预览面板</h5>
<p>显示 LWUIT Demo 的预览面板可以方便地自定义其他的 MIDlet。Theme Creator 支持插入你自己的 MIDlet，这样你就能够实时测试你的主题。</p>
<p>使用Theme Creator 的 MIDlet &gt; Pick MIDlet 菜单并选择你自己的 MIDlet JAR 文件将其装入预览面板。</p>
<p>但是，使用这个功能时有一些限制：因为 MIDlet 将在 Java SE 中运行，它不能使用 javax.microedition 的 API。如果在程序中使用了这些 API，它们将以存根（Stub）的形式实现。例如，如果你使用了 RMS，GCF 或诸如此类的 API，所有的查询将返回 null，所有的操作都将不执行实际动作。另外，调用主题将不会有任何效果。</p>
<p><del datetime="2010-07-12T14:54:14+00:00">If there is a failure in the MIDlet the Theme Creator will silently load the LWUIT Demo in the preview and use it instead. To debug the failure, execute the Theme Creator from command line using java -jar ResourceEditor.jar.</del> <span style="color: #ff0000;">When entering the theme option</span> you can see the stack trace of the exception that caused the failure.</p>
<p>如果在这个 MIDlet 里发生了错误，Theme Creator 将在预览面板里自动载入 LWUIT Demo 来代替你的 MIDlet。为了调试错误，使用命令行 <code><strong>java -jar ResourceEditor.jar</strong></code><strong> </strong>来执行 Theme Creator。当进入主题选项时（<span style="color: #ff0000;"><strong>HOW?</strong></span>），将显示导致程序崩溃的异常有关的堆栈跟踪信息。</p>
<h5 id="toc-11-2-4-5-">11.2.4.5 已知问题</h5>
<p>当使用 Aero 主题时，某些操作系统在某些情形下可能会使得 Theme Creator 崩溃。这个问题源于 Java SE 的 Look &amp; Feel 的实现，唯一的解决办法是使用  Look &amp; Feel 菜单选项改变应用程序的 Look &amp; Feel。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iclipp.com/blog/modo/?feed=rss2&amp;p=3324</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《LWUIT 开发者指南》第二章：使用 LWUIT 器件</title>
		<link>http://www.iclipp.com/blog/modo/?p=3317</link>
		<comments>http://www.iclipp.com/blog/modo/?p=3317#comments</comments>
		<pubDate>Mon, 05 Jul 2010 01:41:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[j2me]]></category>
		<category><![CDATA[notes]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[lwuit]]></category>

		<guid isPermaLink="false">http://www.iclipp.com/blog/modo/?p=3317</guid>
		<description><![CDATA[

2.1 组件
2.2 容器
2.3 窗体
2.4 建立和设置一个 Form Label
2.5 按钮
2.6 单选按钮
2.7 按钮组
2.8 复选框
2.10 标签面板 TabbedPane
2.11 文本区 TextArea
2.12 文本域 TextField



《LWUIT 开发者指南 LWUIT Developer Guide》
2.1 组件
A Component is an object having a graphical representation that can be displayed on the screen and can interact with the user. The buttons, check boxes, and radio buttons in a typical graphical UI [...]]]></description>
			<content:encoded><![CDATA[<div class="toc">
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-1-">2.1 组件</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-2-">2.2 容器</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-3-">2.3 窗体</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-4--form-label">2.4 建立和设置一个 Form Label</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-5-">2.5 按钮</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-6-">2.6 单选按钮</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-7-">2.7 按钮组</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-8-">2.8 复选框</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-10--tabbedpane">2.10 标签面板 TabbedPane</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-11--textarea">2.11 文本区 TextArea</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3317#toc-2-12--textfield">2.12 文本域 TextField</a></li>
</ol>
</div>
<p><span id="more-3317"></span></p>
<p><a href="http://www.iclipp.com/blog/modo/?page_id=3302">《LWUIT 开发者指南 LWUIT Developer Guide》</a></p>
<h3 id="toc-2-1-">2.1 组件</h3>
<p>A Component is an object having a graphical representation that can be displayed on the screen and can interact with the user. The buttons, check boxes, and radio buttons in a typical graphical UI are all examples of a component. Component is the base class. All the widgets in the Lightweight UI Toolkit library use the composite pattern in a manner similar to the AWT Container and Component relationship.</p>
<p>Component 是基类。所有 LWUIT 器件都使用复合模式，类似于 AWT 容器和组件之间的关系。</p>
<h3 id="toc-2-2-">2.2 容器</h3>
<p>A Container is a composite pattern with a Component object. It enables nesting and arranging multiple components using a pluggable layout manager architecture. Containers can be nested one within the other to form elaborate UIs. Components added to a container are tracked in a list. The order of the list defines the components&#8217; front-to-back stacking order within the container. If you do not specify an index when you add a component to a container, it is added to the end of the list (and hence to the bottom of the stacking order).</p>
<p>使用可插拔的布局管理器架构嵌套和布置多个组件。容器可以嵌套。加入容器的组件用一个列表跟踪。列表元素的顺序定义了组件在容器里从前往后的顺序。如果在容器里加入组件时没有指定索引，这个组件将被加入到列表的末尾。</p>
<h3 id="toc-2-3-">2.3 窗体</h3>
<p>Form is a top‐level component that serves as the root for the UI library. This Container handles the title and menus and allows content to be placed between them. By default the form&#8217;s central content (the content pane) is scrollable. Form contains Title bar, MenuBar and a ContentPane. Invocations of Form&#8217;s addComponent method are delegated to the content pane’s addComponent. The same applies to most composite related methods (e.g. setLayout, getComponent and so forth).</p>
<p>窗体是一个顶层组件，作为整个 UI 库的根元素。容器管理标题和菜单并在其间加入内容。默认请款下，窗体中央的内容（内容面板）可以滚动。窗体包含标题条，菜单条和一个内容面板。对窗体 addComponent 方法的调用将被委派到内容面板的 addComponent 方法。同样的机制也用于大多数和复合模式有关的方法（例如 setLayout, getComponent 等等）。</p>
<p>The following code demonstrates creation and setup of a form.</p>
<p>窗体建立和设置的示例代码：</p>
<pre class="brush:java;highlight:[];">// 1. Create a Form
Form mainForm = new Form("Form Title");
// 2. Set LayoutManager
mainForm.setLayout(new BorderLayout());
// 3. Add a Label to the center of Form content pane
mainForm.addComponent(BorderLayout.CENTER, new Label(“Hello World”));
// 4. Set Transitions animation of Fade
mainForm.setTransitionOutAnimator(CommonTransitions.createFade(400));
// 5. Add Command key
mainForm.addCommand(new Command("Run", 2));
// 6. Show it
mainForm.show();</pre>
<div id="_mcePaste">The following notes correspond to the comments in EXAMPLE 2-1.</div>
<div id="_mcePaste">
<ul>
<li>The first line of code creates a form using a constructor that lets you set the form title. The other frequently used form constructor is the no-argument constructor.</li>
<li>Next the code specifies the layout manager of the form. Layout managers are discussed later in this guide.</li>
<li>The next bit of code adds a label to the form content pane. Adding components to a Form (which is a Container) is done with addComponent(Component cmp) or addComponent(Object constraints, Component cmp), where constraints are the locations in the layout manager, BorderLayout.</li>
<li>A Transition is the movement effect action that occurs when switching between forms. See the Transitions and Animation chapter.</li>
<li>Form has menus to emulate the device soft keys, for example. To set such a menu bar item, command, use the addCommand(Command cmd) method. The Commands are placed in the order they are added. If the Form has one Command it is placed on the right. If the Form has two Commands the first one added is placed on the left and the second one is placed on the right. If the Form has more than two Commands the first one stays on the left and a Menu is added with all the remaining Commands.</li>
<li>The show method displays the current form on the screen.</li>
</ul>
</div>
<h3 id="toc-2-4--form-label">2.4 建立和设置一个 Form Label</h3>
<p>The Label widget can display a single line of text and/or an image and align them using multiple options. If you need to create a component that displays a string, an image, or both, you should use or extend Label. If the component is interactive and has a specific state, a Button is the most suitable widget (instead of a label).</p>
<p>如果你需要建立一个组件显示字符串，图像或同时显示二者，你应该使用或扩展 Label。如果这是一个交互式的组件并有某个特定的状态，Button 是最合适的器件。</p>
<p>To create a Label, use one of the following calls:</p>
<p>使用下列代码之一建立一个 Label：</p>
<pre class="brush:java;highlight:[];">Label textLabel = new Label("I am a Label"); // for a text label</pre>
<p>或</p>
<pre class="brush:java;highlight:[];">// create an image for an icon label
Image icon = Image.createImage("/images/duke.png");
Label imageLabel = new Label(icon);</pre>
<p>Labels can be aligned to one of the following directions: CENTER, LEFT, RIGHT. LEFT is the default. In addition the text can be aligned relative to the image position. Valid values are TOP, BOTTOM, LEFT, RIGHT, where the default is RIGHT. To update the text position use:</p>
<p>Label 可以按照下列方式对齐：CENTER, LEFT, RIGHT。默认值是 LEFT。另外，文本能够相对于图像对齐，可用的选项有 TOP, BOTTOM, LEFT, RIGHT，默认值是 RIGHT。为了更新文本的位置，可以使用：</p>
<pre class="brush:java;highlight:[];">setTextPosition(int alignment);</pre>
<p>&#8230; &#8230;</p>
<h3 id="toc-2-5-">2.5 按钮</h3>
<p>The Button component enables the GUI developer to receive action events when the user focuses on the component and clicks. In some devices a button might be more practical and usable than a command option. Button is the base class for several UI widgets that accept click actions. It has three states: rollover, pressed, and the default state. It can also have ActionListeners that react when the Button is clicked.</p>
<p>在某些设备上 Button 可能比命令选项更实用和有用。Button 是数个接受点击动作的 UI 器件的基类。它有三种状态：翻转（rollover），按下，以及默认状态。它可以和多个 ActionListener 连接以对按钮点击事件做出响应。</p>
<p>To get the user clicking event, you must implement an ActionListener, which is notified each time the user clicks the button. The following code snippet creates an action listener and changes the text on the button, every time the user clicks it.</p>
<p>为了获取用户点击事件，你必须实现一个 ActionListener，它在用户点击按钮时得到通知。下面的代码建立了一个动作监听器，当用户点击按钮时改变按钮上的文本：</p>
<pre class="brush:java;highlight:[];">final Button button  = new Button("Old Text");
button.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent evt) {
		button.setText("New Text");
	}
});</pre>
<p>Button extends Label, so you can create three type of buttons: text only, image only or image and text button.</p>
<p>Button 扩展了 Label，因此你可以建立三种样式的按钮：仅文本，仅图像，以及图像和文本按钮。</p>
<h3 id="toc-2-6-">2.6 单选按钮</h3>
<p>RadioButton is a Button that maintains a selection state exclusively within a specific ButtonGroup. Because RadioButton inherits from Button, radio buttons have all the usual button characteristics, as discussed in Button. For example, you can specify the image displayed in a radio button. Each time the user clicks a radio button (even if it was already selected), the button fires an action event, just as in Button.</p>
<p>RadioButton 是维护特定 ButtonGroup 的一个唯一选择状态的 Button。因为 RadioButton 从 Button 派生，单选按钮拥有上面讨论的按钮的全部有用特征。例如，你可以指定一个单选按钮显示的图像。每次当用户点击一个单选按钮时（甚至当它已经被选择时），这个按钮象普通的按钮一样发送一个动作消息（Action Event）。</p>
<p>To create a RadioButton use:</p>
<p>使用下面的代码建立一个 RadioButton：</p>
<pre class="brush:java;highlight:[];">RadioButton radioButton = new RadioButton(“Radio Button”);</pre>
<h3 id="toc-2-7-">2.7 按钮组</h3>
<p>The ButtonGroup component manages the selected and unselected states for a set of RadioButtons. For the group, the ButtonGroup instance guarantees that only one button can be selected at a time.</p>
<p>ButtonGroup 组件管理一组单选按钮的选定和未选状态。对于这个组，ButtonGroup 示例保证在任何时间只能有一个按钮被选择。</p>
<p>Initially, all RadioButtons in a ButtonGroup are unselected. Each ButtonGroup maintains the selected index, and can get a specific RadioButton by calling getRadioButton(int index).</p>
<p>开始的时候 ButtonGroup 里的所有 RadioButton 都处于未选状态。每个 ButtonGroup 都维护着一个选择索引，可以调用 getRadioButton(int index) 来获取某个指定的 RadioButton。</p>
<p>The following code snippet creates a button group made of two RadioButtons.</p>
<p>使用下面的代码建立一个包含两个 RadioButton 的按钮组：</p>
<pre class="brush:java;highlight:[];">Label radioButtonsLabel = new Label("RadioButton:");
....
RadioButton rb1 = new RadioButton("First RadioButton in Group 1");
RadioButton rb2 = new RadioButton("Second RadioButton in Group 1");

ButtonGroup group1 = new ButtonGroup();
group1.add(rb1);
group1.add(rb2);

exampleContainer.addComponent(radioButtonsLabel);
exampleContainer.addComponent(rb1);
exampleContainer.addComponent(rb2);</pre>
<h3 id="toc-2-8-">2.8 复选框</h3>
<p>Check boxes are similar to RadioButtons but their selection model is different, because they can flip the selection state between selected and unselected modes. A group of radio buttons, on the other hand, can have only one button selected. Because CheckBox inherits from Button, check boxes have all the usual button characteristics, as discussed in Button. For example, you can specify the image displayed in a check box. Each time the user select a check box (even if it was already selected), it fires an action event, just as in Button.</p>
<p>复选框与 RadioButton 相似，但它们的选择模型不同。复选框的选择状态可以在选定和未选之间转换。另外，一组单选按钮只能有一个被选定。因为 CheckBox 从 Button 派生，单选框拥有上面讨论过的按钮所有的有用特征。</p>
<p>To create a CheckBox use:</p>
<p>使用下面的代码建立一个 CheckBox：</p>
<pre class="brush:java;highlight:[];">final CheckBox checkBox = new CheckBox(“Check Box”);</pre>
<p><div class="note"><div class="noteclassic">注意 final 关键字的使用！</div></div></p>
<p>This code produces the CheckBox shown in FIGURE 2-7.</p>
<p>To catch select and unselect events you can try this:</p>
<p>为了捕捉选定和未选状态，可以使用下面的代码：</p>
<pre class="brush:java;highlight:[];">checkBox.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent evt) {
      if(checkBox.isSelected()) {
         System.out.println("CheckBox got selected");
      } else {
         System.out.println("CheckBox got unselected");
      }
   }
});</pre>
<p>xxx</p>
<p>2.9 组合按钮 ComboBox</p>
<p>A combo box is a list that allows only one selection at a time. When a user clicks the combo box button, a drop‐down list of elements allows the user to select a single element. The combo box is driven by the list model and allows all the renderer features of the List as well.</p>
<p>组合框由一个列表模型驱动，可以使用 List 渲染器（Renderer）的所有功能。</p>
<p>Other components that can display one-of-many choices are groups of radio buttons, check boxes, buttons, and lists. Groups of radio buttons are generally the easiest for users to understand, but combo boxes can be more appropriate when space is limited or more than a few choices are available. Lists are not always attractive, but they are more appropriate than combo boxes when the number of items is large (say, over five).</p>
<p>可以显示“多个中选择一个”（One-of-many Choices）的组件还有单选按钮组，复选框组，按钮组，以及列表。单选按钮组通常最容易被用户理解，但当空间有限或少数几个选择项的时候组合框更为适用。列表不是很美观，但它在可选项很多时（例如大于五个）比组合框更合用。</p>
<p>The following code creates a combo box (a list model that is built from check boxes) and sets it up:</p>
<p>下面的代码建立了一个组合框（使用由复选框组成的列表）并对它进行设置：</p>
<pre class="brush:java;highlight:[];">String[] content = { "Red", "Blue", "Green", "Yellow" };

// 1. Creating the combo box
ComboBox comboBox = new ComboBox(content);

// 2. Setting a checkBox renderer
comboBox.setListCellRenderer(new checkBoxRenderer());

// 3. Adding a action listener to catch user clicking
//    to open the ComboBox
comboBox.addActionListener(myActionListener......);</pre>
<p>The following notes correspond to the comments in the code above.</p>
<ul>
<li>This combo box code contains an array of strings, but you could just as easily use labels instead.</li>
<li>To put anything else into a combo box or to customize how the items in a combo box look, you need to write a custom renderer.</li>
<li>The next line of code (which calls setListCellRender) registers an action listener on the combo box.</li>
</ul>
<p>下面是对上面代码的一些注释：</p>
<div>
<ul>
<li>这个组合框包括了一个字符串数组，但你可以简单地使用标签来代替。</li>
<li>如果你想在组合框里放入其他东西以定制组合框的外观，需要编写一个自定义的渲染器（Renderer）。</li>
<li>最后一行代码在组合框上注册了一个动作监听器。</li>
</ul>
</div>
<p>The following is a sample of renderer code:</p>
<p>下面的代码是渲染器的一个例子：</p>
<pre class="brush:java;highlight:[];">/**
* Demonstrates implementation of a renderer derived from a CheckBox
*/
private static class checkBoxRenderer extends CheckBox implements ListCellRenderer {

	/** Creates a new instance of checkBoxRenderer */
	public checkBoxRenderer() {
		super("");
	}

	// Setting the current check box text and status
	public Component getListCellRendererComponent(List list,
	Object value, int index, boolean isSelected) {
		setText("" + value);
		if (isSelected) {
			setFocus(true);
			setSelected(true);
		} else {
			setFocus(false);
			setSelected(false);
		}
		return this;
	}

	// Returning the list focus component
	public Component getListFocusComponent(List list) {
		setText("");
		setFocus(true);
		setSelected(true);
		return this;
	}
}</pre>
<p>The sample code produces the combo box in FIGURE 2-8.</p>
<p>示例代码建立的组合框见下图：<br />
<a href="http://www.iclipp.com/blog/modo/wp-content/uploads/2010/07/lwuit_combobox.jpg"><img class="aligncenter size-full wp-image-3362" title="lwuit_combobox" src="http://www.iclipp.com/blog/modo/wp-content/uploads/2010/07/lwuit_combobox.jpg" alt="" width="240" height="308" /></a></p>
<h3 id="toc-2-10--tabbedpane">2.10 标签面板 TabbedPane</h3>
<p>A tabbed Pane is a container that lets the user switch between a group of components that all share the same space by focusing on a tab with a title, an icon, or both. The user chooses which component to view by selecting the tab corresponding to the desired component.</p>
<p>标签面板是一个容器，允许用户在一组组件之间切换，这些组件通过选择一个带有标题或图标（或二者兼而有之）的标签共享同一个显示空间。用户选择对应的标签来决定显示哪一个组件。</p>
<p>To create a tabbed pane, instantiate TabbedPane, create the components you wish it to display, and then add the components to the tabbed pane using the addTab or insertTab methods. TabbedPane has the ability to remove tabs as well, by calling removeTabAt(int index) at a given position index. A tab is represented by an index corresponding to the position it was added in, where the first tab has an index equal to 0 and the last tab has an index equal to the tab count minus 1.</p>
<p>建立组件后，使用 addTab 或 insertTab 方法把组件加入标签。使用 removeTabAt(int index) 移除指定位置的组件。标签用索引表示，这个索引对应于添加它的位置。第一个标签的索引是0，最后一个标签的索引等于标签总数减去1。</p>
<p>If the tab count is greater than 0, then there is always a selected index, which by default is initialized to the first tab. If the tab count is 0, then the selected index is -1.</p>
<p>标签总数大于0时就存在一个选择索引，默认值是第一个标签。如果标签总数是0，那么选择索引就是-1。</p>
<p>TabbedPane has four different tab placement orientations. The default tab placement is set to the TOP location. You can change the tab placement to LEFT, RIGHT, TOP or BOTTOM using the setTabPlacement method.</p>
<p>TabbedPane 可以按照四种不同的方向定位。标签的默认位置是 TOP。可以使用 setTabPlacement 方法使用方向 LEFT, RIGHT, TOP 或 BOTTOM 来改变标签的定位。</p>
<p>The following code creates a TabbedPane with tab placement of <strong><del datetime="2010-07-16T08:26:56+00:00">bottom</del></strong>, and places a Label in the center of the first (and only) tab.</p>
<p>下面的代码建立了一个 TabbedPane，标签的位置在顶部，并在第一个标签（只有一个）的中央位置放置了一个 Label：</p>
<p><a href="http://www.iclipp.com/blog/modo/wp-content/uploads/2010/07/lwuit_tabbedPane.jpg"><img class="aligncenter size-full wp-image-3363" title="lwuit_tabbedPane" src="http://www.iclipp.com/blog/modo/wp-content/uploads/2010/07/lwuit_tabbedPane.jpg" alt="" width="240" height="307" /></a></p>
<h3 id="toc-2-11--textarea">2.11 文本区 TextArea</h3>
<p>The text area represents text that might be editable using the system native editor (it might occur in a new screen). The native editor is used to enable complex input methods (such as T9) and application internationalization. The following code creates and initializes the text area:</p>
<p>文本区表示可以编辑的文本，它使用系统原生编辑器（可能会打开一个新屏幕）。在原生编辑器里可以使用复杂的舒服发（例如 T9）和应用程序国际化。下面的代码建立和初始化了一个文本区：</p>
<pre class="brush:java;highlight:[];">TextArea textArea = new TextArea(5, 20, TextArea.NUMERIC);
textArea.setEditable(false);</pre>
<p>The first two arguments to the TextArea constructor are hints as to the number of rows and columns, respectively, that the text area should display. The third one is a constraint that is passed into the native text editor. Valid values can be one of ANY, EMAILADDR, NUMERIC, PHONENUMBER, URL, or DECIMAL. In addition it can be bitwise OR&#8217;d with one of PASSWORD, UNEDITABLE, SENSITIVE, NON_PREDICTIVE, INITIAL_CAPS_SENTENCE, INITIAL_CAPS_WORD. For example, ANY | PASSWORD. The default value is ANY. In the above example NUMERIC only allows the user to type numbers.</p>
<p>TextArea 构造函数的第三个参数是传递给原生文本编辑器的一个约束，有效值是：ANY, EMAILADDR, NUMERIC, PHONENUMBER, URL, 或 DECIMAL。这些值还可以和 PASSWORD, UNEDITABLE, SENSITIVE, NON_PREDICTIVE, INITIAL_CAPS_SENTENCE, INITIAL_CAPS_WORD 中的一个做<strong>或</strong>运算。例如 ANY | PASSWORD。默认值是 ANY。</p>
<p>Text areas are editable by default. The code setEditable(false) makes the text area uneditable. It is still selectable, but the user cannot change the text area&#8217;s contents directly.</p>
<p>文本区默认是可编辑的。代码 setEditable(false) 使得文本区不可编辑。在其内仍然能够选择文本，但用户不能直接改变文本区的内容。</p>
<h3 id="toc-2-12--textfield">2.12 文本域 TextField</h3>
<p>TextArea doesn&#8217;t always allow in-place editing on existing devices and doesn&#8217;t provide &#8220;fine grained control&#8221; over the input. This allows a text area to be lightweight, and portable for all possible devices. These restrictions sometimes cause a poor user experience because it requires users to go into a different screen for input (since all input is handled natively by the device). From a developer standpoint the native input can be a problem since it doesn&#8217;t send change events and doesn&#8217;t provide control over allowed input.</p>
<p>文本区并不总是支持现存设备上的原地（In-place）编辑，因此不支持输入时的“细粒度控制”（Fine Grained Control）。这种做法使得文本区对于所有可能的设备更轻量级和可移植。但这些限制有时候会带来糟糕的用户体验，因为它需要用户在输入时使用另一个不同的屏幕（因为所有的输入都由设备本身处理）。从开发者的角度来看，原生输入可能是个问题，因为它不发送改变（Change）事件，也不提供允许输入内容方面的控制。</p>
<p>LWUIT provides the TextField component to support direct mobile phone input from within LWUIT. Unlike a TextArea, TextField is completely implemented in LWUIT. Developers can override almost all of its features to provide deep customization (for example, masked input, localization, and more).</p>
<p>LWUIT 提供了 TextField 组件来支持 LWUIT 内直接移动电话输入</p>
<p>TextField inherits the TextArea component and all of its features. It also supports moving to the native text editor.</p>
<p>TextField 继承了 TextArea 组件和它的所有功能。它还支持转移到原生文本编辑器。</p>
<p>The constructor also accepts several arguments, similar to the TextArea component.</p>
<p>它的构造器也接受几个参数，与 TextArea 组件相似。</p>
<p>TextField also has some limitations:</p>
<p>TextField 还有一些限制：</p>
<p>Does not support input in foreign locales unless you provide code for foreign input</p>
<p>Does not support device features, such as T9 input</p>
<p>Might not correctly detect QWERTY devices</p>
<p>Does not work on devices with unique keyboards, such as the Perl</p>
<p>Creating a text field is trivial:</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iclipp.com/blog/modo/?feed=rss2&amp;p=3317</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《LWUIT 开发者指南》第一章：LWUIT 简介</title>
		<link>http://www.iclipp.com/blog/modo/?p=3308</link>
		<comments>http://www.iclipp.com/blog/modo/?p=3308#comments</comments>
		<pubDate>Mon, 05 Jul 2010 01:07:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[j2me]]></category>
		<category><![CDATA[notes]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[lwuit]]></category>

		<guid isPermaLink="false">http://www.iclipp.com/blog/modo/?p=3308</guid>
		<description><![CDATA[

1.1 API 概览

1.1.1 应用域和可移植性

1.1.1.1 MIDP 的 Hello World 例子


1.1.2 事件和线程





《LWUIT 开发者指南 LWUIT Developer Guide》
This book describes how to use the Lightweight UI Toolkit (LWUIT) library. The Lightweight UI Toolkit library helps you create appealing graphical user interface (GUI) applications for mobile phones and other devices that support MIDP 2.0. Lightweight UI Toolkit supports visual components [...]]]></description>
			<content:encoded><![CDATA[<div class="toc">
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3308#toc-1-1-api-">1.1 API 概览</a></p>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3308#toc-1-1-1-">1.1.1 应用域和可移植性</a></p>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3308#toc-1-1-1-1-midp--hello-world-">1.1.1.1 MIDP 的 Hello World 例子</a></li>
</ol>
</li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3308#toc-1-1-2-">1.1.2 事件和线程</a></li>
</ol>
</li>
</ol>
</div>
<p><span id="more-3308"></span></p>
<p><a href="http://www.iclipp.com/blog/modo/?page_id=3302">《LWUIT 开发者指南 LWUIT Developer Guide》</a></p>
<p>This book describes how to use the Lightweight UI Toolkit (LWUIT) library. The Lightweight UI Toolkit library helps you create appealing graphical user interface (GUI) applications for mobile phones and other devices that support MIDP 2.0. Lightweight UI Toolkit supports visual components and other user interface (UI) ingredients such as theming, transitions, animation and more.</p>
<p>使用 LWUIT 可以在支持 MIDP 2.0 的设备或手机上建立具有漂亮外观的应用程序。</p>
<p>LWUIT 支持可视化组件和其他 UI 特性，如主题（Theming），转换（Transition），动画等。</p>
<p>After covering the basics of the Lightweight UI Toolkit, this book provides a walk through of the various widgets and uses of the LWUIT packages.</p>
<h3 id="toc-1-1-api-">1.1 API 概览</h3>
<p><del datetime="2010-07-06T09:52:12+00:00">The Lightweight UI Toolkit is a lightweight widget library inspired by Swing but designed for constrained devices such as mobile phones and set-top boxes. Lightweight UI Toolkit supports pluggable theme-ability, a component and container hierarchy, and abstraction of the underlying GUI toolkit. The term lightweight indicates that the widgets in the library draw their state in Java source without native peer rendering.</del></p>
<p>LWUIT 收到 Swing 的启发，用于资源受限的设备（例如移动电话和机顶盒等）。LWUIT 支持可插拔的主题，组件及容器层次结构，以及底层 GUI 工具库的抽象。在这里，轻量级的意思是库中的小器件在自己的 Java 代码里绘制自己的状态，而不是通过本地对应 GUI 元素来绘制。</p>
<p>Internal interfaces and abstract classes provide abstraction of interfaces and APIs in the underlying profile. This allows portability and a migration path for both current and future devices and profiles. For example, Graphics would be an abstraction of the graphics object in the underlying profile.</p>
<p>The Lightweight UI Toolkit library tries to avoid the &#8220;lowest common denominator&#8221; mentality by implementing some features missing in the low‐end platforms and taking better advantage of high-end platforms. <a href="file:///D:/temp/LWUIT_1_3/docs/LWUIT_Developer_Guide_HTML/chapter1.html#CEFCFICG">FIGURE 1-1</a> shows the widget class hierarchy.</p>
<h4 id="toc-1-1-1-">1.1.1 应用域和可移植性</h4>
<p>The Lightweight UI Toolkit library is strictly a widget UI library and does not try to abstract the underlying system services such as networking or storage. It also doesn&#8217;t try to solve other UI issues related to native graphics, etcetera.</p>
<p>To enable <a name="d0e690"></a>portability, the Lightweight UI Toolkit library implements its own thin layer on top of the native system canvas and provides a widget abstraction. This abstraction is achieved using several key classes that hide the system specific equivalents to said classes, such as Graphics, Image and Font.</p>
<p><del datetime="2010-07-06T09:52:12+00:00">When working with the Lightweight UI Toolkit library it is critical to use the abstract classes for everything. To avoid corruption, there is no way to access the &#8220;real&#8221; underlying instances of these classes (for example,<kbd>javax.microedition.lwuit.Graphics</kbd>).</del></p>
<p>使用 LWUIT 时，在任何情况下都使用抽象类（LWUIT 定义的类）非常重要。为了防止破坏抽象层次，<strong><span style="color: #ff0000;">绝对</span></strong>不要使用底层类，例如 javax.microedition.lwuit.Graphics。</p>
<p>LWUIT strives to enable great functionality on small devices that might be incapable of anti-aliasing at runtime, or might choke under the weight of many images. To solve these problems the LWUIT library ships with an optional resource file format that improves resource utilization. For more details, see <a href="file:///D:/temp/LWUIT_1_3/docs/LWUIT_Developer_Guide_HTML/chapter11.html#CJBCGCDD">Chapter 11</a>.</p>
<h5 id="toc-1-1-1-1-midp--hello-world-">1.1.1.1 MIDP 的 Hello World 例子</h5>
<p>这里是建立在 MIDP 上的一个简单的 Hello World 例子。这里使用 LWUIT 的界面代码与其他平台（例如 CDC）兼容。</p>
<p><div class="note"><div class="notetip">到这本书完成时，LWUIT 的 CDC 版本尚未正式发布。</div></div></p>
<p>但这个例子特定于 MIDP。对于 MIDP，应用程序管理系统（AMS）要求存在一个 MIDlet 类，而在 CDC 环境里则期望一个 Xlet 类（在 Java SE 环境里需要的则是一个主类 main，等等）。</p>
<pre class="brush:java;highlight:[];">import com.sun.lwuit.Display;
import com.sun.lwuit.Form;
import com.sun.lwuit.Label;
import com.sun.lwuit.layouts.BorderLayout;
import com.sun.lwuit.plaf.UIManager;
import com.sun.lwuit.util.Resources;

public class HelloMidlet extends javax.microedition.midlet.MIDlet {

   public void startApp() {
       //init the LWUIT Display
       Display.init(this);

       // Setting the application theme is discussed
       // later in the theme chapter and the resources chapter
       try {
             Resources r = Resources.open("/myresources.res");
            UIManager.getInstance().setThemeProps(r.getTheme(
               r.getThemeResourceNames()[0])
                );
       } catch (java.io.IOException e) {
       }
       Form f = new Form();
       f.setTitle("Hello World");
       f.setLayout(new BorderLayout());
       f.addComponent("Center", new Label("I am a Label"));
       f.show();
   }

   public void pauseApp() {
   }

   public void destroyApp(boolean unconditional) {
   }
}</pre>
<p>注意，如同这个例子所示，任何使用 LWUIT 的应用程序的第一行代码必须在 display 里注册主类。这个行为是工具包特定的。在 MIDP 里，如果没有到父 MIDlet 的引用，你将做不了什么事情，因此这个操作必须在应用程序的开始完成。</p>
<p>为了简化起见，在 MIDlet 里建立了 UI 代码，但它们可以被分离到其他类里完成，以便移植到未来任何移植了 LWUIT 的平台上。</p>
<h4 id="toc-1-1-2-">1.1.2 事件和线程</h4>
<p>为了达到更高的兼容性，LWUIT 库完整地处理和封装了 UI 线程。它有一个独立的主线程 EDT（受到了 Swing 和 AWT 事件分发线程 Event Dispatch Thread 的启发）。这个线程被用来分发所有的事件和绘制调用。这保证了事件和绘制调用顺序进行，因此不会产生线程问题。通过使用它，那些线程模型可能有些微不一致性的 profile 也能被移植。有关与 EDT 继承和在其上顺序执行调用的详细内容请参见 Display 类（API 文档里的 com.sun.lwuit.Display）。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iclipp.com/blog/modo/?feed=rss2&amp;p=3308</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用 Eclipse for JavaEE 测试 Web Services</title>
		<link>http://www.iclipp.com/blog/modo/?p=3293</link>
		<comments>http://www.iclipp.com/blog/modo/?p=3293#comments</comments>
		<pubDate>Wed, 30 Jun 2010 11:45:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[axis]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[wtp]]></category>

		<guid isPermaLink="false">http://www.iclipp.com/blog/modo/?p=3293</guid>
		<description><![CDATA[参考

如何根据已有的 WSDL 文件测试 Web Services：Using Web Service Explorer to test a Web service
如何建立 Web Services：Webservices with Axis2 and the Eclipse Web Tool Platform (WTP)

可以在本地测试的 Web Services 只有一个框架，可以通过建立指向实际  Web Services 服务器的节点（Node）来测试远程 Web Services。
]]></description>
			<content:encoded><![CDATA[<p>参考</p>
<ul>
<li>如何根据已有的 WSDL 文件测试 Web Services：<a href="http://www.eclipse.org/webtools/jst/components/ws/1.0/tutorials/WebServiceExplorer/WebServiceExplorer.html">Using Web Service Explorer to test a Web service</a></li>
<li>如何建立 Web Services：<a href="http://www.vogella.de/articles/Webservice/article.html">Webservices with Axis2 and the Eclipse Web Tool Platform (WTP)</a></li>
</ul>
<p>可以在本地测试的 Web Services 只有一个框架，可以通过建立指向实际  Web Services 服务器的节点（Node）来测试远程 Web Services。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iclipp.com/blog/modo/?feed=rss2&amp;p=3293</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>搭建 J2ME 开发环境：Eclipse+WTJ+J2MESDK</title>
		<link>http://www.iclipp.com/blog/modo/?p=3258</link>
		<comments>http://www.iclipp.com/blog/modo/?p=3258#comments</comments>
		<pubDate>Mon, 21 Jun 2010 06:52:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[j2me]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[eclipseme]]></category>
		<category><![CDATA[j2mesdk]]></category>
		<category><![CDATA[wtj]]></category>

		<guid isPermaLink="false">http://www.iclipp.com/blog/modo/?p=3258</guid>
		<description><![CDATA[


安装及配置

下载安装 JDK
下载安装 Eclipse
下载安装 J2ME SDK
安装及配置 WTJ

安装
配置预处理器支持
配置 WTJ




开发应用程序

WTJ
J2ME GUI 库

LWUIT
javax.microedition.lcdui




参考


安装及配置
下载安装 JDK
J2ME SDK 需要 JDK，只安装 JRE 将使 J2ME SDK 的安装不能继续。
只有使用1.4以上版本的JDK才可以享受到新增的HotSwap功能对于调试带来的方便。
下载安装 Eclipse
下载安装 Eclipse IDE for Java Developer Galileo（Eclipse 不同发行包的比较）。
另一个（可能是更好的）选择是 Pulsar for Mobile Developers。使用它可以避免在导入 LWUIT 时发生错误。
下载安装 J2ME SDK
下载安装 J2ME SDK 3.0。
安装及配置 WTJ
安装

在 Eclipse 里选择安装软件，使用 Update Site http://download.eclipse.org/dsdp/mtj/updates/1.1.0/stable/ 安装 WTJ 1.1.0。

配置预处理器支持
由于 Eclipse Java 编译器自身扩展性的局限（更多信息参见 Bug 116143），需要在 Eclipse 平台底层挂入 MTJ 以提供预处理器支持。要得到这个支持需要对 Eclipse [...]]]></description>
			<content:encoded><![CDATA[<p><span id="more-3258"></span>
<div class="toc">
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc-">安装及配置</a></p>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc--jdk">下载安装 JDK</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc--eclipse">下载安装 Eclipse</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc--j2me-sdk">下载安装 J2ME SDK</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc--wtj">安装及配置 WTJ</a>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc-1">安装</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc-2">配置预处理器支持</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc--wtj1">配置 WTJ</a></li>
</ol>
</li>
</ol>
</li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc-3">开发应用程序</a>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc-wtj">WTJ</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc-j2me-gui-">J2ME GUI 库</a>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc-lwuit">LWUIT</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc-javax-microedition-lcdui">javax.microedition.lcdui</a></li>
</ol>
</li>
</ol>
</li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3258#toc-4">参考</a></li>
</ol>
</div>
<h3 id="toc-">安装及配置</h3>
<h4 id="toc--jdk">下载安装 JDK</h4>
<p><div class="note"><div class="noteimportant">J2ME SDK 需要 JDK，只安装 JRE 将使 J2ME SDK 的安装不能继续。</div></div></p>
<p><div class="note"><div class="notetip">只有使用1.4以上版本的JDK才可以享受到新增的HotSwap功能对于调试带来的方便。</div></div></p>
<h4 id="toc--eclipse">下载安装 Eclipse</h4>
<p>下载安装 Eclipse IDE for Java Developer Galileo（<a href="http://www.eclipse.org/downloads/packages/compare-packages">Eclipse 不同发行包的比较</a>）。</p>
<p><div class="note"><div class="notetip">另一个（可能是更好的）选择是 <a href="http://www.eclipse.org/downloads/packages/pulsar-mobile-developers/heliosr">Pulsar for Mobile Developers</a>。使用它可以避免在导入 LWUIT 时发生<a href="http://dev.10086.cn/cmdn/bbs/viewthread.php?tid=15985&amp;page=1">错误</a>。</div></div></p>
<h4 id="toc--j2me-sdk">下载安装 J2ME SDK</h4>
<p>下载安装 <a href="http://java.sun.com/javame/downloads/index.jsp">J2ME SDK 3.0</a>。</p>
<h4 id="toc--wtj">安装及配置 WTJ</h4>
<h5 id="toc-1">安装</h5>
<ul>
<li>在 Eclipse 里选择安装软件，使用 Update Site <a href="http://download.eclipse.org/dsdp/mtj/updates/1.1.0/stable/">http://download.eclipse.org/dsdp/mtj/updates/1.1.0/stable/</a> 安装 WTJ 1.1.0。</li>
</ul>
<h5 id="toc-2">配置预处理器支持</h5>
<p>由于 Eclipse Java 编译器自身扩展性的局限（更多信息参见 <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=116143" target="blank">Bug 116143</a>），需要在 Eclipse 平台底层挂入 MTJ 以提供预处理器支持。要得到这个支持需要对 Eclipse 做一些额外的改动：</p>
<ul>
<li>必须将 MTJ 安装到 Eclipse 的基本目录下（例如 C:\software\eclipse）。安装结束后，文件 org.eclipse.mtj.core.hooks_[version].jar 必须与文件 org.eclipse.osgi_[version].jar 位于同一目录。</li>
<li>必须修改 Eclipse 配置文件来引用 MTJ 框架挂钩集合（Bundle）：
<ol>
<li>在 &lt;eclipse install&gt;/configuration 目录下找到文件 config.ini；</li>
<li>使用文本编辑器编辑 config.ini 文件；</li>
<li>在配置文件里添加下面的属性：
<pre class="brush:plain;light:false;">osgi.framework.extensions=org.eclipse.mtj.core.hooks</pre>
<p>如果这个属性已经存在，在它的定义后追加“,org.eclipse.mtj.core.hooks”；<div class="note"><div class="noteimportant">这一行必须添加到文件结束标记（end-of-file Marker）之前。如果不是这样，Eclipse 将不能启动。</div></div></li>
<li>保存这个配置文件；</li>
<li>重新启动 Eclipse。</li>
</ol>
</li>
</ul>
<p>如果你的项目被配置为使用预处理，但还没有按照上述步骤配置 Eclipse，你将会在 Eclipse 工作空间日志文件里看到类似下面的信息：</p>
<pre class="brush:plain;light:false;">Preprocessor invoked, but hook is not installed. Consult the installation instructions for MTJ.</pre>
<h5 id="toc--wtj1">配置 WTJ</h5>
<p>配置 WTJ 和建立简单 MIDlet 的教程参见 <a href="http://www.eclipse.org/dsdp/mtj/development/tutorial/gettingstarted.php">Getting Started with WTJ</a>。</p>
<h3 id="toc-3">开发应用程序</h3>
<h4 id="toc-wtj">WTJ</h4>
<p>参见 <a href="http://help.eclipse.org/galileo/index.jsp?nav=/18">WTJ 用户文档</a>。</p>
<h4 id="toc-j2me-gui-">J2ME GUI 库</h4>
<h5 id="toc-lwuit">LWUIT</h5>
<ul>
<li><a href="https://lwuit.dev.java.net/">LWUIT 项目主页</a></li>
<li><a href="http://tech.ddvip.com/2009-09/1252724975132350.html">J2ME GUI实战之一 &#8211; LWUIT简介</a></li>
<li><a href="http://forums.java.net/jive/thread.jspa?threadID=55711">How to build LWUIT with Eclipse</a></li>
</ul>
<h5 id="toc-javax-microedition-lcdui">javax.microedition.lcdui</h5>
<ul>
<li><a href="http://java.sun.com/javame/reference/apis/jsr118/javax/microedition/lcdui/package-summary.html">Documentation for package javax.microedition.lcdui</a></li>
</ul>
<h3 id="toc-4">参考</h3>
<ul>
<li><a href="http://eclipseme.org">eclipseME</a>: 已经成为 <a href="http://www.eclipse.org/dsdp/mtj/">Eclipse Mobile Tools for Java (MTJ) </a>项目。</li>
<li>教程：
<ul>
<li><a href="http://www.yesky.com/478/1923478.shtml">Eclipse 开发 J2ME 程序之安装配置</a></li>
<li><a href="http://www.yesky.com/382/1930382.shtml">Eclipse 开发 J2ME 程序之插件安装</a></li>
<li><a href="http://www.yesky.com/380/1933380.shtml">Eclipse 开发 J2ME 程序之 Hello World</a></li>
<li><a href="http://www.yesky.com/381/1933381.shtml">Eclipse 开发 J2ME 程序之仿真机发布</a></li>
<li><a href="http://www.yesky.com/394/1933394.shtml">Eclipse 开发 J2ME 程序之图形化游戏</a></li>
</ul>
</li>
<li><a href="http://www.j2megame.org/index.php/content/view/624/125.html">Eclipse+EclipseME+WTK 搭建 J2ME 开发环境</a>：设置 Antenna JAR 编写打包脚本，使用 <a href="http://proguard.sourceforge.net/">Proguard</a> 加密程序等等。</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.iclipp.com/blog/modo/?feed=rss2&amp;p=3258</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android 操作系统修改版 CyanogenMod 5 发布</title>
		<link>http://www.iclipp.com/blog/modo/?p=3254</link>
		<comments>http://www.iclipp.com/blog/modo/?p=3254#comments</comments>
		<pubDate>Wed, 26 May 2010 14:38:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[mobile device]]></category>

		<guid isPermaLink="false">http://www.iclipp.com/blog/modo/?p=3254</guid>
		<description><![CDATA[(From solidot)
CyanogenMod黑客宣布向HTC Dream和HTC Magic系列手机发布最新版的自制系统CyanogenMod 5.0.7(基于Android 2.1)。
新版增加了大量新特性，修正了大量bug，主要的特性包括：Kernel 2.6.33.4，Pershoot时钟模式，支持手机互联技术（Tethering）等等。开发者承认可能还存在一些小纰漏，但相信能作为日常使用稳定运行。
]]></description>
			<content:encoded><![CDATA[<p>(From solidot)</p>
<p>CyanogenMod黑客<a href="http://lwn.net/Articles/389040/">宣布</a>向HTC Dream和HTC Magic系列手机发布最新版的自制系统<a href="http://forum.cyanogenmod.com/index.php?/topic/3908-cyanogenmod-5-for-dreammagic-mean-lean-pastry-machine-v507-05252010/">CyanogenMod 5.0.7</a>(基于Android 2.1)。</p>
<p>新版增加了大量新特性，修正了大量bug，主要的特性<a href="http://github.com/cyanogen/android_vendor_cyanogen/blob/eclair/CHANGELOG">包括</a>：Kernel 2.6.33.4，Pershoot时钟模式，支持手机互联技术（Tethering）等等。开发者承认可能还存在一些小纰漏，但相信能作为日常使用稳定运行。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iclipp.com/blog/modo/?feed=rss2&amp;p=3254</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VoltDB 发布</title>
		<link>http://www.iclipp.com/blog/modo/?p=3250</link>
		<comments>http://www.iclipp.com/blog/modo/?p=3250#comments</comments>
		<pubDate>Wed, 26 May 2010 14:32:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[database]]></category>

		<guid isPermaLink="false">http://www.iclipp.com/blog/modo/?p=3250</guid>
		<description><![CDATA[(From solidot)
VoltDB 内存驻留（In-Memory）数据库管理系统正式宣布。
VoltDB是Postgres和Ingres联合创始人Mike Stonebraker领导开发的下一代开源数据库管理系统。它能在现有的廉价服务器集群上实现每秒数百万次数据处理。VoltDB大幅降低了服务器资源开销，单节点每秒数据处理远远高于其它数据库管理系统。不同于NoSQL的key-value储存，VoltDB能使用SQL存取，支持传统数据库的ACID模型。VoltDB代码采用GPLv3授权，支持订阅费用从15,000美元起步。
]]></description>
			<content:encoded><![CDATA[<p>(From solidot)</p>
<p><a href="http://voltdb.com/voltdb-launches-next-generation-open-source-oltp-dbms">VoltDB</a> 内存驻留（In-Memory）数据库管理系统<a href="http://lwn.net/Articles/389117/">正式宣布</a>。</p>
<p>VoltDB是Postgres和Ingres联合创始人Mike Stonebraker领导开发的下一代开源数据库管理系统。它能在现有的廉价服务器集群上实现每秒数百万次数据处理。VoltDB大幅降低了服务器资源开销，单节点每秒数据处理远远高于其它数据库管理系统。不同于NoSQL的key-value储存，VoltDB能使用SQL存取，支持传统数据库的ACID模型。VoltDB代码采用GPLv3授权，支持订阅费用从15,000美元起步。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iclipp.com/blog/modo/?feed=rss2&amp;p=3250</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MIT开发出自动执行重复任务的软件</title>
		<link>http://www.iclipp.com/blog/modo/?p=3248</link>
		<comments>http://www.iclipp.com/blog/modo/?p=3248#comments</comments>
		<pubDate>Wed, 26 May 2010 14:31:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[productivity]]></category>

		<guid isPermaLink="false">http://www.iclipp.com/blog/modo/?p=3248</guid>
		<description><![CDATA[(From solidot)
MIT技术评论》报道（中文版），MIT研究人员开发出名为KarDo的软件，能自动配置电子邮件账户，安装杀毒软件，或者设置VPN。
KarDo只需要观察管理员执行一次任务，就可以在运行不同软件的电脑上实施同样的工作。根据Forrester和Gartner的报告，企业每年花费在简单重复的IT任务上的资金达数十亿美元。KarDo能将这笔开销削减20%之多。在某些方面，KarDo与记录宏命令—用户在电脑上的一系列操作—的软件有相似之处。但KarDo会尝试学习每个操作的目的，从而在今后更广泛地使用该操作。当IT员工想要KarDo学习一项新任务时，只需要事先按下“开始”按钮并在结束后按“停止”即可。
]]></description>
			<content:encoded><![CDATA[<p>(From solidot)</p>
<p>MIT技术评论》<a href="http://www.technologyreview.com/computing/25351/?a=f">报道</a>（<a href="http://www.mittrchinese.com/article.jsp?id=899">中文版</a>），MIT研究人员开发出名为<a href="http://kardo.csail.mit.edu/">KarDo</a>的软件，能自动配置电子邮件账户，安装杀毒软件，或者设置VPN。</p>
<p>KarDo只需要观察管理员执行一次任务，就可以在运行不同软件的电脑上实施同样的工作。根据Forrester和Gartner的报告，企业每年花费在简单重复的IT任务上的资金达数十亿美元。KarDo能将这笔开销削减20%之多。在某些方面，KarDo与记录宏命令—用户在电脑上的一系列操作—的软件有相似之处。但KarDo会尝试学习每个操作的目的，从而在今后更广泛地使用该操作。当IT员工想要KarDo学习一项新任务时，只需要事先按下“开始”按钮并在结束后按“停止”即可。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iclipp.com/blog/modo/?feed=rss2&amp;p=3248</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Paparazzi: Open Source 自动飞行系统</title>
		<link>http://www.iclipp.com/blog/modo/?p=3246</link>
		<comments>http://www.iclipp.com/blog/modo/?p=3246#comments</comments>
		<pubDate>Wed, 26 May 2010 07:25:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[autopilot]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://www.iclipp.com/blog/modo/?p=3246</guid>
		<description><![CDATA[
Paparazzi is  a free and open-source hardware and software project intended to create  an exceptionally powerful and versatile autopilot system by allowing  and encouraging input from the community. The project includes not only  the airborne hardware and software, from voltage regulators and GPS  receivers to Kalman  filtering code, but [...]]]></description>
			<content:encoded><![CDATA[<tr>
<td><a title="http://www.nongnu.org/paparazzi/" rel="nofollow" href="http://www.nongnu.org/paparazzi/">Paparazzi</a> is  a free and open-source hardware and software project intended to create  an exceptionally powerful and versatile autopilot system by allowing  and encouraging input from the community. The project includes not only  the airborne hardware and software, from voltage regulators and GPS  receivers to <a title="http://en.wikipedia.org/wiki/Kalman_filtering" rel="nofollow" href="http://en.wikipedia.org/wiki/Kalman_filtering">Kalman  filtering</a> code, but also a powerful and ever-expanding array of  ground hardware and software including modems, antennas, and a highly  evolved user-friendly ground control software interface.</td>
</tr>
<tr>
<td>All hardware and software is open-source and freely available to  anyone under the <a title="http://www.gnu.org" rel="nofollow" href="http://www.gnu.org/">GNU</a> licencing agreement. <a title="Get Hardware" href="http://paparazzi.enac.fr/wiki/Get_Hardware"> Several vendors</a> are currently producing and selling Paparazzi  autopilots and popular accessories, making the system easy and  affordable to all.</td>
</tr>
<tr>
<td>The key feature of the paparazzi autopilot is its unique combination  of infrared thermopiles and inertial measurement for attitude sensing,  providing a robust and accurate attitude estimate that requires no  ground calibration and can recover from any launch attitude.</td>
</tr>
]]></content:encoded>
			<wfw:commentRss>http://www.iclipp.com/blog/modo/?feed=rss2&amp;p=3246</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《从汇编语言到Windows内核编程》第一章：汇编指令与C语言</title>
		<link>http://www.iclipp.com/blog/modo/?p=3220</link>
		<comments>http://www.iclipp.com/blog/modo/?p=3220#comments</comments>
		<pubDate>Thu, 06 May 2010 06:39:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[notes]]></category>
		<category><![CDATA[windows xp]]></category>
		<category><![CDATA[asm]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[disassembling]]></category>

		<guid isPermaLink="false">http://www.iclipp.com/blog/modo/?p=3220</guid>
		<description><![CDATA[

1.1 上机建立第一个工程

1.1.1 用 Visual Studio 创建工程
1.1.2 用 Visual Studio 查看汇编指令


1.2 简要复习常用的汇编指令

1.2.1 堆栈相关指令
1.2.2 数据传送指令
1.2.3 跳转与比较指令


1.3 C 函数的参数传递过程

基础知识
技术细节
代码分析





1.1 上机建立第一个工程
1.1.1 用 Visual Studio 创建工程
『略』
1.1.2 用 Visual Studio 查看汇编指令
C 语言程序对应的汇编代码，可以在 VC 中非常清楚地显示出对应关系。只需要调出汇编指令窗口，步骤：

VC 必须处于调试状态才能看到汇编指令窗口，因此可以在程序的最后一行代码上设置断点（F9）；
按下 F5 调试程序。当程序停在断点位置时，打开菜单 [Debug]&#62;[Windows]&#62;[Disassembly]。

1.2 简要复习常用的汇编指令
1.2.1 堆栈相关指令

push：把一个 32 位操作数压入堆栈。注意：栈顶 esp 在压入数据后向低地址空间增长，每次减少 4（字节）。
pop：esp 加 4。参数一般是一个寄存器。
sub 和 add 常用来操作堆栈：便于在堆栈上一次性分配或回收空间。
ret：等于 pop+jump。
call：等于 push+jump。

1.2.2 数据传送指令

mov：第一个参数是目的，第二个参数是来源。在 C 语言中相当于赋值操作符。
xor：常用来对寄存器清零，这样比使用 mov 更快且占用内存更少，例如：
xor eax, eax
代替：
mov eax, 0
进行清零操作。
lea：取得地址（第二个参数的地址）后放入寄存器（第一个参数）。实际上，有时使用它来做 [...]]]></description>
			<content:encoded><![CDATA[<div class="toc">
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-1-1-">1.1 上机建立第一个工程</a></p>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-1-1-1--visual-studio-">1.1.1 用 Visual Studio 创建工程</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-1-1-2--visual-studio-">1.1.2 用 Visual Studio 查看汇编指令</a></li>
</ol>
</li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-1-2-">1.2 简要复习常用的汇编指令</a>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-1-2-1-">1.2.1 堆栈相关指令</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-1-2-2-">1.2.2 数据传送指令</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-1-2-3-">1.2.3 跳转与比较指令</a></li>
</ol>
</li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-1-3-c-">1.3 C 函数的参数传递过程</a>
<ol>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-">基础知识</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-1">技术细节</a></li>
<li><a href="http://www.iclipp.com/blog/modo/?p=3220#toc-2">代码分析</a></li>
</ol>
</li>
</ol>
</div>
<p><span id="more-3220"></span></p>
<h3 id="toc-1-1-">1.1 上机建立第一个工程</h3>
<h4 id="toc-1-1-1--visual-studio-">1.1.1 用 Visual Studio 创建工程</h4>
<p>『略』</p>
<h4 id="toc-1-1-2--visual-studio-">1.1.2 用 Visual Studio 查看汇编指令</h4>
<p>C 语言程序对应的汇编代码，可以在 VC 中非常清楚地显示出对应关系。只需要调出汇编指令窗口，步骤：</p>
<ol>
<li>VC 必须处于调试状态才能看到汇编指令窗口，因此可以在程序的最后一行代码上设置断点（F9）；</li>
<li>按下 F5 调试程序。当程序停在断点位置时，打开菜单 [Debug]&gt;[Windows]&gt;[Disassembly]。</li>
</ol>
<h3 id="toc-1-2-">1.2 简要复习常用的汇编指令</h3>
<h4 id="toc-1-2-1-">1.2.1 堆栈相关指令</h4>
<ul>
<li><strong>push</strong>：把一个 <strong>32</strong> 位操作数压入堆栈。注意：栈顶 esp 在压入数据后向<strong><span style="color: #ff6600;">低</span></strong>地址空间增长，每次减少 <strong>4</strong>（字节）。</li>
<li><strong>pop</strong>：esp 加 4。参数一般是一个寄存器。</li>
<li><strong>sub </strong>和 <strong>add</strong> 常用来操作堆栈：便于在堆栈上一次性分配或回收空间。</li>
<li><strong>ret</strong>：等于 pop+jump。</li>
<li><strong>call</strong>：等于 push+jump。</li>
</ul>
<h4 id="toc-1-2-2-">1.2.2 数据传送指令</h4>
<ul>
<li><strong>mov</strong>：第一个参数是目的，第二个参数是来源。在 C 语言中相当于赋值操作符。</li>
<li><strong>xor</strong>：常用来对寄存器清零，这样比使用 mov 更快且占用内存更少，例如：
<pre class="brush:text;highlight:[];">xor eax, eax</pre>
<p>代替：</p>
<pre class="brush:text;highlight:[];">mov eax, 0</pre>
<p>进行清零操作。</li>
<li><strong>lea</strong>：取得地址（第二个参数的地址）后放入寄存器（第一个参数）。实际上，有时使用它来做 mov 的工作，例如赋值，
<pre class="brush:plain;light:false;">lea edi, [ebp-0cch]</pre>
<p><strong><span style="color: #ff6600;"> 方括弧</span></strong>表示存储器，取 <code>ebp-0cch</code> 这个地址所指的存储器的地址，也就是 <code>ebp-0cch</code>。但 mov 指令无法完成这行代码的工作，因为 mov 指令里不支持第二个参数写成寄存器减去数字。</li>
<li><strong>stos</strong> (stosd)：串存储指令，它的功能是把 eax 里的数据放入 edi 所指的地址中，同时 edi 增加 4（字节数）。stos 的三个变形是 stosd（4）， stosb（1），stosw（2）。</li>
<li><strong>rep</strong>：重复指令。使后面的指令重复执行 ecx 中指定的次数。下面的代码
<pre class="brush:plain;light:false;">mov ecx, 30h
mov eax, 0CCCCCCCCh
rep stos dword ptr es:[edi]</pre>
<p>把堆栈中的 30h*4 个字节初始化为 <strong><span style="color: #ff6600;">0cch</span></strong>（<strong><span style="color: #ff6600;">int3</span></strong> 指令的机器码），这样发生意外执行堆栈里的内容时将会引发<strong>调试中断</strong>。</li>
</ul>
<h4 id="toc-1-2-3-">1.2.3 跳转与比较指令</h4>
<ul>
<li><strong>jmp</strong>：无条件跳转。</li>
<li><strong>jg</strong>：大于的时候跳转。</li>
<li><strong>jl</strong>：小于的时候跳转。</li>
<li><strong>jge</strong>：大于等于时跳转。</li>
<li><strong>cmp</strong>：往往时条件跳转指令的执行条件。</li>
</ul>
<h3 id="toc-1-3-c-">1.3 C 函数的参数传递过程</h3>
<h4 id="toc-">基础知识</h4>
<p>函数和堆栈的关系密切：</p>
<ul>
<li>C 语言通常通过堆栈把参数从函数外部传入到函数内部。这些参数对齐到机器字长（16/32/64位 CPU 分别对齐 2/4/8个字节）</li>
<li>在堆栈中划分区域容纳函数的内部变量。</li>
</ul>
<p>调用 push 和 pop 指令时，<strong><span style="color: #ff6600;">esp</span></strong> 用于指向栈顶的位置（栈中地址最小的位置），push 时 esp 减小，pop 时 esp 增加。</p>
<p><div class="note"><div class="notetip">call 和 ret 指令只是为了方便函数调用，而不是函数存在的绝对证据。因为即使只使用 jmp 并自己操作堆栈也能实现函数的功能。</div></div></p>
<p>不同的函数调用机制（Windows 上）</p>
<ul>
<li>C 方式（_cdecl）：
<ul>
<li>参数从右到左进入堆栈；</li>
<li>函数返回后，<strong><span style="color: #993300;">调用者</span></strong>要负责清除堆栈，因此这种方式会生成<strong><span style="color: #993300;">较大</span></strong>的可执行程序。</li>
</ul>
</li>
</ul>
<ul>
<li>WINAPI 方式（_stdcall）：
<ul>
<li>参数从右到左进入堆栈；</li>
<li>被调用的<strong><span style="color: #993300;">函数</span></strong>在返回前自行清除堆栈，所以生成的代码比 _cdecl <strong><span style="color: #993300;">小</span></strong>。</li>
</ul>
</li>
</ul>
<ul>
<li>Pascal 方式：主要用在 Win16 函数库中，现在基本已经不再使用
<ul>
<li>参数<strong>从左到右</strong>进入堆栈；</li>
<li>被调用的函数在返回前自行清除堆栈；</li>
<li>不支持可变参数的函数调用。</li>
</ul>
</li>
<li>Windows 内核中常见的还有<strong>快速调用</strong>方式（_fastcall）『后』；</li>
<li>C++ 编译的代码中有 <strong>this call</strong> 方式（this_call）『后』。</li>
</ul>
<h4 id="toc-1">技术细节</h4>
<p>使用堆栈传递参数。</p>
<p>返回值写入 <strong><span style="color: #ff6600;">eax</span></strong> 中，然后返回。在 Windows 中，不管哪种调用方式都是通过 eax 传递返回值。</p>
<p>_cdecl 调用方式由调用者清理复原堆栈；_stdcall 调用方式由被调用者恢复堆栈（<strong><span style="color: #ff0000;">可变参数</span></strong>函数调用除外）。</p>
<p><strong>_cdecl</strong> 方式下<strong>被调用函数</strong>需要做以下一些事情：</p>
<ol>
<li>保存 <strong><span style="color: #993300;">ebp</span></strong>：因为接下来通常将使用 ebp 保存这个函数执行之前的 esp 的值。执行完毕函数以后，再使用 ebp 恢复 esp。同时，调用这个函数的上层函数也用 ebp 做同样的事情，因此要先把 ebp 压入堆栈，返回之前弹出，以免改动 ebp。</li>
<li>把 <strong><span style="color: #993300;">esp</span></strong> 保存到 ebp 中。上面两步的代码如下：
<pre class="brush:plain;light:false;">; 保存 ebp，并把 esp 放到 ebp 中，此时 ebp 与 esp
; 同样都是这次函数调用时的栈顶
push ebp
mov ebp, esp</pre>
</li>
<li>在堆栈中腾出一个<strong><span style="color: #993300;">区域</span></strong>用来保存局部变量，即常说的“局部变量保存在栈空间中”。方法是，把 esp 减少一个数值，这样就等于压入了一堆变量。要恢复时，只需要把 esp <strong><span style="color: #993300;">恢复</span></strong>成 ebp 中保存的数据即可。</li>
<li>把 <strong><span style="color: #993300;">ebx</span></strong>、<strong><span style="color: #993300;">esi</span></strong> 和 <strong><span style="color: #993300;">edi</span></strong> 保存到堆栈，函数调用完毕后恢复。这两步对应的代码如下：
<pre class="brush:plain;light:false;">; 把 esp 往下移动一个范围，等于在堆栈中放出一片新的
; 空间用来存放局部变量
sub esp, 0cch
; 保存三个寄存器
push ebx
push esi
push edi</pre>
</li>
<li>把局部变量区域初始化为全 0cccccccch（<strong><span style="color: #993300;">0cch</span></strong> 实际上是 int3 指令的机器码）。因为局部变量不可能被执行，如果执行了，必然程序有错，此时发生中断来提示开发者。这是 VC 编译 Debug 版本的特有操作。相关代码如下：
<pre class="brush:plain;light:false;">lea edi, [ebp-0cch]
mov ecx, 33h
mov eax, 0cccccccch
rep stos dword ptr [edi] ;串写入</pre>
</li>
<li>然后做函数应该做的工作。<strong><span style="color: #993300;">参数的获取</span></strong>：ebp+12 字节处为第二个参数，ebp+8 字节处为第一个参数（倒序压入），一次增加，最后 ebp+4 字节处是要返回的地址。</li>
<li>恢复 <strong>ebx</strong>、<strong>esi</strong>、<strong>edi</strong>、<strong>esp</strong>、<strong>ebp</strong>，最后返回，代码如下：
<pre class="brush:plain;light:false;">; 恢复三个寄存器
pop edi
pop esi
pop ebx
; 恢复原来的 ebp 和 esp，让上一个调用的函数正常使用
mov esp, ebp
pop ebp
ret</pre>
</li>
<li>如果需要返回值，函数应该在返回之前，把返回值放入 <strong><span style="color: #993300;">eax</span></strong>。外部通过 eax 获取返回值。</li>
</ol>
<h4 id="toc-2">代码分析</h4>
<p>『略』：函数 myfunction(int, int) 的汇编代码，可以使用 VS 得到。</p>
<p>主函数对函数 myfunction(int, int) 的调用方式是：</p>
<pre class="brush:plain;light:false;">mov eax, dword ptr[b]
mov eax
mov ecx, dword ptr[a]
push ecx
call myfunction
add esp, 8    ;恢复堆栈！</pre>
<p><div class="note"><div class="notetip">重点观察那些设计 call、ret、push 和 pop，操作 ebp 和 esp 的指令，就能看到 C 语言函数的调用过程。</div></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iclipp.com/blog/modo/?feed=rss2&amp;p=3220</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
