﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-FORTUNE</title><link>http://www.blogjava.net/fortune/</link><description>THE WAY TO THE MASTER...</description><language>zh-cn</language><lastBuildDate>Fri, 03 Jul 2026 18:30:49 GMT</lastBuildDate><pubDate>Fri, 03 Jul 2026 18:30:49 GMT</pubDate><ttl>60</ttl><item><title>IBM : developerWorks 中国网站 : xml 中的XML 入门 (修订版)学习及整理(转)</title><link>http://www.blogjava.net/fortune/archive/2006/10/16/75414.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 16 Oct 2006 06:52:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/10/16/75414.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/75414.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/10/16/75414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/75414.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/75414.html</trackback:ping><description><![CDATA[
		<div>XML，或称为可扩展标记语言（Extensible Markup Language），是一种您可以用来创建自己的标记的标记语言。它由万维网协会（W3C）创建，用来克服 HTML（即超文本标记语言（Hypertext Markup Language），它是所有网页的基础）的局限。和 HTML 一样，XML 基于 SGML — 标准通</div>
		<div>用标记语言（Standard Generalized Markup Language）。尽管 SGML 已在出版业使用了数十年，但其理解方面的复杂性使许多本打算使用它的人望而却步（SGML 也代表“听起来很棒，但或许以后会用（Sounds great, maybe later）”）。XML 是为 Web 设计的。</div>
		<div> </div>
		<div>
				<strong>XML文档规则<br /></strong>有三种 XML 文档：<br />无效文档没有遵守 XML 规范定义的语法规则。如果开发人员已经在 DTD 或模式中定义了文档能够包含什么，而某个文档没有遵守那些规则，那</div>
		<div>么这个文档也是无效的。（请参阅定义文档内容以获得对 XML 文档 的 DTD 和模式的专门介绍。） <br />有效文档既遵守 XML 语法规则也遵守在其 DTD 或模式中定义的规则。 <br />格式良好的文档遵守 XML 语法，但没有 DTD 或模式。 </div>
		<div>
				<br />
				<em>
						<strong>根元素</strong>
						<br />
				</em>XML 文档必须包含在一个单一元素中。这个单一元素称为根元素，它包含文档中所有文本和所有其它元素。在下面的示例中，XML 文档包含在一</div>
		<div>个单一元素 &lt;greeting&gt; 中。请注意文档有一行注释在根元素之外；那是完全合乎规则的。</div>
		<div>
				<br />&lt;?xml version="1.0"?&gt;<br />&lt;!-- A well-formed document --&gt;<br />&lt;greeting&gt;<br />  Hello, World!<br />&lt;/greeting&gt;<br />          </div>
		<div>下面是一个不包含单一根元素的文档：</div>
		<div>
				<br />&lt;?xml version="1.0"?&gt;<br />&lt;!-- An invalid document --&gt;<br />&lt;greeting&gt;<br />  Hello, World!<br />&lt;/greeting&gt;<br />&lt;greeting&gt;<br />  Hola, el Mundo!<br />&lt;/greeting&gt;<br />          </div>
		<div>不管该文档可能包含什么信息，XML 解析器都会拒绝它。</div>
		<div>
				<br />
				<em>
						<strong>元素不能重叠</strong>
				</em>
				<br />XML 元素不能重叠。下面是一些不合乎规则的标记：</div>
		<div>
				<br />&lt;!-- NOT legal XML markup --&gt;            <br />&lt;p&gt;<br />  &lt;b&gt;I &lt;i&gt;really <br />  love&lt;/b&gt; XML.<br />  &lt;/i&gt;<br />&lt;/p&gt;<br />          </div>
		<div>如果您在 &lt;b&gt; 元素中开始了 &lt;i&gt; 元素，则必须在 &lt;b&gt; 元素中结束 &lt;i&gt; 元素。如果您希望文本 XML 以斜体出现，那么您需要添加第二个 &lt;i&gt; </div>
		<div>元素以更正标记：</div>
		<div>
				<br />&lt;!-- legal XML markup --&gt;<br />&lt;p&gt;<br />  &lt;b&gt;I &lt;i&gt;really <br />  love&lt;/i&gt;&lt;/b&gt;<br />  &lt;i&gt;XML.&lt;/i&gt;<br />&lt;/p&gt;<br />          </div>
		<div>XML 解析器将只接受这种标记；大多数 Web 浏览器中的 HTML 解析器对于两者都接受。</div>
		<div>
				<br />
				<strong>
						<em>结束标记是必需的</em>
				</strong>
				<br />不能省去任何结束标记。在下面第一个示例中，标记是不合乎规则的，因为没有结束段落（&lt;/p&gt;）标记。尽管这在 HTML（以及某些情况下在 </div>
		<div>SGML）中可以接受，但 XML 解析器将拒绝它。</div>
		<div>
				<br />&lt;!-- NOT legal XML markup --&gt;<br />&lt;p&gt;Yada yada yada...<br />&lt;p&gt;Yada yada yada...<br />&lt;p&gt;...<br />          </div>
		<div>如果一个元素根本不包含标记，则称为空元素；HTML 换行（&lt;br&gt;）和图像（&lt;img&gt;）元素就是两个例子。在 XML 文档的空元素中，您可以把结束</div>
		<div>斜杠放在开始标记中。下面的两个换行元素和两个图像元素对于 XML 解析器来说是一回事：</div>
		<div>
				<br />&lt;!-- Two equivalent break elements --&gt;<br />&lt;br&gt;&lt;/br&gt;<br />&lt;br /&gt;</div>
		<div>&lt;!-- Two equivalent image elements --&gt;<br />&lt;img src="../img/c.gif"&gt;&lt;/img&gt;<br />&lt;img src="../img/c.gif" /&gt;</div>
		<div>元素是区分大小写的<br />XML 元素是区分大小写的。在 HTML 中，&lt;h1&gt; 和 &lt;H1&gt; 是相同的；在 XML 中，它们是不同的。如果您试图用 &lt;/H1&gt; 标记结束 &lt;h1&gt; 元素，将会</div>
		<div>出错。在下面的示例中，顶部的标题是不合乎规则的，而底部的则是正确的。</div>
		<div>
				<br />&lt;!-- NOT legal XML markup --&gt;<br />&lt;h1&gt;Elements are <br />  case sensitive&lt;/H1&gt;</div>
		<div>&lt;!-- legal XML markup --&gt;<br />&lt;h1&gt;Elements are <br />  case sensitive&lt;/h1&gt;</div>
		<div>
				<br />
				<em>
						<strong>属性必须有用引号括起的值</strong>
				</em>
				<br />XML 文档中的属性有两个规则：</div>
		<div>属性必须有值 <br />那些值必须用引号括起。<br /> <br />比较下面的两个示例。顶部的标记在 HTML 中是合乎规则的，但在 XML 中则不是。为了在 XML 中取得相同结果，您必须给属性赋值，而且必须</div>
		<div>把值括在引号中。</div>
		<div>
				<br />&lt;!-- NOT legal XML markup --&gt;<br />&lt;ol compact&gt;</div>
		<div>&lt;!-- legal XML markup --&gt;<br />&lt;ol compact="yes"&gt;<br />          </div>
		<div>您可以使用单引号，也可以使用双引号，但要始终保持一致。</div>
		<div>如果属性值包含单引号或双引号，则您可以使用另一种引号来括起该值（如 name="Doug's car"），或使用实体 &amp;quot; 代表双引号，使用 </div>
		<div>&amp;apos; 代表单引号。实体是一个符号（如 &amp;quot;），XML 解析器会用其它文本代替该符号（如 "）。</div>
		<div> </div>
		<div>
				<strong>
						<em>XML 声明<br /></em>
				</strong>大多数 XML 文档以 XML 声明作为开始，它向解析器提供了关于文档的基本信息。建议使用 XML 声明，但它不是必需的。如果有的话，那么它一</div>
		<div>定是文档的第一样东西。</div>
		<div>声明最多可以包含三个名称-值对（许多人称它们为属性，尽管在技术上它们并不是）。version 是使用的 XML 版本；目前该值必须是 1.0。</div>
		<div>encoding 是该文档所使用的字符集。该声明中引用的 ISO-8859-1 字符集包括大多数西欧语言用到的所有字符。如没有指定 encoding，XML 解</div>
		<div>析器会假定字符在 UTF-8 字符集中，这是一个几乎支持世界上所有语言的字符和象形文字的 Unicode 标准。</div>
		<div>
				<br />&lt;?xml version="1.0" encoding="ISO-8859-1" standalone="no"?&gt;<br />          </div>
		<div>最后，standalone（可以是 yes 或 no）定义了是否可以在不读取任何其它文件的情况下处理该文档。例如，如果 XML 文档没有引用任何其它文</div>
		<div>件，则您可以指定 standalone="yes"。如果 XML 文档引用其它描述该文档可以包含什么的文件（马上会详细介绍这些文件），则您可以指定 </div>
		<div>standalone="no"。因为 standalone="no" 是缺省的，所以您很少会在 XML 声明中看到 standalone。</div>
		<div>
				<br />
				<em>
						<strong>XML 文档中的其它项<br /></strong>
				</em>您或许会在一个 XML 文档中发现其它几项：</div>
		<div>注释：注释可以出现在文档的任何位置；它们甚至可以出现在根元素的前面或后面。注释以 &lt;!-- 开始，以 --&gt; 结束。注释不能在结束部分以外</div>
		<div>包含双连字符（--）；除此之外，注释可以包含任何内容。最重要的是，注释内的任何标记都被忽略；如果您希望除去 XML 文档的一块较大部分</div>
		<div>，只需用注释括住那个部分即可。（要恢复这个注释掉的部分，只需除去注释标记即可。）下面是包含注释的标记： </div>
		<div>&lt;!-- Here's a PI for Cocoon: --&gt;<br />&lt;?cocoon-process type="sql"?&gt;<br />          </div>
		<div>处理指令：处理指令是为使用一段特殊代码而设计的标记。在上面的示例中，有一个用于 Cocoon 的处理指令（有时称为 PI），Cocoon 是来自 </div>
		<div>Apache 软件基金会（Apache Software Foundation）的 XML 处理框架。当 Cocoon 处理 XML 文档时，它会寻找以 cocoon-process 开头的处理</div>
		<div>指令，然后相应地处理 XML 文档。在该示例中，type="sql" 属性告诉 Cocoon：XML 文档包含一个 SQL 语句。 </div>
		<div>&lt;!-- Here's an entity: --&gt;<br />&lt;!ENTITY dw "developerWorks"&gt;<br />          </div>
		<div>实体：上面的示例为文档定义了一个实体。无论 XML 处理器在何处找到字符串 &amp;dw;，它都会用字符串 developerWorks 代替该实体。XML 规范</div>
		<div>还定义了五个您可以用来替代不同的特殊字符的实体。这些实体是：<br />&amp;lt; 代表小于符号 <br />&amp;gt; 代表大于符号 <br />&amp;quot; 代表一个双引号 <br />&amp;apos; 代表一个单引号（或撇号） <br />&amp;amp; 代表一个“与”符号。 </div>
		<div>
				<br />
				<em>
						<strong>名称空间</strong>
				</em>
				<br />XML 的能力来自它的灵活性，即您和我以及数百万其他人可以定义我们自己的标记来描述我们的数据。记得表示个人姓名和地址的样本 XML 文档</div>
		<div>吗？那个文档包括表示个人尊称的 &lt;title&gt; 元素，这是对元素名称非常合理的选择。如果您经营一家网上书店，您或许会创建一个表示书名的 </div>
		<div>&lt;title&gt; 元素。如果您经营一家网上抵押放款公司，您或许会创建表示一份财产名称的 &lt;title&gt; 元素。所有这些都是合理的选择，但它们都用相</div>
		<div>同的名称创建元素。如何分辨某个特定的 &lt;title&gt; 元素指的是人、书籍还是一份财产呢？可以使用名称空间。</div>
		<div>要使用名称空间，您要定义一个名称空间前缀，然后将它映射至一个特殊字符串。下面介绍如何定义我们这三个 &lt;title&gt; 元素的名称空间前缀：</div>
		<div>
				<br />&lt;?xml version="1.0"?&gt;<br />&lt;customer_summary<br />  xmlns:addr="<a href="http://www.xyz.com/addresses/"><font color="#ffffff">http://www.xyz.com/addresses/</font></a>"<br />  xmlns:books="<a href="http://www.zyx.com/books/"><font color="#ffffff">http://www.zyx.com/books/</font></a>"<br />  xmlns:mortgage="<a href="http://www.yyz.com/title/"><font color="#ffffff">http://www.yyz.com/title/</font></a>"<br />&gt;<br />... &lt;addr:name&gt;&lt;title&gt;Mrs.&lt;/title&gt; ... &lt;/addr:name&gt; ...<br />... &lt;books:title&gt;Lord of the Rings&lt;/books:title&gt; ...<br />... &lt;mortgage:title&gt;NC2948-388-1983&lt;/mortgage:title&gt; ...<br />          </div>
		<div>在该示例中，三个名称空间前缀是 addr、books 和 mortgage。请注意，为特定元素定义名称空间意味着该元素的所有子元素都属于同一名称空</div>
		<div>间。第一个 &lt;title&gt; 元素属于 addr 名称空间，因为其父元素 &lt;addr:Name&gt; 属于该名称空间。</div>
		<div>最后要指出的是：名称空间定义中的字符串仅仅是字符串。对，这些字符串看似 URL，其实不是。您可以定义 xmlns:addr="mike"，那也是有效</div>
		<div>的。名称空间唯一的重要性在于其唯一性；这就是为什么大多数名称空间定义看起来象 URL 的原因。XML 解析器不会到 </div>
		<div>
				<a href="http://www.zyx.com/books/">
						<font color="#ffffff">http://www.zyx.com/books/</font>
				</a> 去搜索 DTD 或模式，它只是把那个文本作为字符串使用。这有些令人困惑，但名称空间就是这样工作的。</div>
		<div> </div>
		<div>
				<br />
				<strong>定义文档内容 </strong>   <br />在了解到了 XML 文档的基本规则之后，您需要定义将用来表示数据的元素。做到这一点的两种方法。</div>
		<div>一种方法是使用文档类型定义（Document Type Definition），或简称 DTD。DTD 定义可以在 XML 文档中出现的元素、这些元素出现的次序、它</div>
		<div>们可以如何相互嵌套以及 XML 文档结构的其它详细信息。DTD 是最初的 XML 规范的一部分，与 SGML DTD 非常相似。 <br />另一种方法是使用 XML Schema。模式可以定义您能在 DTD 中使用的所有文档结构，它还可以定义数据类型和比 DTD 更复杂的规则。W3C 在提出</div>
		<div>最初的 XML 规范的几年之后开发了 XML Schema 规范。  </div>
		<div> </div>
		<div>
				<em>
						<strong>文档类型定义</strong>
				</em>
				<br />DTD 允许您指定 XML 文档的基本结构。下面的几页将研究 DTD 片段。首先是定义本章中地址文档示例的基本结构的 DTD，XML 是什么？：</div>
		<div>
				<br />&lt;!-- address.dtd --&gt;<br />&lt;!ELEMENT address (name, street, city, state, postal-code)&gt;<br />&lt;!ELEMENT name (title? first-name, last-name)&gt;<br />&lt;!ELEMENT title (#PCDATA)&gt;<br />&lt;!ELEMENT first-name (#PCDATA)&gt;<br />&lt;!ELEMENT last-name (#PCDATA)&gt;<br />&lt;!ELEMENT street (#PCDATA)&gt;<br />&lt;!ELEMENT city (#PCDATA)&gt;<br />&lt;!ELEMENT state (#PCDATA)&gt;<br />&lt;!ELEMENT postal-code (#PCDATA)&gt;<br />          </div>
		<div>该 DTD 定义了样本文档中使用的所有元素。它定义了三个元素：</div>
		<div>&lt;address&gt; 元素包含一个 &lt;name&gt;、一个 &lt;street&gt;、一个 &lt;city&gt;、一个 &lt;state&gt; 和一个 &lt;postal-code&gt;。所有这些元素必须出现，而且必须以</div>
		<div>这个顺序出现。 <br />&lt;name&gt; 元素包含一个可选的 &lt;title&gt; 元素（问号表示 title 这个元素是可选的），后面跟有一个 &lt;first-name&gt; 和一个 &lt;last-name&gt; 元素。 <br />所有其它包含文本的元素。（#PCDATA 代表已解析字符数据；不能在这些元素中包含另一个元素。） <br />尽管 DTD 相当简单，但它清楚地说明了什么样的元素组合是合乎规则的。&lt;postal-code&gt; 元素在 &lt;state&gt; 元素之前的地址文档是不合乎规则的</div>
		<div>，没有 &lt;last-name&gt; 元素的文档也不合乎规则。</div>
		<div>另外，请注意，DTD 语法不同于普通的 XML 语法。（相反，XML Schema 文档本身就是 XML，这导致一些有趣的结果）。尽管 DTD 的语法不同，</div>
		<div>但您仍可以将普通的注释放到 DTD 中。</div>
		<div>
				<br />
				<em>
						<strong>DTD 中的符号</strong>
				</em>
				<br />DTD 中有几个符号用于指出某元素在 XML 文档中可能会出现多少次（或是否出现）。下面是一些示例及其含义：</div>
		<div>&lt;!ELEMENT address (name, city, state)&gt; <br />&lt;address&gt; 元素必须包含一个 &lt;name&gt; 元素、一个 &lt;city&gt; 元素和一个 &lt;state&gt; 元素，并且符合上面的次序。所有的元素都是必需的。逗号表示</div>
		<div>项的列表。 </div>
		<div>&lt;!ELEMENT name (title?, first-name, last-name)&gt; <br />这意味着 &lt;name&gt; 元素包含一个可选的 &lt;title&gt; 元素，后面必须跟有一个 &lt;first-name&gt; 和一个 &lt;last-name&gt; 元素。问号表示这一项是可选的</div>
		<div>；它可以出现一次或根本不出现。 </div>
		<div>&lt;!ELEMENT addressbook (address+)&gt; <br />&lt;addressbook&gt; 元素包含一个或多个 &lt;address&gt; 元素。您可以有任意多的 &lt;address&gt; 元素，但必须至少有一个。加号表示这一项必须至少出现</div>
		<div>一次，但可出现任意次。 </div>
		<div>&lt;!ELEMENT private-addresses (address*)&gt; <br />&lt;private-addresses&gt; 元素包含零个或多个 &lt;address&gt; 元素。星号表示这一项可以出现任意次，包括零次。 </div>
		<div>&lt;!ELEMENT name (title?, first-name, (middle-initial | middle-name)?, last-name)&gt; <br />&lt;name&gt; 元素包含一个可选的 &lt;title&gt; 元素，后面跟有一个 &lt;first-name&gt; 元素，随后可能跟有一个 &lt;middle-initial&gt; 或 &lt;middle-name&gt; 元素</div>
		<div>，然后跟有一个 &lt;last-name&gt; 元素。换句话说，&lt;middle-initial&gt; 和 &lt;middle-name&gt; 都是可选的，而且您只能选择二者中的一个。竖线符号表</div>
		<div>示选择列表；您只能从列表选择一项。还要注意该示例用圆括号对特定元素进行分组，然后在这个组旁放上问号。</div>
		<div>&lt;!ELEMENT name ((title?, first-name, last-name) | (surname, mothers-name, given-name))&gt; <br />这个 &lt;name&gt; 元素可以包含两个序列中的一个：一个可选的 &lt;title&gt;，后面跟有一个 &lt;first-name&gt; 和一个 &lt;last-name&gt;；或一个 &lt;surname&gt;、</div>
		<div>一个 &lt;mothers-name&gt; 和一个 &lt;given-name&gt;。</div>
		<div> </div>
		<div>
				<strong>
						<em>定义属性</em>
				</strong>
				<br />本篇介绍性教程没有很详细地研究 DTD 如何工作，但这里要介绍一个更基本的概念：定义属性。您可以定义将在 XML 文档中出现的元素的属性</div>
		<div>。使用 DTD，您还可以：</div>
		<div>定义哪些属性是必需的 <br />定义属性的缺省值 <br />列出给定属性的所有有效值 <br />假设您要更改 DTD，使 state 成为 &lt;city&gt; 元素的属性。下面演示如何做到这一点：</div>
		<div>
				<br />&lt;!ELEMENT city (#PCDATA)&gt;<br />&lt;!ATTLIST city state CDATA #REQUIRED&gt;<br />          </div>
		<div>和以前一样，我们定义了 &lt;city&gt; 元素，但修改的示例还使用了 ATTLIST 声明来列出元素的属性。属性列表中的名称 city 告诉解析器这些属性</div>
		<div>是为 &lt;city&gt; 元素定义的。名称 state 是属性的名称，关键字 CDATA 和 #REQUIRED 告诉解析器 state 属性包含文本并且是必需的（如果它是</div>
		<div>可选的，用 CDATA #IMPLIED 即可）。</div>
		<div>要定义元素的多个属性，可象下面那样编写 ATTLIST：</div>
		<div>
				<br />&lt;!ELEMENT city (#PCDATA)&gt;<br />&lt;!ATTLIST city state CDATA #REQUIRED<br />               postal-code CDATA #REQUIRED&gt;<br />          </div>
		<div>该示例将 state 和 postal-code 都定义为 &lt;city&gt; 元素的属性。</div>
		<div>最后，DTD 允许您定义属性缺省值，并列举属性的所有有效值：</div>
		<div>
				<br />&lt;!ELEMENT city (#PCDATA)&gt;<br />&lt;!ATTLIST city state CDATA (AZ|CA|NV|OR|UT|WA) "CA"&gt;<br />          </div>
		<div>上面的示例表明它仅支持来自亚利桑那州（AZ）、加利福尼亚州（CA）、内华达州（NV）、俄勒冈州（OR）、犹他州（UT）和华盛顿州（WA）的地址，并且缺省值是加利福尼亚州。这样，您就可以进行形式非常有限的数据验证。尽管这是有用的功能，但它只是您能用 XML 模式（请参阅</div>
		<div>XML 模式）完成的工作的一个小子集。</div>
		<div> </div>
		<div>
				<strong>
						<em>XML 模式<br /></em>
				</strong>使用 XML 模式，您会有更多的能力来定义什么样的 XML 文档是有效的。它们与 DTD 相比有几个优势：</div>
		<div>XML 模式使用 XML 语法。换句话说，XML 模式是一个 XML 文档。这意味着您可以象处理任何其它文档一样处理模式。例如，您可以编写一个 XSLT 样式表，该样式表将 XML 模式转换成具有自动生成的 JavaScript 代码的 Web 表单，其中的 JavaScript 代码可以验证您输入的数据。 <br />XML 模式支持数据类型。尽管 DTD 确实支持数据类型，但很明显这些数据类型是从发布的角度开发的。XML 模式支持 DTD 中的所有原始数据类型（诸如标识和标识引用之类的类型）。它们还支持整数、浮点数、日期、时间、字符串、URL 和其它对数据处理和验证有用的数据类型。 <br />XML 模式是可扩展的。除了 XML 模式规范中定义的数据类型以外，您还可以创建自己的数据类型，并且可以基于其它数据类型派生出新的数据类型。 <br />XML 模式有更强的表达能力。例如，您可以用 XML 模式定义任何 &lt;state&gt; 属性值不得超过 2 个字符，或定义任何 &lt;postal-code&gt; 元素的值必</div>
		<div>须与正则表达式 [0-9]{5}(-[0-9]{4})? 相匹配。您无法用 DTD 做这些事。 </div>
		<div> </div>
		<div>
				<strong>
						<em>样本 XML 模式</em>
				</strong>
				<br />下面是与原始名称和地址 DTD 相匹配的 XML 模式。它增加了两个约束：&lt;state&gt; 元素的值必须刚好是两个字符长，&lt;postal-code&gt; 元素的值必</div>
		<div>须与正则表达式 [0-9]{5}(-[0-9]{4})? 相匹配。尽管这个模式比 DTD 长很多，但它更清楚地表达了有效的文档看起来是什么样子。下面是模式</div>
		<div>：</div>
		<div>
				<br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;xsd:schema xmlns:xsd="<a href="http://www.w3.org/2001/XMLSchema"><font color="#ffffff">http://www.w3.org/2001/XMLSchema</font></a>"&gt;<br />  &lt;xsd:element name="address"&gt;<br />    &lt;xsd:complexType&gt;<br />      &lt;xsd:sequence&gt;<br />        &lt;xsd:element ref="name"/&gt;<br />        &lt;xsd:element ref="street"/&gt;<br />        &lt;xsd:element ref="city"/&gt;<br />        &lt;xsd:element ref="state"/&gt;<br />        &lt;xsd:element ref="postal-code"/&gt;<br />      &lt;/xsd:sequence&gt;<br />    &lt;/xsd:complexType&gt;<br />  &lt;/xsd:element&gt;</div>
		<div>  &lt;xsd:element name="name"&gt;<br />    &lt;xsd:complexType&gt;<br />      &lt;xsd:sequence&gt;<br />        &lt;xsd:element ref="title" minOccurs="0"/&gt;<br />        &lt;xsd:element ref="first-Name"/&gt;<br />        &lt;xsd:element ref="last-Name"/&gt;<br />      &lt;/xsd:sequence&gt;<br />    &lt;/xsd:complexType&gt;<br />  &lt;/xsd:element&gt;</div>
		<div>  &lt;xsd:element name="title"      type="xsd:string"/&gt;<br />  &lt;xsd:element name="first-Name" type="xsd:string"/&gt;<br />  &lt;xsd:element name="last-Name"  type="xsd:string"/&gt;<br />  &lt;xsd:element name="street"     type="xsd:string"/&gt;<br />  &lt;xsd:element name="city"       type="xsd:string"/&gt;</div>
		<div>  &lt;xsd:element name="state"&gt;<br />    &lt;xsd:simpleType&gt;<br />      &lt;xsd:restriction base="xsd:string"&gt;<br />        &lt;xsd:length value="2"/&gt;<br />      &lt;/xsd:restriction&gt;<br />    &lt;/xsd:simpleType&gt;<br />  &lt;/xsd:element&gt;</div>
		<div>  &lt;xsd:element name="postal-code"&gt;<br />    &lt;xsd:simpleType&gt;<br />      &lt;xsd:restriction base="xsd:string"&gt;<br />        &lt;xsd:pattern value="[0-9]{5}(-[0-9]{4})?"/&gt;<br />      &lt;/xsd:restriction&gt;<br />    &lt;/xsd:simpleType&gt;<br />  &lt;/xsd:element&gt;<br />&lt;/xsd:schema&gt;<br />          <br /><strong><em>定义模式中的元素</em></strong><br />样本 XML 模式中的 XML 模式用 &lt;xsd:element&gt; 元素定义了一些 XML 元素。头两个定义的元素（&lt;address&gt; 和 &lt;name&gt;）由其它元素组成。</div>
		<div>&lt;xsd:sequence&gt; 元素定义了包含在这两个元素中的元素的序列。下面是示例：</div>
		<div>
				<br />&lt;xsd:element name="address"&gt;<br />  &lt;xsd:complexType&gt;<br />    &lt;xsd:sequence&gt;<br />      &lt;xsd:element ref="name"/&gt;<br />      &lt;xsd:element ref="street"/&gt;<br />      &lt;xsd:element ref="city"/&gt;<br />      &lt;xsd:element ref="state"/&gt;<br />      &lt;xsd:element ref="postal-code"/&gt;<br />    &lt;/xsd:sequence&gt;<br />  &lt;/xsd:complexType&gt;<br />&lt;/xsd:element&gt;<br />          </div>
		<div>与 DTD 版本一样，XML 模式示例定义 &lt;address&gt; 包含一个 &lt;name&gt;、一个 &lt;street&gt;、一个 &lt;city&gt;、一个 &lt;state&gt; 和一个 &lt;postal-code&gt; 元素</div>
		<div>，并且依照上面的次序。请注意，该模式实际上用 &lt;xsd:complexType&gt; 元素定义了新的数据类型。</div>
		<div>大多数元素包含文本；定义它们很简单。您只要声明新的元素，然后指定它的数据类型为 xsd:string：</div>
		<div>
				<br />&lt;xsd:element name="title"      type="xsd:string"/&gt;<br />&lt;xsd:element name="first-Name" type="xsd:string"/&gt;<br />&lt;xsd:element name="last-Name"  type="xsd:string"/&gt;<br />&lt;xsd:element name="street"     type="xsd:string"/&gt;<br />&lt;xsd:element name="city"       type="xsd:string"/&gt;<br />          <br /><strong><em>定义模式中的元素内容<br /></em></strong>样本模式为两个元素的内容定义了约束：&lt;state&gt; 元素的内容必须是两个字符长，而 &lt;postal-code&gt; 元素的内容必须与正则表达式 [0-9]{5}(-</div>
		<div>[0-9]{4})? 匹配。下面演示如何做到那一点：</div>
		<div>
				<br />  &lt;xsd:element name="state"&gt;<br />    &lt;xsd:simpleType&gt;<br />      &lt;xsd:restriction base="xsd:string"&gt;<br />        &lt;xsd:length value="2"/&gt;<br />      &lt;/xsd:restriction&gt;<br />    &lt;/xsd:simpleType&gt;<br />  &lt;/xsd:element&gt;</div>
		<div>  &lt;xsd:element name="postal-code"&gt;<br />    &lt;xsd:simpleType&gt;<br />      &lt;xsd:restriction base="xsd:string"&gt;<br />        &lt;xsd:pattern value="[0-9]{5}(-[0-9]{4})?"/&gt;<br />      &lt;/xsd:restriction&gt;<br />    &lt;/xsd:simpleType&gt;<br />  &lt;/xsd:element&gt;<br />          </div>
		<div>对于 &lt;state&gt; 和 &lt;postal-code&gt; 元素，模式用约束定义了新的数据类型。第一个情况使用 &lt;xsd:length&gt; 元素，而第二个情况则使用 </div>
		<div>&lt;xsd:pattern&gt; 元素定义该元素必须匹配的正则表达式。</div>
		<div>这里概要的介绍仅仅触及 XML 模式能力的表面；有整本的书籍讨论这个主题。就这篇介绍性文章而言，我们足以说明 XML 模式是描述什么样的 </div>
		<div>XML 文档才算有效的非常强大和灵活的方式。</div>
		<div> </div>
		<div> </div>
		<div> <strong>XML 编程接口<br /></strong>本章将研究 XML 的多种编程接口。这些接口为开发人员使用 XML 文档提供了一致的接口。有许多 API 可以使用；本章研究最流行和广泛使用的 </div>
		<div>API 中的四种：文档对象模型（Document Object Model (DOM)）、用于 XML 的简单 API（Simple API for XML (SAX)）、JDOM 和用于 XML 解</div>
		<div>析的 Java API（Java API for XML Parsing (JAXP)）。（您可以通过参考资料中的大量链接找到有关这些 API 的更多信息。）</div>
		<div>
				<br />
				<strong>
						<em>文档对象模型<br /></em>
				</strong>文档对象模型（通常称为 DOM）为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档，然后构建一个驻留内存的树结构，然后您的代</div>
		<div>码就可以使用 DOM 接口来操作这个树结构。您可以遍历树以了解原始文档包含了什么，您可以删除树的几个部分，还可以重新排列树和添加新的</div>
		<div>分支，等等。</div>
		<div>DOM 由 W3C 创建，并且是该协会的正式建议书。</div>
		<div>DOM 问题<br />DOM 提供了一组丰富的功能，您可以用这些功能来解释和操作 XML 文档，但使用它们是有代价的。在开发用于 XML 文档的原始 DOM 时，XML-</div>
		<div>DEV 邮件列表上的许多人提出了 DOM 的几个问题：</div>
		<div>DOM 构建整个文档驻留内存的树。如果文档很大，就会要求有极大的内存。 <br />DOM 创建表示原始文档中每个东西的对象，包括元素、文本、属性和空格。如果您只需关注原始文档的一小部分，那么创建那些永远不被使用的</div>
		<div>对象是极其浪费的。 <br />DOM 解析器必须在您的代码取得控制权之前读取整个文档。对于非常大的文档，这会引起显著的延迟。 <br />这些仅仅是由文档对象模型的设计引起的问题；撇开这些问题，DOM API 是解析 XML 文档非常有用的方法。</div>
		<div>用于 XML 的简单 API  第 4 页（共8 页） </div>
		<div> </div>
		<div>
				<br />为了解决 DOM 问题，XML-DEV 参与者们（由 David Megginson 领导）创建了 SAX 接口。SAX 的几个特征解决了 DOM 的问题：</div>
		<div>SAX 解析器向您的代码发送事件。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时，它会告诉您。您可以决定什么事件对您重</div>
		<div>要，而且可以决定要创建什么类型的数据结构以保存来自这些事件的数据。如果您没有显式地保存来自某个事件的数据，它就被丢弃。 <br />SAX 解析器根本不创建任何对象，它只是将事件传递给您的应用程序。如果希望基于那些事件创建对象，这将由您来完成。 <br />SAX 解析器在解析开始的时候就开始发送事件。当解析器发现文档开始、元素开始和文本等时，代码会收到一个事件。您的应用程序可以立即开</div>
		<div>始生成结果；您不必一直等到整个文档被解析完毕。更妙的是，如果您只查找文档中某些内容，代码一旦找到所要找的东西就可以抛出一个异常</div>
		<div>。该异常会停止 SAX 解析器，然后代码用它找到的数据做它需要做的任何事。 <br />该说的都已经说了，SAX 和 DOM 各有千秋。本章余下的部分将讨论为什么您可能需要使用不同的接口。</div>
		<div> </div>
		<div>
				<strong>
						<em>SAX 问题<br /></em>
				</strong>公平而言，SAX 解析器也有些问题引人关注：</div>
		<div>SAX 事件是无状态的。当 SAX 解析器在 XML 文档中发现文本时，它就向您的代码发送一个事件。该事件仅仅给您发现的文本；它不告诉您什么</div>
		<div>元素包含那个文本。如果您想知道这一点，则必须自己编写状态管理代码。 <br />SAX 事件不是持久的。如果应用程序需要一个数据结构来对 XML 文档建模，则必须自己编写那样的代码。如果您需要从 SAX 事件访问数据，并</div>
		<div>且没有把那个数据存储在代码中，那么您不得不再次解析该文档。 <br />SAX 不是由一个集中管理的组织控制的。尽管到目前为止这还没有引起什么问题，但如果 SAX 是由象 W3C 这样的一个组织控制的话，有些开发</div>
		<div>人员会感觉更自在。 </div>
		<div> </div>
		<div>
				<strong>
						<em>JDOM</em>
				</strong>
				<br />用 DOM 和 SAX 模型完成某些任务时的困难使 Jason Hunter 和 Brett McLaughlin 感到失望，于是他们创建了 JDOM 包。JDOM 是基于 Java 技</div>
		<div>术的开放源码项目，它试图遵循 80/20 规则：用 DOM 和 SAX 20% 的功能来满足 80% 的用户需求。JDOM 使用 SAX 和 DOM 解析器，因此它是作</div>
		<div>为一组相对较小的 Java 类被实现的。</div>
		<div>JDOM 的主要特性是它极大地减少了您必须编写的代码数量。尽管本篇介绍性教程并不深入讨论编程主题，但 JDOM 应用程序的长度通常是 DOM </div>
		<div>应用程序的三分之一，大约是 SAX 应用程序的一半。（当然，坚持使用 DOM 的纯粹主义者会建议说：从长远来看，学习和使用 DOM 终会有所回</div>
		<div>报）。JDOM 并不做所有的事，但对于大多数您要做的解析，它可能正好适合您。</div>
		<div>用于 XML 解析的 Java API<br />尽管 DOM、SAX 和 JDOM 为大多数常见任务提供了标准接口，但仍有些事情是它们不能解决的。例如，在 Java 程序中创建 DOMParser 对象的过</div>
		<div>程因 DOM 解析器的不同而不同。为了修正这个问题，Sun 发布了 JAXP（用于 XML 解析的 Java API，Java API for XML Parsing）。该 API 为</div>
		<div>使用 DOM、SAX 和 XSLT 处理 XML 文档提供了公共接口。</div>
		<div>JAXP 提供的诸如 DocumentBuilderFactory 和 DocumentBuilder 之类的接口为不同的解析器提供了一个标准接口。还有一些方法可以允许您控</div>
		<div>制底层的解析器是否可以识别名称空间以及是否使用 DTD 或模式来验证 XML 文档。</div>
		<div>哪种接口适合您？<br />为了确定哪种接口适合您，您需要理解所有接口的设计要点，而且需要理解应用程序用您将要处理的 XML 文档来做什么。考虑下面的问题将有助</div>
		<div>于您找到正确的方法。</div>
		<div>要用 Java 编写应用程序吗？JAXP 使用 DOM、SAX 和 JDOM；如果您用 Java 编写代码，那么您应使用 JAXP 将您的代码与各种解析器实现的细</div>
		<div>节隔离。 <br />应用程序将如何部署？如果您的应用程序将要作为 Java applet 部署，那么您会希望使要下载的代码数量最小，别忘了 SAX 解析器比 DOM 解析</div>
		<div>器小。还要知道使用 JDOM 时，除了 SAX 或 DOM 解析器之外还要求编写少量的代码。 <br />一旦解析了 XML 文档，还需要多次访问那些数据吗？如果您需要回过头来访问 XML 文件的已解析版本，DOM 可能是正确的选择。而 SAX 事件被</div>
		<div>触发时，如果您以后需要它，则由您（开发人员）自己决定以某种方式保存它。如果您需要访问不曾保存的事件，则必须再次解析该文件。而 </div>
		<div>DOM 自动保存所有的数据。 <br />只需要 XML 源文件的少量内容吗？如果您只需要 XML 源文件的少量内容，那么 SAX 可能是正确的选择。SAX 不会为源文件中的每个东西创建对</div>
		<div>象；您要确定什么是重要的。使用 SAX，您要检查每个事件以了解它是否与您的需要有关，然后相应地处理它。更妙的是，一旦找到您正在寻找</div>
		<div>的东西，您的代码就会抛出一个异常来完全停止 SAX 解析器。 <br />您正在一台内存很少的机器上工作吗？若是的话，不管您可能考虑到的其它因素是什么，SAX 是您的最佳选择。 <br />要知道还存在用于其它语言的 XML API；尤其是 Perl 和 Python 社区有极佳的 XML 工具。</div>
		<div> </div>
		<div> </div>
		<div>
				<strong>XML 标准</strong>
				<br />XML 世界中存在多种标准。除了基本 XML 标准以外，其它标准定义了模式、样式表、链接、Web 服务、安全性和其它重要项目。本章介绍最流行</div>
		<div>的 XML 标准，并为您指出了查找其它标准的参考资料。</div>
		<div>
				<br />
				<strong>
						<em>XML 规范</em>
				</strong>
				<br />该规范（位于 <a href="http://www.w3.org/TR/REC-xml"><font color="#ffffff">http://www.w3.org/TR/REC-xml</font></a>）定义了 XML 文档的基本规则。本教程前面讨论的所有 XML 文档规则都是在此规范中定义的。</div>
		<div>除了基本 XML 标准以外，名称空间规范是 XML 的另一个重要部分。您也可以在 W3C 查找名称空间标准：<a href="http://www.w3.org/TR/REC-xml"><font color="#ffffff">http://www.w3.org/TR/REC-xml</font></a>-</div>
		<div>names/。</div>
		<div>
				<br />XML Schema<br />XML Schema 语言定义成以下三个部分：</div>
		<div>入门位于 w3.org/TR/xmlschema-0，它介绍了 XML 模式文档及其设计用途； <br />文档结构的标准位于w3.org/TR/xmlschema-1，它说明了如何定义 XML 文档的结构； <br />数据类型的标准位于w3.org/TR/xmlschema-2，它定义了一些常用数据类型以及创建新类型的规则。 <br />本教程在定义文档内容中简要地介绍了模式；如果您对于用 XML 模式可以做的所有事情，需要了解完整的详细信息，那么最好先阅读“入门”。<br /> <br />XSL、XSLT 和 XPath<br />可扩展样式表语言（Extensible Stylesheet Language（XSL））定义了一组元素（称为格式化对象），它们描述应该如何格式化数据。为清晰起</div>
		<div>见，通常将该标准称为 XSL-FO 以和 XSLT 进行区分。尽管它主要是设计用于生成高质量的可打印文档，但您也可以使用格式化对象从 XML 生成</div>
		<div>音频文件。XSL-FO 标准位于 w3.org/TR/xsl/。</div>
		<div>用于转换的可扩展样式表语言（Extensible Stylesheet Language for Transformation（XSLT））是一个描述如何将 XML 文档转换成别的东西</div>
		<div>的 XML 词汇表。该标准位于w3.org/TR/xslt（结尾没有斜杠符号）。</div>
		<div>XPath（XML 路径语言，XML Path Language）是描述 XML 文档中位置的语法。您使用 XSLT 样式表中的 XPath 来描述您希望转换 XML 文档的哪</div>
		<div>个部分。XPath 也用在其它 XML 标准中，这就是为什么它是独立于 XSLT 的标准的原因。XPath 在 w3.org/TR/xpath（结尾没有斜杠符号）中定</div>
		<div>义。</div>
		<div>DOM <br />文档对象模型定义了如何将 XML 文档转换为驻留内存的树结构。DOM 在 W3C 的许多规范中都有定义：</div>
		<div>核心 DOM 定义 DOM 本身、树结构、以及代码遍历树时会发现的各种节点和异常。完整的规范在 w3.org/TR/DOM-Level-2-Core/。 <br />事件定义对于树可以发生的事件，以及如何处理这些事件。该规范试图协调 Netscape 和 Internet Explorer 浏览器的版本 4 之后所支持对象</div>
		<div>模型之间的差异。该规范位于 w3.org/TR/DOM-Level-2-Events/。 <br />样式定义程序如何访问 XSLT 样式表和 CSS 样式表。该规范位于 w3.org/TR/DOM-Level-2-Style/。 <br />遍历和范围定义一些允许程序遍历树或定义树中节点范围的接口。可以在 w3.org/TR/DOM-Level-2-Traversal-Range/ 找到完整的规范。 <br />视图为文档本身定义 AbstractView 接口。请参阅 w3.org/TR/DOM-Level-2-Views/ 以获得更多信息。</div>
		<div> </div>
		<div>
				<strong>
						<em>SAX、JDOM 和 JAXP<br /></em>
				</strong>用于 XML 的简单 API 定义了一些事件和接口，用于与符合 SAX 的 XML 解析器进行交互。可以在 <a href="http://www.saxproject.org/"><font color="#ffffff">www.saxproject.org</font></a> 上找到完整的 SAX 规范</div>
		<div>。</div>
		<div>Jason Hunter 和 Brett McLaughlin 创建的 JDOM 项目位于 jdom.org/。在 JDOM 站点，您可以找到代码、样本程序和其它能帮助您入门的工具</div>
		<div>。（有关在 developerWorks 上介绍 JDOM 的文章，请参阅参考资料）。</div>
		<div>有关 SAX 和 JDOM 的重要一点是：二者都来自 XML 开发人员社区，而不是标准组织。它们获得的广泛接受是对全世界 XML 开发人员积极参与的</div>
		<div>回报。</div>
		<div>您可以在 java.sun.com/xml/jaxp/ 找到所有与 JAXP 有关的内容。</div>
		<div>
				<br />链接和引用<br />在 XML 世界中有两个用于链接和引用的标准：XLink 和 XPointer：</div>
		<div>XLink（XML 链接语言，XML Linking Language）定义将不同资源链接在一起的各种方法。您可以进行正常的点对点链接（就象用 HTML &lt;a&gt; 元素</div>
		<div>）或扩展的链接，后者可包括多点链接、通过第三方的链接以及定义转向给定链接的意义的规则。XLink 标准位于 <a href="http://www.w3.org/TR/xlink/"><font color="#ffffff">www.w3.org/TR/xlink/</font></a>。 <br />XPointer（XML 指针语言，XML Pointer Language）使用 XPath 作为引用其它资源的方法。它还包括对 XPath 的一些扩展。可以在 </div>
		<div>
				<a href="http://www.w3.org/TR/xptr/">
						<font color="#ffffff">www.w3.org/TR/xptr/</font>
				</a> 找到该规范。 </div>
		<div>安全性<br />有两个处理 XML 文档安全性的重要标准。一个是 XML 数字签名（XML Digital Signature）标准（w3.org/TR/xmldsig-core/），它定义了用于</div>
		<div>数字签名的 XML 文档结构。您可以为任何类型的数据创建 XML 数字签名，不管它是 XML 文档、HTML 文件、纯文本、二进制数据还是其它东西</div>
		<div>。您可以用数字签名来验证一个特定文件自签名后没有被修改过。如果您要签名的数据是 XML 文档，您可以将 XML 文档嵌入签名文件本身，这</div>
		<div>会使数据和签名的处理变得非常简单。</div>
		<div>另一个标准用于加密 XML 文档。可以将 XML 文档编写得易于人们阅读和理解，尽管这样做很好，但如果文档落入坏人之手就会引起麻烦。XML </div>
		<div>加密（XML Encryption）标准（w3.org/TR/xmlenc-core/）定义了如何加密 XML 文档的各部分。</div>
		<div>将这些标准一起使用，您就能放心地使用 XML 文档了。我可以对一个重要的 XML 文档进行数字签名，生成一个包含 XML 文档本身的签名。然后</div>
		<div>我可以加密该文档（使用我的私钥和您的公钥）然后把它发送给您。当您收到文档时，您可以用您的私钥和我的公钥解密该文档；这可以让您知</div>
		<div>道是我发送的文档。（如果需要，您还可以证明我发送了文档）。一旦您解密了文档，您可以使用该数字签名确定文档没有经过任何修改。</div>
		<div> </div>
		<div>
				<strong>
						<em>Web 服务</em>
				</strong>
				<br />Web 服务是一种新的重要的应用程序。Web 服务是一段可以用 XML 发现、描述和访问的代码。在这一领域有许多活动，但有三种主要的用于 Web </div>
		<div>服务的 XML 标准：</div>
		<div>SOAP：最初是简单对象访问协议（Simple Object Access Protocol），SOAP 定义一个 XML 文档格式，该格式描述如何调用一段远程代码的方法</div>
		<div>。我的应用程序创建一个描述我希望调用的方法的 XML 文档，并传递给它所有必需的参数，然后应用程序通过网络将该 XML 文档发送给那段代</div>
		<div>码。代码接收 XML 文档、解释它、调用我请求的方法，然后发回一个描述结果的 XML 文档。SOAP 规范版本 1.1 位于 w3.org/TR/SOAP/。请访</div>
		<div>问 w3.org/TR/ 以了解 W3C 中 SOAP 相关的所有活动。 <br />WSDL：Web 服务描述语言（Web Services Description Language）是一个描述 Web 服务的 XML 词汇表。编写一段接收 WSDL 文档然后调用其以</div>
		<div>前从未用过的 Web 服务的代码，这是可能的。WSDL 文件中的信息定义 Web 服务的名称、它的方法的名称、这些方法的参数和其它详细信息。您</div>
		<div>可以在 w3.org/TR/wsdl（结尾没有斜杠符号）找到最新的 WSDL 规范。 <br />UDDI：统一描述、发现和集成（Universal Description, Discovery, and Integration）协议向 Web 服务注册中心定义 SOAP 接口。如果您有</div>
		<div>一段代码希望作为 Web 服务部署，UDDI 规范定义如何将您的服务描述添加至注册中心。如果您在寻找一段提供某种功能的代码，UDDI 规范定义</div>
		<div>如何查询注册中心以找到您想要的信息。有关 UDDI 的所有资料来源都可以在 <a href="http://www.uddi.org/"><font color="#ffffff">www.uddi.org</font></a> 找到。 </div>
		<div>其它标准<br />还有许多其它的 XML 标准，我没有在这里深入介绍。除了象可伸缩向量图（Scalable Vector Graphic）（<a href="http://www.w3.org/TR/SVG/"><font color="#ffffff">www.w3.org/TR/SVG/</font></a>）、SMIL（同步</div>
		<div>多媒体集成语言，Synchronized Multimedia Integration Language）（<a href="http://www.w3.org/TR/smil20/"><font color="#ffffff">www.w3.org/TR/smil20/</font></a>）那样可广泛应用的标准外，还有许多特定于业</div>
		<div>界的标准。例如，HR-XML 协会已定义了许多用于人力资源的 XML 标准；您可以在 <a href="http://www.hr-xml.org/"><font color="#ffffff">www.hr-xml.org</font></a> 找到那些标准。</div>
		<div>最后，要查找有关 XML 标准的优秀信息来源，请访问 xml.org/xml/registry.jsp 上的 XML 资源库。该站点的特点是有数百个用于各行各业的</div>
		<div>标准。</div>
		<div>现实世界示例<br />到目前为止，我希望您相信 XML 具有能使电子商务的运行方式发生革命性变化的极大潜力。尽管潜力是巨大的，但真正重要的是市场中的实际结</div>
		<div>果。本章描述了三个案例研究，案例中的组织使用了 XML 来简化其业务过程并改进其结果。</div>
		<div>这里讨论的所有案例研究都来自 IBM 的 jStart 计划。jStart 团队的任务是帮助客户使用新技术来解决问题。当客户同意 jStart 约定时，他</div>
		<div>会以一定的折扣得到 IBM 咨询和开发服务，客户将被明确告之由此产生的项目将会被作为案例研究使用。如果您想看到更多案例研究，包括涉及 </div>
		<div>Web 服务和其它新技术的案例研究，请通过 ibm.com/software/jstart 访问 jStart Web 页面。</div>
		<div>请注意，jStart 团队不再从事 XML 项目的工作；小组当前的工作重点是从事 Web 服务。Web 服务以专门的方式使用 XML，通常是通过前面Web </div>
		<div>服务中提到的 SOAP、WSDL 和 UDDI 标准来使用 XML。 </div>
		<div>
				<br />用 XML 生成多个用户界面<br />除了 HTML 界面以外，还规划了 Java 客户机界面和 B2B 电子界面。针对所有这些界面，将结构化的 XML 数据转换成适当的结构和文档。该服</div>
		<div>务首次公开展示时允许一个业务伙伴 — 加拿大证券注册系统（Canadian Securities Registration Systems）使用安全套接字层（SSL）提交 </div>
		<div>XML 事务数据。然后将该 XML 事务数据转换成用于后端事务的适当格式。</div>
		<div>最终结果是马尼托巴省能够创建一个灵活的新应用程序，并且他们的最终用户可以更方便更快捷地访问财产注册中心。因为该省使用 XML 作为数</div>
		<div>据格式，所以政府 IT 团队在设计新界面和新访问方法时有极大的灵活性。最棒的是，根本不必更改后端系统。</div>
		<div>第一联合银行（First Union）使用 XML<br />第一联合银行（美国最大的银行之一）正在使用 Java 和 XML 重新设计它的许多应用程序。和大多数大公司一样，它有一个异构环境，有 </div>
		<div>OS/390、AIX、Solaris、HP/9000 以及 Windows NT 服务器和 Windows NT、Windows 98、Solaris 和 AIX 客户机。在这种环境下，第一联合银</div>
		<div>行选择 Java 作为独立于平台的代码，选择 XML 作为独立于平台的数据。</div>
		<div>用 Web 服务来帮忙！<br />为了解决这些问题，Hewitt 和 jStart 团队共同努力构建 Web 服务来满足 Hewitt 客户的需要。Web 服务是一种以许多有趣方式使用 XML 的新</div>
		<div>型应用程序：</div>
		<div>首先，Web 服务通常使用 SOAP，这是一个用于将 XML 数据从一处移至另一处的 XML 标准。 <br />其次，Web 服务提供的接口（方法名称、参数和数据类型等）是用 XML 描述的。 <br />再次，Web 服务的描述可以存储在 UDDI 注册中心，或从注册中心检索；所有进出该注册中心的信息都格式化为 XML。 <br />最后，Web 服务提供的数据本身就是 XML 数据。 <br />Hewitt 已经开发出两个应用程序，它们都证明了自己以更灵活的方式传递数据的能力：</div>
		<div>使用 Secure Participant Mailbox，经授权的用户可以请求包含关于退休和其它员工福利的个性化信息的报告。 <br />使用 Retirement Access B2B Connection，经授权的用户可以获得客户的 401(k) 财务信息的详细情况。 <br />这些应用程序都从现有的旧系统检索数据，使用 XML 格式化数据，然后在 Web 上传递格式化的信息。因为这些应用程序构建于开放标准之上，</div>
		<div>所以 Hewitt 可以快速地完成它们的开发。最妙的是，这些应用程序的灵活性使 Hewitt 从其竞争对手中脱颖而出。</div>
		<div>“我们把 Web 服务看作一种工具，它通过无所不在的数据网络，对我们参与者的业务服务和数据提供一种开放、非专有的访问。”Hewitt 首席</div>
		<div>技术决策专家 Tim Hilgenberg 这样说道。最终结果是：Hewitt 用较低的成本较快地开发出更灵活的应用程序，客户们能够更好地访问他们的数</div>
		<div>据，并且不必更改 Hewitt 现有的旧应用程序。</div>
		<div>案例研究总结<br />在所有这些案例研究中，各公司都使用 XML 来创建独立于系统的数据格式。XML 文档可以表示那些可以从一个系统或过程移到另一个的结构化数</div>
		<div>据。当前端和后端应用程序更改时，XML 可以在它们之间移动而保持不变。更妙的是，当越来越多的前端和后端应用程序添加进来时，XML 的使</div>
		<div>用将现有应用程序与任何更改都隔离起来。当 Web 服务变得越来越普遍时，XML 还将用来传输数据。</div>
		<div>有关这些案例研究的更多信息，请通过 <a href="mailto:thompsam@us.ibm.com"><font color="#ffffff">thompsam@us.ibm.com</font></a> 与 IBM 的 Sam Thompson 联系。您可以在 <a href="http://www.gov.mb.ca/"><font color="#ffffff">www.gov.mb.ca</font></a> 找到有关马尼托巴省的</div>
		<div>更多信息，第一联合银行的网站是 <a href="http://www.firstunion.com/"><font color="#ffffff">http://www.firstunion.com</font></a>，Hewitt Associates 的网站是 <a href="http://www.hewitt.com/"><font color="#ffffff">http://www.hewitt.com</font></a>。</div>
		<div>建议和参考资料<br />行动起来！<br />此时此刻，我希望您已经相信 XML 是移动和操作结构化数据的最佳方法。如果您现在还没有使用 XML，您该如何开始呢？下面是一些建议：</div>
		<div>确定您要将什么数据转换成 XML。通常这是需要从一个系统移到另一个系统的数据，或必须转换成不同格式的数据。 <br />了解是否有现有的 XML 标准。如果您正在研究很常见的数据，例如采购订单、医疗记录或股票报价，则很可能已经有人为那些数据定义了 XML </div>
		<div>标准。 <br />了解您现有的工具是否支持 XML。如果您正在使用数据库软件包、电子表格或其它数据管理工具的最新版本，则您的现有工具（或其升级版本）</div>
		<div>很可能可以使用 XML 作为输入或输出格式。 <br />学习如何构建基于 XML 的应用程序。您需要理解您的数据现在是如何存储的，需要如何转换它，以及如何将您的 XML 开发工作与现有的应用程</div>
		<div>序集成起来。Benoît Marchal 的 Working XML 专栏是开始的好地方；您可以在 <a href="http://www-106.ibm.com/developerworks/xml/library/x"><font color="#ffffff">http://www-106.ibm.com/developerworks/xml/library/x</font></a>-</div>
		<div>wxxmcol/ 找到他所有专栏文章的最新列表。 <br />加入适当的标准组织。考虑加入象万维网协会（W3C）这样的组织，以及象 HR-XML.org 这样特定于业界的组织。成为这些组织的成员将有助于您</div>
		<div>跟踪业界中所发生的事件，而且使您有机会塑造 XML 标准的未来。 <br />避免专有产品的诡计。在开发工作中仅使用基于标准的技术很重要；抵制为您提供所谓改进的供应商的诱惑。XML 的优点之一是您对数据有完全</div>
		<div>的控制权。一旦它受到某个专有数据格式的限制，您就失去了极大的控制权。 <br />联系 jStart 团队。如果您认为您的企业可以使用 jStart 约定模型，请与该团队联系以了解您可能得到什么服务？ <br />关注 developerWorks。我们的 XML 专区有涉及各种 XML 主题的数千页内容，包括 DTD 和模式开发、XML 编程和创建 XSLT 样式表。 </div>
		<div>
				<br />参考资料<br />下面是一些可以帮助您开始的参考资料：</div>
		<div>dW XML 专区是 XML 参考资料的“一站式商店”。请参阅 www-106.ibm.com/developerworks/xml 以获取您一直希望了解的有关 XML 的内容。</div>
		<div>XML 工具： developerWorks 有一个系列的“Fill your XML toolbox”文章，它们描述用于各种语言的 XML 编程工具：</div>
		<div>C/C++：请在 www-106.ibm.com/developerworks/library/x-ctlbx.html（developerWorks，2001 年 9 月）参阅 Rick Parrish 的文章。 <br />Java：请在 www-106.ibm.com/developerworks/library/java-xml-toolkit/index.html（developerWorks，2000 年 5 月）参阅 Doug Tidwell </div>
		<div>的文章。 <br />Perl：请在 www-106.ibm.com/developerworks/library/perl-xml-toolkit/index.html（developerWorks，2001 年 6 月）参阅 Parand Tony </div>
		<div>Darugar 的文章。 <br />PHP：请在 www-106.ibm.com/developerworks/library/php-xml-toolkit.html（developerWorks，2000 年 6 月）参阅 Craig Knudsen 的文章</div>
		<div>。 <br />除了这些文章以外，请在 www-106.ibm.com/developerworks/library/l-pxml.html 参阅 David Mertz 在其“Charming Python: Revisiting </div>
		<div>XML tools for Python”文章中对 Python XML 工具的评论。</div>
		<div>XML 教程：可在 developerWorks 获得数十篇有关 XML 主题的教程；请参阅 <a href="http://www-105.ibm.com/de"><font color="#ffffff">http://www-105.ibm.com/de</font></a></div>
		<div>veloperworks/education.nsf/dw/xml-onlinecourse-bytitle 以获得最新的列表。</div>
		<div>IBM 的 jStart 团队：jStart 团队使用新技术（例如 XML Web 服务）以非常低的成本帮助客户构建解决方案。作为回报，那些客户同意让 IBM </div>
		<div>将他们的项目作为案例研究公布。要了解更多信息，请参阅 ibm.com/software/jstart。</div>
		<div>XML 标准：下面是本教程中提到的所有 XML 标准的字母顺序列表。</div>
		<div>DOM，文档对象模型：<br />核心规范： w3.org/TR/DOM-Level-2-Core/ <br />事件规范： w3.org/TR/DOM-Level-2-Events/ <br />样式规范： w3.org/TR/DOM-Level-2-Style/ <br />遍历和范围规范： w3.org/TR/DOM-Level-2-Traversal-Range/ <br />视图规范： w3.org/TR/DOM-Level-2-Views/ <br />HR-XML.org，人力资源 XML 协会（Human Resources XML Consortium）：hr-xml.org <br />JAXP，用于 XML 解析的 Java API（Java API for XML Parsing）：java.sun.com/xml/jaxp/ <br />JDOM，不代表任何缩写形式：jdom.org/ <br />SAX，用于 XML 的简单 API（Simple API for XML）：saxproject.org/ <br />SMIL，同步多媒体集成语言（Synchronized Multimedia Integration Language）：<a href="http://www.w3.org/TR/smil20/"><font color="#ffffff">www.w3.org/TR/smil20/</font></a><br />SOAP，过去用于代表简单对象访问协议（Simple Object Access Protocol），但现在正式不代表任何缩写形式：w3.org/TR/SOAP/ <br />SVG，可伸缩向量图（Scalable Vector Graphics）：<a href="http://www.w3.org/TR/SVG/"><font color="#ffffff">www.w3.org/TR/SVG/</font></a><br />UDDI，统一描述、发现和集成协议（Universal Description, Discovery, and Integration Protocol）：uddi.org <br />WSDL，Web 服务描述语言（Web Services Description Language）：w3.org/TR/wsdl（结尾没有斜杠符号） <br />XLink，XML 链接语言（XML Linking Language）：w3.org/TR/xlink/ <br />XML，最基础的标准：w3.org/TR/REC-xml <br />XML 数字签名（XML Digital Signature）：w3.org/TR/xmldsig-core/ <br />XML 加密（XML Encryption）：w3.org/TR/xmlenc-core/ <br />XML 名称空间（XML Namespaces）：w3.org/TR/REC-xml-names/ <br />DTD 和模式的 XML 资源库（XML Repository）：xml.org/xml/registry.jsp <br />XML Schema：<br />第 0 部分 — 入门：w3.org/TR/xmlschema-0 <br />第 1 部分 — 文档结构：w3.org/TR/xmlschema-1 <br />第 2 部分 — 数据类型：w3.org/TR/xmlschema-2 <br />XPath，XML 路径语言（XML Path Language）：w3.org/TR/xpath（结尾没有斜杠符号） <br />XPointer，XML 指针语言（XML Pointer Language）：<a href="http://www.w3.org/TR/xptr/"><font color="#ffffff">www.w3.org/TR/xptr/</font></a><br />XSL-FO，用于格式化对象的可扩展样式表语言（Extensible Stylesheet Language for Formatting Objects）：w3.org/TR/xsl/ <br />XSLT，可扩展样式表语言（Extensible Stylesheet Language）：w3.org/TR/xslt（结尾没有斜杠符号） <br />有关 JDOM 的更多信息，请参阅以下 developerWorks 文章：</div>
		<div>Simplify XML programming with JDOM（developerWorks，2001 年 5 月，<a href="http://www.ibm.com/developerWorks/cn/java/j-jdom/index.shtml"><font color="#ffffff">http://www.ibm.com/developerWorks/cn/java/j-jdom/index.shtml</font></a></div>
		<div>） <br />Converting from DOM（developerWorks，2001 年 4 月，<a href="http://www.ibm.com/developerWorks/cn/xml/tips/x-tipcdm/index.shtml"><font color="#ffffff">http://www.ibm.com/developerWorks/cn/xml/tips/x-tipcdm/index.shtml</font></a>） <br />Converting from SAX（developerWorks，2001 年 4 月，<a href="http://www.ibm.com/developerWorks/cn/xml/tips/x-tipcsx/index.shtml"><font color="#ffffff">http://www.ibm.com/developerWorks/cn/xml/tips/x-tipcsx/index.shtml</font></a>） <br />Using JDOM and XSLT（developerWorks，2001 年 3 月，<a href="http://www.ibm.com/developerWorks/cn/xml/tips/x-tipjdom/index.shtml"><font color="#ffffff">http://www.ibm.com/developerWorks/cn/xml/tips/x-tipjdom/index.shtml</font></a>） </div>
<img src ="http://www.blogjava.net/fortune/aggbug/75414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-10-16 14:52 <a href="http://www.blogjava.net/fortune/archive/2006/10/16/75414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>连接数据库出现错误的原因</title><link>http://www.blogjava.net/fortune/archive/2006/06/06/50808.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Tue, 06 Jun 2006 08:43:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/06/06/50808.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/50808.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/06/06/50808.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/50808.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/50808.html</trackback:ping><description><![CDATA[
		<strong>问：服务器拒绝访问，telnet 1433 失败的问题。</strong>从来没遇到过这种问题，在客户的一台机上装了我公司的软件和Sql server ，运行时居然出现服务器不存在或拒绝访问。客户的操作系统是xp,我给他装了sql server 的个人版。
<p>　　程序是绝对没问题的，因为已被很多其他客户使用。后面我检查了一下 ping 服务器，ping ip 都可以ping 通，也可以打开查询分析器。</p><p>　　但就是应用程序访问不了，后面我用 telnet 主机 1433 和　telnet IP 1433　测试，居然失败，估计是1433端口的问题</p><p>　　我在服务器端网络实用工具作了设置winsock代理1433端口和tcpip默认端口还是不行，在客户端网络实用工具作了设置别名，还是不行。调了好久，还是没能成功，是不是因为windos　有其他设置或防火墙的设置(客户是用adsl上网的，没装其他防火墙)不能访问1433端口的。</p><p> </p><p> </p><p>　　答：第一步，先确定你的情况是否符合这篇文章的描述：<br /><strong>                                                                  <br />                                                            《SQL Server连接中常见的错误》<br /></strong><br />SQL Server连接中的四个最常见错误:</p><p><strong>　　一."SQL Server 不存在或访问被拒绝"</strong></p><p><strong>　　这个是最复杂的,错误发生的原因比较多,需要检查的方面也比较多.</strong></p><p><strong>　　一般说来,有以下几种可能性:</strong></p><p><strong>　　1,SQL Server名称或IP地址拼写有误</strong></p><p><strong>　　2,服务器端网络配置有误</strong></p><p><strong>　　3,客户端网络配置有误</strong></p><p><strong>　　要解决这个问题,我们一般要遵循以下的步骤来一步步找出导致错误的原因.</strong></p><p><strong>　　============= 首先,检查网络物理连接 =============</strong></p><p><strong>　　ping &lt;服务器IP地址/服务器名称&gt;</strong></p><p><strong>　　如果 ping &lt;服务器IP地址&gt; 不成功,说明物理连接有问题,这时候要检查硬件设备,如网卡,HUB,路由器等.</strong></p><p><strong>　　还有一种可能是由于客户端和服务器之间安装有防火墙软件造成的,比如 ISA Server.防火墙软件可能会屏蔽对 ping,telnet 等的响应</strong></p><p><strong>　　因此在检查连接问题的时候,我们要先把防火墙软件暂时关闭,或者打开所有被封闭的端口.</strong></p><p><strong>　　如果ping &lt;服务器IP地址&gt; 成功而,ping &lt;服务器名称&gt; 失败</strong></p><p><strong>　　则说明名字解析有问题,这时候要检查 DNS 服务是否正常.</strong></p><p><strong>　　有时候客户端和服务器不在同一个局域网里面,这时候很可能无法直接使用服务器名称来标识该服务器,这时候我们可以使用HOSTS文件来进行名字解析,</strong></p><p><strong>　　具体的方法是:</strong></p><p><strong>　　1.使用记事本打开HOSTS文件(一般情况下位于C:\WINNT\system32\drivers\etc).</strong></p><p><strong>　　添加一条IP地址与服务器名称的对应记录,如:</strong></p><p><strong>　　172.168.10.24 myserver</strong></p><p><strong>　　2.或在 SQL Server 的客户端网络实用工具里面进行配置,后面会有详细说明.</strong></p><p><strong>　　============= 其次,使用 telnet 命令检查SQL Server服务器工作状态 =============</strong></p><p><strong>　　telnet &lt;服务器IP地址&gt; 1433</strong></p><p><strong>　　如果命令执行成功,可以看到屏幕一闪之后光标在左上角不停闪动,这说明 SQL Server 服务器工作正常,并且正在监听1433端口的 TCP/IP 连接</strong></p><p><strong>　　如果命令返回"无法打开连接"的错误信息,则说明服务器端没有启动 SQL Server 服务,</strong></p><p><strong>　　也可能服务器端没启用 TCP/IP 协议,或者服务器端没有在 SQL Server 默认的端口1433上监听.</strong></p><p><strong>　　=============接着,我们要到服务器上检查服务器端的网络配置,检查是否启用了命名管道.是否启用了 TCP/IP 协议等等 =============</strong></p><p><strong>　　可以利用 SQL Server 自带的服务器网络使用工具来进行检查.</strong></p><p><strong>　　点击:程序 -- Microsoft SQL Server -- 服务器网络使用工具</strong></p><p><strong>　　打开该工具后,在"常规"中可以看到服务器启用了哪些协议.</strong></p><p><strong>　　一般而言,我们启用命名管道以及 TCP/IP 协议.</strong></p><p><strong>　　点中 TCP/IP 协议,选择"属性",我们可以来检查 SQK Server 服务默认端口的设置</strong></p><p><strong>　　一般而言,我们使用 SQL Server 默认的1433端口.如果选中"隐藏服务器",则意味着客户端无法通过枚举服务器来看到这台服务器,起到了保护的作用,但不影响连接.</strong></p><p><strong>　　============= 接下来我们要到客户端检查客户端的网络配置 =============</strong></p><p><strong>　　我们同样可以利用 SQL Server 自带的客户端网络使用工具来进行检查,</strong></p><p><strong>　　所不同的是这次是在客户端来运行这个工具.</strong></p><p><strong>　　点击:程序 -- Microsoft SQL Server -- 客户端网络使用工具</strong></p><p><strong>　　打开该工具后,在"常规"项中,可以看到客户端启用了哪些协议.</strong></p><p><strong>　　一般而言,我们同样需要启用命名管道以及 TCP/IP 协议.</strong></p><p><strong>　　点击 TCP/IP 协议,选择"属性",可以检查客户端默认连接端口的设置,该端口必须与服务器一致.</strong></p><p><strong>　　单击"别名"选项卡,还可以为服务器配置别名.服务器的别名是用来连接的名称,</strong></p><p><strong>　　连接参数中的服务器是真正的服务器名称,两者可以相同或不同.别名的设置与使用HOSTS文件有相似之处.</strong></p><p><strong>　　通过以上几个方面的检查,基本上可以排除第一种错误.</strong></p><p><strong>　　-----------------------------------------------------------------------------</strong></p><p><strong>　　二."无法连接到服务器,用户xxx登陆失败"</strong></p><p><strong>　　该错误产生的原因是由于SQL Server使用了"仅 Windows"的身份验证方式,</strong></p><p><strong>　　因此用户无法使用SQL Server的登录帐户(如 sa )进行连接.解决方法如下所示:</strong></p><p><strong>　　1.在服务器端使用企业管理器,并且选择"使用 Windows 身份验证"连接上 SQL Server</strong></p><p><strong>　　操作步骤:</strong></p><p><strong>　　在企业管理器中</strong></p><p><strong>　　--右键你的服务器实例(就是那个有绿色图标的)</strong></p><p><strong>　　--编辑SQL Server注册属性</strong></p><p><strong>　　--选择"使用windows身份验证"</strong></p><p><strong>　　--选择"使用SQL Server身份验证"</strong></p><p><strong>　　--登录名输入:sa,密码输入sa的密码</strong></p><p><strong>　　--确定</strong></p><p><strong>　　2.设置允许SQL Server身份登录</strong></p><p><strong>　　操作步骤:</strong></p><p><strong>　　在企业管理器中</strong></p><p><strong>　　--展开"SQL Server组",鼠标右键点击SQL Server服务器的名称</strong></p><p><strong>　　--选择"属性"</strong></p><p><strong>　　--再选择"安全性"选项卡</strong></p><p><strong>　　--在"身份验证"下,选择"SQL Server和 Windows ".</strong></p><p><strong>　　--确定,并重新启动SQL Server服务.</strong></p><p><strong>　　在以上解决方法中,如果在第 1 步中使用"使用 Windows 身份验证"连接 SQL Server 失败,</strong></p><p><strong>　　那就通过修改注册表来解决此问题:</strong></p><p><strong>　　1.点击"开始"-"运行",输入regedit,回车进入注册表编辑器</strong></p><p><strong>　　2.依次展开注册表项,浏览到以下注册表键:</strong></p><p><strong>　　[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer]</strong></p><p><strong>　　3.在屏幕右方找到名称"LoginMode",双击编辑双字节值</strong></p><p><strong>　　4.将原值从1改为2,点击"确定"</strong></p><p><strong>　　5.关闭注册表编辑器</strong></p><p><strong>　　6.重新启动SQL Server服务.</strong></p><p><strong>　　此时,用户可以成功地使用sa在企业管理器中新建SQL Server注册,</strong></p><p><strong>　　但是仍然无法使用Windows身份验证模式来连接SQL Server.</strong></p><p><strong>　　这是因为在 SQL Server 中有两个缺省的登录帐户:</strong></p><p><strong>　　BUILTIN\Administrators</strong></p><p><strong>　　&lt;机器名&gt;\Administrator 被删除.</strong></p><p><strong>　　要恢复这两个帐户,可以使用以下的方法:</strong></p><p><strong>　　1.打开企业管理器,展开服务器组,然后展开服务器</strong></p><p><strong>　　2.展开"安全性",右击"登录",然后单击"新建登录"</strong></p><p><strong>　　3.在"名称"框中,输入 BUILTIN\Administrators</strong></p><p><strong>　　4.在"服务器角色"选项卡中,选择"System Administrators"</strong></p><p><strong>　　5.点击"确定"退出</strong></p><p><strong>　　6.使用同样方法添加 &lt;机器名&gt;\Administrator 登录.</strong></p><p><strong>　　说明:</strong></p><p><strong>　　以下注册表键:</strong></p><p><strong>　　HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\LoginMode</strong></p><p><strong>　　的值决定了SQL Server将采取何种身份验证模式.</strong></p><p><strong>　　1.表示使用"Windows 身份验证"模式</strong></p><p><strong>　　2.表示使用混合模式(Windows 身份验证和 SQL Server 身份验证).</strong></p><p><strong>　　-----------------------------------------------------------------------------</strong></p><p><strong>　　三.提示连接超时</strong></p><p><strong>　　如果遇到第三个错误,一般而言表示客户端已经找到了这台服务器,并且可以进行连接,</strong></p><p><strong>　　不过是由于连接的时间大于允许的时间而导致出错.</strong></p><p><strong>　　这种情况一般会发生在当用户在Internet上运行企业管理器来注册另外一台同样在Internet上的服务器,</strong></p><p><strong>　　并且是慢速连接时,有可能会导致以上的超时错误.有些情况下,由于局域网的网络问题,也会导致这样的错误.</strong></p><p><strong>　　要解决这样的错误,可以修改客户端的连接超时设置.</strong></p><p><strong>　　默认情况下,通过企业管理器注册另外一台SQL Server的超时设置是 4 秒,</strong></p><p><strong>　　而查询分析器是 15 秒(这也是为什么在企业管理器里发生错误的可能性比较大的原因).</strong></p><p><strong>　　具体步骤为:</strong></p><p><strong>　　企业管理器中的设置:</strong></p><p><strong>　　1.在企业管理器中,选择菜单上的"工具",再选择"选项"</strong></p><p><strong>　　2.在弹出的"SQL Server企业管理器属性"窗口中,点击"高级"选项卡</strong></p><p><strong>　　3.在"连接设置"下的"登录超时(秒)"右边的框中输入一个比较大的数字,如 20.</strong></p><p><strong>　　查询分析器中的设置:</strong></p><p><strong>　　工具 -- 选项 -- 连接 -- 将登录超时设置为一个较大的数字</strong></p><p><strong>　　---------------------------------------------------------------------------------</strong></p><p><strong>　　四.大部分机都用Tcp/ip才能成功，有次我发现用Named Pipes才可以?</strong></p><p><strong>　　回复人: leimin(黄山光明顶)</strong></p><p><strong>　　这是因为在WINDOWS 2000以后的操作系统中，MS为解决SQL SERVER的安全问题将TCP/IP配置</strong></p><p><strong>　　为SQLSERVER的默认连接协议，你可以在CLIENT NETWORK UTILITY中看到TCP/IP和NAME PIPE</strong></p><p><strong>　　的顺序。</strong></p><p><strong>　　你也可以在:</strong></p><p><strong>　　[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\SuperSocketNetLib]</strong></p><p><strong>　　"ProtocolOrder"=hex(7):74,00,63,00,70,00,00,00,00,00</strong></p><p><strong>　　看到默认的协议。</strong></p><p><strong>　　2.怎么在程序中更改Named Pipes ， Tcp/ip ，其sql语句怎么写?</strong></p><p><strong>　　你可以在上面提到的注册表的位置修改:</strong></p><p><strong>　　CLIENT端:</strong></p><p><strong>　　[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\SuperSocketNetLib]</strong></p><p><strong>　　"ProtocolOrder"=hex(7):74,00,63,00,70,00,00,00,00,00</strong></p><p><strong>　　SERVER端:</strong></p><p><strong>　　[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib]</strong></p><p><strong>　　"ProtocolOrder"=hex(7):74,00,63,00,70,00,00,00,00,00</strong></p><p><br /><br /><br /> </p><p><strong>      </strong>第二步，如果是远程方面的问题，请参看这篇文章：<br /><br /><strong>                                                            《远程连接sql server 服务器的解决方案》<br /><br /></strong>远程连接sql server 2000服务器的解决方案</p><p><strong>　　一 看ping 服务器IP能否ping通。</strong></p><p><strong>　　这个实际上是看和远程sql server 2000服务器的物理连接是否存在。如果不行，请检查网络，查看配置，当然得确保远程sql server 2000服务器的IP拼写正确。</strong></p><p><strong>　　二 在Dos或命令行下输入telnet 服务器IP 端口，看能否连通。</strong></p><p><strong>　　如telnet 202.114.100.100 1433</strong></p><p><strong>　　通常端口值是1433，因为1433是sql server 2000的对于Tcp/IP的默认侦听端口。如果有问题，通常这一步会出问题。通常的提示是“……无法打开连接,连接失败"。</strong></p><p><strong>　　如果这一步有问题，应该检查以下选项。</strong></p><p><strong>　　1 检查远程服务器是否启动了sql server 2000服务。如果没有，则启动。</strong></p><p><strong>　　2 检查服务器端有没启用Tcp/IP协议，因为远程连接(通过因特网)需要靠这个协议。检查方法是，在服务器上打开 开始菜单-&gt;程序-&gt;Microsoft SQL Server-&gt;服务器网络实用工具，看启用的协议里是否有tcp/ip协议，如果没有，则启用它。</strong></p><p><strong>　　3 检查服务器的tcp/ip端口是否配置为1433端口。仍然在服务器网络实用工具里查看启用协议里面的tcp/ip的属性，确保默认端口为1433，并且隐藏服务器复选框没有勾上。</strong></p><p><strong>　　事实上，如果默认端口被修改，也是可以的，但是在客户端做telnet测试时，写服务器端口号时必须与服务器配置的端口号保持一致。如果隐藏服务器复选框被勾选，则意味着客户端无法通过枚举服务器来看到这台服务器，起到了保护的作用，但不影响连接，但是Tcp/ip协议的默认端口将被隐式修改为2433，在客户端连接时必须作相应的改变。</strong></p><p><strong>　　4 如果服务器端操作系统打过sp2补丁，则要对windows防火墙作一定的配置，要对它开放1433端口，通常在测试时可以直接关掉windows防火墙(其他的防火墙也关掉最好)。</strong></p><p><strong>　　5 检查服务器是否在1433端口侦听。如果服务器没有在tcp连接的1433端口侦听，则是连接不上的。检查方法是在服务器的dos或命令行下面输入</strong></p><p><strong>　　netstat -a -n 或者是netstat -an，在结果列表里看是否有类似 tcp 127.0.0.1 1433 listening 的项。如果没有，则通常需要给sql server 2000打上至少sp3的补丁。其实在服务器端启动查询分析器，输入 select @@version 执行后可以看到版本号，版本号在8.0.2039以下的都需要打补丁。</strong></p><p><strong>　　如果以上都没问题，这时你再做telnet 服务器ip 1433 测试，将会看到屏幕一闪之后光标在左上角不停闪动。恭喜你，你马上可以开始在企业管理器或查询分析器连接了。</strong></p><p><strong>　　三 检查客户端设置</strong></p><p><strong>　　程序-&gt;Microsoft SQL Server -&gt; 客户端网络使用工具。像在服务器网络实用工具里一样，确保客户端tcp/ip协议启用，并且默认端口为1433(或其他端口，与服务器端保持一致就行)。</strong></p><p><strong>　　四 在企业管理器里或查询那分析器连接测试</strong></p><p><strong>　　企业管理器-&gt;右键SQlserver组-&gt;新建sqlserver注册-&gt;下一步-&gt;写入远程IP-&gt;下一步-&gt;选Sqlserver登陆-&gt;下一步-&gt;写入登陆名与密码(sa,password)-&gt;下一步-&gt;下一步-&gt;完成</strong></p><p><strong>　　查询分析器-&gt;文件-&gt;连接-&gt;写入远程IP-&gt;写入登录名和密码(sa,password)-&gt;确定</strong></p><p><strong>　　通常建议在查询分析器里做，因为默认情况下，通过企业管理器注册另外一台SQL Server的超时设置是4秒，而查询分析器是15秒。</strong></p><p><strong>　　修改默认连接超时的方法:</strong></p><p><strong>　　企业管理器-&gt;工具-&gt;选项-&gt;在弹出的"SQL Server企业管理器属性"窗口中，点击"高级"选项卡-&gt;连接设置-&gt;在 登录超时(秒) 后面的框里输入一个较大的数字</strong></p><p><strong>　　查询分析器-&gt;工具-&gt;选项-&gt;连接-&gt;在 登录超时(秒) 后面的框里输入一个较大的数字</strong></p><p><strong>　　通常就可以连通了，如果提示错误，则进入下一步。</strong></p><p><strong>　　五 错误产生的原因通常是由于SQL Server使用了"仅 Windows"的身份验证方式，因此用户无法使用SQL Server的登录帐户(如 sa )进行连接。解决方法如下所示:</strong></p><p><strong>　　1 在服务器端使用企业管理器，并且选择"使用 Windows 身份验证"连接上 SQL Server。</strong></p><p><strong>　　2 展开"SQL Server组"，鼠标右键点击SQL Server服务器的名称，选择"属性"，再选择"安全性"选项卡。</strong></p><p><strong>　　3 在"身份验证"下，选择"SQL Server和 Windows "。</strong></p><p><strong>　　4 重新启动SQL Server服务。(在dos或命令行下面net stop mssqlserver停止服务，net start mssqlserver启动服务，也是一种快捷的方法)。</strong></p><p><strong>　　附注:在连接本地服务器时，通常使用的是命名管道协议(在服务器网络实用工具里可以看到启用的协议有这个)，默认端口是445，因此在本地能连通是不能说明什么问题的，连接远程服务器是完全不同的协议)</strong></p><p><br /> </p><p>      第三步：如果上述方法仍不能解决你的问题，请检查你的SQL有没有打补丁,没有的话要打上补丁,检查的方法是在查询分析器中运行:</p><p>　　select @@version</p><p>　　如果出来的版本号是8.00.2039以下,则表明你未安装sp4的补丁,要装上.</p><p>　　SQL补丁下载:</p><p>　　全部补丁的位置(在下载页的中间部分,可以选择语言,以下载和sql server实例语言对应的补丁)</p><p>　　http://www.microsoft.com/downloads/details.aspx?FamilyId=8E2DFC8D-C20E-4446-99A9-B7F0213F8BC5&amp;displaylang=zh-cn</p><p>　　应该安装的是</p><p>　　http://download.microsoft.com/download/9/b/f/9bff6646-2cdb-4069-ada0-548be9cb9338/SQL2000-KB884525-SP4-x86-CHS.EXE</p><p>　　注意下载后,执行的时候是解压,要在解压后的目录中执行setup.bat才是真正的安装</p><p>　　如果你的操作系统是xp,那么在安装xp sp2后,不管以前是否安装过sql sp4,都要再安装一次,并且在防火墙中开启1433端口,否则无法被其他电脑访问.</p><img src ="http://www.blogjava.net/fortune/aggbug/50808.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-06-06 16:43 <a href="http://www.blogjava.net/fortune/archive/2006/06/06/50808.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何使用links方式安装Eclipse插件</title><link>http://www.blogjava.net/fortune/archive/2006/05/04/44550.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Thu, 04 May 2006 11:10:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/05/04/44550.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/44550.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/05/04/44550.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/44550.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/44550.html</trackback:ping><description><![CDATA[　eclispe想必大家都很熟悉了，一般来说，eclipse插件都是安装在plugins目录下。不过这样一来，当安装了许多插件之后，eclipse变的很大，最主要的是不便于更新和管理众多插件。用links方式安装eclipse插件，可以解决这个问题。<br />　　<br />　　<b>当前配置XP SP1，eclipse3.0.1</b><br />　　<br />　　现在假设我的eclipse安装目录是D:\eclipse，待安装插件目录是D:\plug-in ，我将要安装LanguagePackFeature（语言包）、emf-sdo-xsd-SDK、GEF-SDK、Lomboz这四个插件。<br />　　<br />　　先把这四个插件程序全部放在D:\plug-in目录里，分别解压。如Lomboz3.0.1.zip解压成Lomboz3.0.1目录，这个目录包含一个plugins目录，要先在Lomboz3.0.1目录中新建一个子目录eclipse，然后把plugins目录移动到刚建立的eclipse目录中，即目录结构要是这样的：D:\plug-in\Lomboz3.0.1\eclipse\plugins<br />　　<br />　　Eclipse 将会到指定的目录下去查找 eclipse\features 目录和eclipse\plugins 目录，看是否有合法的功能部件和（或）插件。也就是说，目标目录必须包含一个 \eclipse 目录。如果找到，附加的功能部件和插件在运行期配置是将是可用的，如果链接文件是在工作区创建之后添加的，附加的功能部件和插件会作为新的配置变更来处理。<br />　　<br />　　其它压缩文件解压后若已经包含eclipse\plugins目录，则不需要建立eclipse目录。<br />　　<br />　　然后在 eclipse安装目录D:\eclipse目录中建立一个子目录links，在links目录中建立一个link文件，比如 LanguagePackFeature.link，改文件内容为　path=D:/plug-in/LanguagePackFeature　即这个link文件要对应一个刚解压后的插件目录。<br />　　<br />　　<b>说明：</b><br />　　<br />　　1. 插件可以分别安装在多个自定义的目录中。<br />　　<br />　　2. 一个自定义目录可以安装多个插件。<br />　　<br />　　3. link文件的文件名及扩展名可以取任意名称，比如ddd.txt，myplugin都可以。<br />　　<br />　　4. link文件中path=插件目录的path路径分隔要用\\或是/<br />　　<br />　　5. 在links目录也可以有多个link文件，每个link文件中的path参数都将生效。<br />　　<br />　　6. 插件目录可以使用相对路径。<br />　　<br />　　7. 可以在links目录中建立一个子目录，转移暂时不用的插件到此子目录中，加快eclipse启动。<br />　　<br />　　8.　如果安装后看不到插件，把eclipse 目录下的configuration目录删除，重启即可。 <img src ="http://www.blogjava.net/fortune/aggbug/44550.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-05-04 19:10 <a href="http://www.blogjava.net/fortune/archive/2006/05/04/44550.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>中断JAVA线程</title><link>http://www.blogjava.net/fortune/archive/2006/04/12/40628.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Wed, 12 Apr 2006 05:36:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/04/12/40628.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/40628.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/04/12/40628.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/40628.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/40628.html</trackback:ping><description><![CDATA[在JAVA中，通过其对线程类的内嵌支持，编程人员编写多线程程序是很简易的。然而，在编程人员面前，多线程呈现出了一组新的难题，如果没有被恰当的解决，将导致意外的行为以及细微的、难以发现的错误。在本篇文章中，我们针对这些难题之一：如何中断一个正在运行的线程。 <br /><br />背景<br />中断（Interrupt）一个线程意味着在该线程完成任务之前停止其正在进行的一切，有效地中止其当前的操作。线程是死亡、还是等待新的任务或是继续运行至下一步，就取决于这个程序。<br /><br />虽然初次看来它可能显得简单，但是，你必须进行一些预警以实现期望的结果。你最好还是牢记以下的几点告诫。<br /><br />首先，忘掉Thread.stop方法。虽然它确实停止了一个正在运行的线程，然而，这种方法是不安全也是不受提倡的，这意味着，在未来的JAVA版本中，它将不复存在。<br /><br />一些轻率的家伙可能被另一种方法Thread.interrupt所迷惑。尽管，其名称似乎在暗示着什么，然而，这种方法并不会中断一个正在运行的线程（待会将进一步说明），正如Listing A中描述的那样。它创建了一个线程，并且试图使用Thread.interrupt方法停止该线程。Thread.sleep()方法的调用，为线程的初始化和中止提供了充裕的时间。线程本身并不参与任何有用的操作。<br /><br />Listing A<br />class Example1 extends Thread {<br /><br />  public static void main( String args[] ) throws Exception {<br /><br />    Example1 thread = new Example1();<br /><br />   System.out.println( "Starting thread..." );<br /><br />   thread.start();<br /><br />   Thread.sleep( 3000 );<br /><br />   System.out.println( "Interrupting thread..." );<br /><br />   thread.interrupt();<br /><br />   Thread.sleep( 3000 );<br /><br />   System.out.println( "Stopping application..." );<br /><br />   System.exit( 0 );<br /><br />  }<br /><br /><br />如果你运行了Listing A中的代码，你将在控制台看到以下输出：<br /><br />Starting thread...<br /><br />Thread is running...<br /><br />Thread is running...<br /><br />Thread is running...<br /><br />Interrupting thread...<br /><br />Thread is running...<br /><br />Thread is running...<br /><br />Thread is running...<br /><br />Stopping application...<br /><br />甚至，在Thread.interrupt()被调用后，线程仍然继续运行了一段时间。<br /><br />真正地中断一个线程<br /><br />中断线程最好的，最受推荐的方式是，使用共享变量（shared variable）发出信号，告诉线程必须停止正在运行的任务。线程必须周期性的核查这一变量（尤其在冗余操作期间），然后有秩序地中止任务。Listing B描述了这一方式。<br /><br />Listing B<br />class Example2 extends Thread {<br /><br />  volatile boolean stop = false;<br /><br />  public static void main( String args[] ) throws Exception {<br /><br />    Example2 thread = new Example2();<br /><br />   System.out.println( "Starting thread..." );<br /><br />   thread.start();<br /><br />   Thread.sleep( 3000 );<br /><br />   System.out.println( "Asking thread to stop..." );<br /><br />   thread.stop = true;<br /><br />   Thread.sleep( 3000 );<br /><br />   System.out.println( "Stopping application..." );<br /><br />   System.exit( 0 );<br /><br />  }<br /><br />  public void run() {<br /><br />    while ( !stop ) {<br /><br />     System.out.println( "Thread is running..." );<br /><br />      long time = System.currentTimeMillis();<br /><br />      while ( (System.currentTimeMillis()-time &lt; 1000) &amp;&amp; (!stop) ) {<br /><br />      }<br /><br />    }<br /><br />   System.out.println( "Thread exiting under request..." );<br /><br />  }<br /><br />}<br /><br /> <br /><br /><br />运行Listing B中的代码将产生如下输出（注意线程是如何有秩序的退出的）<br /><br />Starting thread...<br /><br />Thread is running...<br /><br />Thread is running...<br /><br />Thread is running...<br /><br />Asking thread to stop...<br /><br />Thread exiting under request...<br /><br />Stopping application...<br /><br />虽然该方法要求一些编码，但并不难实现。同时，它给予线程机会进行必要的清理工作，这在任何一个多线程应用程序中都是绝对需要的。请确认将共享变量定义成volatile 类型或将对它的一切访问封入同步的块/方法（synchronized blocks/methods）中。<br /><br />到目前为止一切顺利!但是，当线程等待某些事件发生而被阻塞，又会发生什么？当然，如果线程被阻塞，它便不能核查共享变量，也就不能停止。这在许多情况下会发生，例如调用Object.wait()、ServerSocket.accept()和DatagramSocket.receive()时，这里仅举出一些。<br /><br />他们都可能永久的阻塞线程。即使发生超时，在超时期满之前持续等待也是不可行和不适当的，所以，要使用某种机制使得线程更早地退出被阻塞的状态。<br /><br />很不幸运，不存在这样一种机制对所有的情况都适用，但是，根据情况不同却可以使用特定的技术。在下面的环节，我将解答一下最普遍的例子。<br /><br />使用Thread.interrupt()中断线程<br />正如Listing A中所描述的，Thread.interrupt()方法不会中断一个正在运行的线程。这一方法实际上完成的是，在线程受到阻塞时抛出一个中断信号，这样线程就得以退出阻塞的状态。更确切的说，如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞，那么，它将接收到一个中断异常（InterruptedException），从而提早地终结被阻塞状态。<br /><br />因此，如果线程被上述几种方法阻塞，正确的停止线程方式是设置共享变量，并调用interrupt()（注意变量应该先设置）。如果线程没有被阻塞，这时调用interrupt()将不起作用；否则，线程就将得到异常（该线程必须事先预备好处理此状况），接着逃离阻塞状态。在任何一种情况中，最后线程都将检查共享变量然后再停止。Listing C这个示例描述了该技术。<br /><br />Listing C<br />class Example3 extends Thread {<br /><br />  volatile boolean stop = false;<br /><br />  public static void main( String args[] ) throws Exception {<br /><br />   Example3 thread = new Example3();<br /><br />   System.out.println( "Starting thread..." );<br /><br />   thread.start();<br /><br />   Thread.sleep( 3000 );<br /><br />   System.out.println( "Asking thread to stop..." );<br /><br />   thread.stop = true;<br /><br />   thread.interrupt();<br /><br />   Thread.sleep( 3000 );<br /><br />   System.out.println( "Stopping application..." );<br /><br />   System.exit( 0 );<br /><br />  }<br /><br />  public void run() {<br /><br />    while ( !stop ) {<br /><br />     System.out.println( "Thread running..." );<br /><br />      try {<br /><br />      Thread.sleep( 1000 );<br /><br />      } catch ( InterruptedException e ) {<br /><br />      System.out.println( "Thread interrupted..." );<br /><br />      }<br /><br />    }<br /><br />   System.out.println( "Thread exiting under request..." );<br /><br />  }<br /><br />}<br /><br />一旦Listing C中的Thread.interrupt()被调用，线程便收到一个异常，于是逃离了阻塞状态并确定应该停止。运行以上代码将得到下面的输出：<br /><br />Starting thread...<br /><br />Thread running...<br /><br />Thread running...<br /><br />Thread running...<br /><br />Asking thread to stop...<br /><br />Thread interrupted...<br /><br />Thread exiting under request...<br /><br />Stopping application...<br /><br /><br />中断I/O操作<br />然而，如果线程在I/O操作进行时被阻塞，又会如何？I/O操作可以阻塞线程一段相当长的时间，特别是牵扯到网络应用时。例如，服务器可能需要等待一个请求（request），又或者，一个网络应用程序可能要等待远端主机的响应。<br /><br />如果你正使用通道（channels）（这是在Java 1.4中引入的新的I/O API），那么被阻塞的线程将收到一个ClosedByInterruptException异常。如果情况是这样，其代码的逻辑和第三个例子中的是一样的，只是异常不同而已。<br /><br />但是，你可能正使用Java1.0之前就存在的传统的I/O，因为新的I/O是最近才引入，而且要求更多的工作。既然这样，Thread.interrupt()将不起作用，因为线程将不会退出被阻塞状态。Listing D描述了这一行为。尽管interrupt()被调用，线程也不会退出被阻塞状态<br /><br />Listing D<br />import java.io.*;<br /><br />class Example4 extends Thread {<br /><br />  public static void main( String args[] ) throws Exception {<br /><br />    Example4 thread = new Example4();<br /><br />   System.out.println( "Starting thread..." );<br /><br />   thread.start();<br /><br />   Thread.sleep( 3000 );<br /><br />   System.out.println( "Interrupting thread..." );<br /><br />   thread.interrupt();<br /><br />   Thread.sleep( 3000 );<br /><br />   System.out.println( "Stopping application..." );<br /><br />   System.exit( 0 );<br /><br />  }<br /><br />  public void run() {<br /><br />   ServerSocket socket;<br /><br />    try {<br /><br />      socket = new ServerSocket(7856);<br /><br />    } catch ( IOException e ) {<br /><br />     System.out.println( "Could not create the socket..." );<br /><br />      return;<br /><br />    }<br /><br />    while ( true ) {<br /><br />     System.out.println( "Waiting for connection..." );<br /><br />      try {<br /><br />       Socket sock = socket.accept();<br /><br />      } catch ( IOException e ) {<br /><br />      System.out.println( "accept() failed or interrupted..." );<br /><br />      }<br /><br />    }<br /><br />  }<br /><br />}<br /><br /><br />很幸运，Java平台为这种情形提供了一项解决方案，即调用阻塞该线程的套接字的close()方法。在这种情形下，如果线程被I/O操作阻塞，该线程将接收到一个SocketException异常，这与使用interrupt()方法引起一个InterruptedException异常被抛出非常相似。<br /><br />唯一要说明的是，必须存在socket的引用（reference），只有这样close()方法才能被调用。这意味着socket对象必须被共享。Listing E描述了这一情形。运行逻辑和以前的示例是相同的。<br /><br />Listing E<br />import java.net.*;<br />import java.io.*;<br />class Example5 extends Thread {<br />  volatile boolean stop = false;<br />  volatile ServerSocket socket;<br />  public static void main( String args[] ) throws Exception {<br />    Example5 thread = new Example5();<br />   System.out.println( "Starting thread..." );<br />   thread.start();<br />   Thread.sleep( 3000 );<br />   System.out.println( "Asking thread to stop..." );<br />   thread.stop = true;<br />   thread.socket.close();<br />   Thread.sleep( 3000 );<br />   System.out.println( "Stopping application..." );<br />   System.exit( 0 );<br />  }<br />  public void run() {<br />    try {<br />      socket = new ServerSocket(7856);<br />    } catch ( IOException e ) {<br />     System.out.println( "Could not create the socket..." );<br />      return;<br />    }<br />    while ( !stop ) {<br />     System.out.println( "Waiting for connection..." );<br />      try {<br />       Socket sock = socket.accept();<br />      } catch ( IOException e ) {<br />      System.out.println( "accept() failed or interrupted..." );<br />      }<br />    }<br />   System.out.println( "Thread exiting under request..." );<br />  }<br />}<br />以下是运行Listing E中代码后的输出：<br /><br />Starting thread...<br /><br />Waiting for connection...<br /><br />Asking thread to stop...<br /><br />accept() failed or interrupted...<br /><br />Thread exiting under request...<br /><br />Stopping application...<br /><br />多线程是一个强大的工具，然而它正呈现出一系列难题。其中之一是如何中断一个正在运行的线程。如果恰当地实现，使用上述技术中断线程将比使用Java平台上已经提供的内嵌操作更为简单。 <br /><img src ="http://www.blogjava.net/fortune/aggbug/40628.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-04-12 13:36 <a href="http://www.blogjava.net/fortune/archive/2006/04/12/40628.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java线程</title><link>http://www.blogjava.net/fortune/archive/2006/04/12/40558.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Wed, 12 Apr 2006 01:41:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/04/12/40558.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/40558.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/04/12/40558.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/40558.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/40558.html</trackback:ping><description><![CDATA[
		<span class="javascript" id="text162090">在新的JDK5.0中，对thread做了一些改进，我通过阅读一些资料写下了下面的总结，请大家看看。<br /><br />1.创建线程<br />在java中实现多线程有两种方法，一个是直接继承Thread类，一个是实现Runnable接口，但是推荐的是第二种。因为在逻辑上应该要把一个线程要做的事情以及做这个事情的方法分开；对于Thread来讲，它只负责线程的操作，而具体要做的事情就应该放在Runnable中。但不管是那种方式，都要实现public void run()方法，但启动线程用start而不是run。<br /><br />2.终止线程<br />在1.0中，可以用stop方法来终止，但是现在这种方法已经被禁用了，改用interrupt方法。interrupt方法并不是强制终止线程，它只能设置线程的interrupted状态，而在线程中一般使用一下方式：<br />while (!Thread.currentThread().isInterrupted() &amp;&amp; more work to do)<br />{<br />do more work<br />}<br />而被block的线程在被调用interrupt时会产生InterruptException，此时是否终止线程由本线程自己决定。程序的一般形式是：<br />public void run()<br />{<br />try<br />{<br />. . .<br />while (!Thread.currentThread().isInterrupted() &amp;&amp; more work to do)<br />{<br />do more work<br />}<br />}<br />catch(InterruptedException e)<br />{<br />// thread was interrupted during sleep or wait<br />}<br />finally<br />{<br />cleanup, if required<br />}<br />// exiting the run method terminates the thread<br />}<br /><br />Thread.sleep方法也会产生InterruptedException，因此，如果每次在做完一些工作后调用了sleep方法，那么就不用检查isInterrupted，而是直接捕捉InterruptedException。<br /><br />在捕捉到InterruptedException时，如果没有其他的事情可做，最好做一下处理，不能用{}<br />1）<br />void mySubTask()<br />{<br />. . .<br />try { sleep(delay); }<br />catch (InterruptedException e) { Thread().currentThread().interrupt(); }<br />. . .<br />}<br />或是<br />2）<br />void mySubTask() throws InterruptedException<br />{<br />. . .<br />sleep(delay);<br />. . .<br />}<br /><br />3.线程状态<br />New：当使用new创建一个线程时<br />Runnable: 调用start或是从blocked状态出来时<br />Blocked：sleep, block on input/output, try to acquire lock, suspend, wait.<br />Dead: 运行完成或有exception产生。<br /><br />4.线程优先级<br />可以设置线程优先级，但是不能保证高优先级的线程就会被先运行<br /><br />5.线程组<br />可以把多个线程加到一个线程组里面去，这样可以对这些线程进行一些统一的操作，例如<br />ThreadGroup g = new ThreadGroup(groupName）<br />...<br />g.interrupt(); // interrupt all threads in group g<br /><br />6.为Uncaught Exceptions设置Handlers<br />在java 5.0中，可以为线程中产生的unchecked exception设置一个处理器，这个处理器必须实现UncaughtExceptionHandler接口。<br />可以调用线程实例的setUncaughtExceptionHandler方法为每个线程设置一个处理器，也可以调用Thread.setDefaultUncaughtExceptionHandler来为所有的线程设置一个默认的处理器。如果没有给每一个线程设置处理器，那线程会首先使用线程组的处理器，如果还没有再使用默认的处理器。<br /><br />7.Synchronization<br />多线程很重要的一个问题就是同步的问题，如果不解决好同步的问题一个是可能会引起数据的混乱，而且还有可能造成线程的死锁。在Java 5.0之前，用synchronized来解决这个问题，在5.0中加入了一个新的类:ReentrantLock<br /><br />使用lock的基本形式是：<br />myLock.lock(); // a ReentrantLock object<br />try<br />{<br />critical section<br />}<br />finally<br />{<br />myLock.unlock(); // make sure the lock is unlocked even if an exception is thrown<br />}<br /><br />这个锁被称为Reentrant的原因是在一个线程中可以重复多次申请同一个锁，系统会保留加锁的次数，而在解锁的时候也就必须执行相同次数。<br /><br />在一个线程已经得到锁可以执行程序的时候，可能会发现需要的条件还不能满足，这时他就必须等待直到条件满足。但是因为它已经对所需要操作的东西加了锁，其他的线程不能访问，因此它又可能会永远等待下去。现在可以用Condition Object来避免这种情况。<br />sufficientFunds = bankLock.newCondition();<br />如果条件不满足：<br />sufficientFunds.await();<br />这时线程就会释放锁并进入blocked状态，其他线程就有机会执行操作。当其他线程执行完后，就可通知等待的线程继续执行它的操作了：<br />sufficientFunds.signalAll();<br />当然也可以调用singal方法，这样效率会高一些，但是有一定的危险性，因为它的唤醒具有随机性。<br /><br />在5.0之前，采用的是synchronized关键字来进行同步，但是和lock相比它有一些局限性：<br />1. 申请锁的线程不能被interrupt<br />2. 没有timeout设置<br />3. 只有一个隐性的condition条件<br /><br />另外，在申请锁的时候可以用tryLock方法，它会返回一个bool值来表示锁是否申请成功，如果没有成功，程序就可以做其他的事情了。<br /><br />tryLock, await方法都可以被interrupt。<br /><br />java.util.concurrent.locks包中提供了两种锁，一个就是ReentrantLock，另一个是ReentrantReadWriteLock，一般用于多操作远远多于写操作的时候：<br />private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();<br />private Lock readLock = rwl.readLock();<br />private Lock writeLock = rwl.writeLock();<br /><br />8. Callables and Futures<br />实现多线程时一般用的是Runnable接口，但是他有一个问题就是他没有参数和返回值，所以当执行一个线程需要返回一个值的时候就不是很方便了。Callable接口和Runnable差不多，但是他提供了参数和返回值：<br />public interface Callable&lt;V&gt;<br />{<br />V call() throws Exception;<br />}<br />而Future接口可以保留异步执行的值：<br />public interface Future&lt;V&gt;<br />{<br />V get() throws . . .;<br />V get(long timeout, TimeUnit unit) throws . . .;<br />void cancel(boolean mayInterrupt);<br />boolean isCancelled();<br />boolean isDone();<br />}<br /><br />FutureTask可以很方便的把Callable转换成Future和Runnable:<br />Callable&lt;Integer&gt; myComputation = . . .;<br />FutureTask&lt;Integer&gt; task = new FutureTask&lt;Integer&gt;(myComputation);<br />Thread t = new Thread(task); // it's a Runnable<br />t.start();<br />. . .<br />Integer result = task.get(); // it's a Future<br /><br />9.用Executors创建线程池<br />用线程池有两个好处：1. 减少创建线程的开销。2. 控制线程的数量。<br />EXecutors提供了一些方法可以很方便的创建线程池：<br />newCachedThreadPool<br />New threads are created as needed; idle threads are kept for 60 seconds.<br /><br />newFixedThreadPool<br />The pool contains a fixed set of threads; idle threads are kept indefinitely.<br /><br />newSingleThreadExecutor<br />A "pool" with a single thread that executes the submitted tasks sequentially.<br /><br />newScheduledThreadPool<br />A fixed-thread pool for scheduled execution.<br /><br />newSingleThreadScheduledExecutor<br />A single-thread "pool" for scheduled execution.<br /><br />在使用Executors时，先调用这些静态方法创建线程池，得到一个ExecutorService对象，然后用这个对象的submit方法提交你的Runnable或是Callable对象。<br />Future&lt;?&gt; submit(Runnable task)<br />Future&lt;T&gt; submit(Runnable task, T result)<br />Future&lt;T&gt; submit(Callable&lt;T&gt; task)<br />如果不再需要任何提交，就用shutdown方法来关闭线程池。<br /><br />10.在界面中使用多线程<br />对于GUI设计来说，很重要的一个原则就是要及时的给用户反馈，就算是不能立即得到结果，界面也不能停在那里，是用户不知道发生了什么事情，必须让用户随时知道程序在坐什么。所以当程序要执行一段需要消耗比较长时间的操作时，就要使用多线程。<br /><br />但是，有些界面控件并不是线程安全的，在使用这些控件时就要特别注意。在API doc中这些都有注明，使用的时候就可以查一下。<br /><br />如果想在自己另外所创建的线程执行过程中随时更新界面来表示执行进程，要注意的一点是，这个线程并不能直接调用界面控件的方法，而要采用EventQueue类的invokeLater，invokeAndWait方法：<br />EventQueue.invokeLater(new<br />Runnable()<br />{<br />public void run()<br />{<br />label.setText(percentage + "% complete");<br />}<br />}); </span>
		<br />
<img src ="http://www.blogjava.net/fortune/aggbug/40558.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-04-12 09:41 <a href="http://www.blogjava.net/fortune/archive/2006/04/12/40558.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT的线程间通信</title><link>http://www.blogjava.net/fortune/archive/2006/04/10/40280.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 10 Apr 2006 09:29:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/04/10/40280.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/40280.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/04/10/40280.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/40280.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/40280.html</trackback:ping><description><![CDATA[
		<h2> </h2>
		<p>
		</p>
		<p>在SWT中，通常需要开多个线程来执行任务，因为主线程为UI线程，不能用太长的时间来执行某个任务，否则会造成失去响应的假象。<br />SWT的线程通信有几个要注意的地方：<br />1、工作线程访问UI线程。不能在非UI线程中直接访问UI控件的值，要获得或设置控件的值必须通过Display对象的asyncExec()或syncExec()函数，一般的使用方法是：<br /><span style="COLOR: #008080"></span></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">//代码A：<br /> <br />Display disp  </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">  Display.getDefault();<br /> </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000"> (disp </span>
				<span style="COLOR: #000000">!=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">null</span>
				<span style="COLOR: #000000"> )  {<br />   disp.asyncExec(<br />    </span>
				<span style="COLOR: #0000ff">new</span>
				<span style="COLOR: #000000">  Runnable()  {<br />    </span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000">  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">  run()  {<br />       </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 在这里设置或获得控件的值 </span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000"> } <br />} <br />); <br />} </span>
		</div>
		<br />2、内部类与外部类的交流。内部类调用外部类局部变量时，该变量必须是final的，这样在取得控件的值后返回给外部类处理时就比较麻烦。例如，在上面的代码段中，有个匿名内部类实现了Runnable接口，在里面的run()函数里可以访问到UI对象，但是，得到了对象的值怎么告诉外面的代码呢？假如用普通的局部变量传递进去，由于是final的，是不能赋值的，所以需要有一个封装类来把需要返回的变量封装起来，这个封装类是final的，但里面的成员变量是可变的，这样就把内部类里得到的东西传递到了外部，不过似乎比较麻烦，不知道有没有更好的办法。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">//代码B：<br /><br />class</span><span style="COLOR: #000000"> StringWrapper {<br /></span><span style="COLOR: #0000ff">   public</span><span style="COLOR: #000000"> String uiValue;<br />}<br />StringWrapper sw </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> StringWrapper(); <br />Display disp  </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">  Display.getDefault();<br /> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (disp </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> )  {<br />   disp.asyncExec(<br />    </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">  Runnable()  {<br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">  run()  {<br />        sw.uiValue </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> text.getText();</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">假设text是一个文本框对象<br />       </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 在这里设置或获得控件的值 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    } <br />   } <br />   ); <br />} <br /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">这里就可以对sw.uiValue的值进行访问</span></div>3、线程间的同步。在上面的代码B中，通过asyncExec()函数来取得控件的值所需要的时间比较长，如果在后面马上访问那些值是得不到的，于是就需要有个同步的问题，即在控件值取得之前先不进行下一步操作。可以通过synchronized块及wait()，notify()机制来实现同步。<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008000">//</span><span style="COLOR: #008000">代码C：</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> StringWrapper {<br />   </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> String uiValue;<br />}<br />StringWrapper sw </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> StringWrapper(); <br />Display disp  </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">  Display.getDefault();<br /> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (disp </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> )  {<br />   disp.asyncExec(<br />    </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">  Runnable()  {<br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">  run()  {<br />        </span><span style="COLOR: #0000ff">synchronized</span><span style="COLOR: #000000">(sw){<br />          sw.uiValue </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> text.getText();</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">假设text是一个文本框对象</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">            sw.notify();<br />         }<br />       </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 在这里设置或获得控件的值</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"> <br />    } <br />   } <br />   ); <br />}<br /></span><span style="COLOR: #0000ff">synchronized</span><span style="COLOR: #000000">(sw){<br />  sw.wait();<br />} <br /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">这里就可以对sw.uiValue的值进行访问</span></div><br />但是这里会带来一个问题，假如很快就能取得控件的值，但后面还有很长一段时间才会用到该值，如果把sw.wait()语句放在比较后的地方，就有可能造成死锁，因为sw已经被notify之后才开始wait的，再没有其他线程来notify它了，它就只能一直wait下去……。为了解决这个问题，可以(1)把sw.wait()紧跟在disp.asyncExec()后面；(2)给wait()设置一个timeout参数，到了一定的时间还没有东西notify它，它就自己超时。但这两种办法似乎都比较牵强，没有十足的保证，JDK文档里面有个例子，是用while来判断是否已经达到了要求，如果已经达到了就不再wait。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008000">//</span><span style="COLOR: #008000">代码D：</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> StringWrapper {<br />   </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> String uiValue;<br />   </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">boolean</span><span style="COLOR: #000000"> isValueSet;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">是否已经取得了控件的值</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">}<br />StringWrapper sw </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> StringWrapper(); <br />sw.isValueSet </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;<br />Display disp  </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">  Display.getDefault();<br /> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (disp </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> )  {<br />   disp.asyncExec(<br />    </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">  Runnable()  {<br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">  run()  {<br />        </span><span style="COLOR: #0000ff">synchronized</span><span style="COLOR: #000000">(sw){<br />          sw.uiValue </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> text.getText();</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">假设text是一个文本框对象</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">            sw.isValueSet </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br />            sw.notify();<br />         }<br />       <span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 在这里设置或获得控件的值</span></span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"> <br />    } <br />   } <br />   ); <br />}<br /></span><span style="COLOR: #0000ff">synchronized</span><span style="COLOR: #000000">(sw){<br />  </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">sw.isValueSet){<br />    </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">{<br />      sw.wait();<br />    }</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (InterruptedException e){<br />    }<br />  }<br />} <br /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">这里就可以对sw.uiValue的值进行访问</span></div><img src ="http://www.blogjava.net/fortune/aggbug/40280.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-04-10 17:29 <a href="http://www.blogjava.net/fortune/archive/2006/04/10/40280.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>swt 解决在容器中添加或修改内容时不能及时显示的问题</title><link>http://www.blogjava.net/fortune/archive/2006/04/04/39257.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Tue, 04 Apr 2006 13:38:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/04/04/39257.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/39257.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/04/04/39257.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/39257.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/39257.html</trackback:ping><description><![CDATA[想了很久 （水平太滥）查了半天资料才发现需要在最后添加一个函数layout（）就能解决了<br />比如在composite中就添加一句composite.layout()就OK了，呵呵，是不是很简单。以后不许忘了哦。<img src ="http://www.blogjava.net/fortune/aggbug/39257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-04-04 21:38 <a href="http://www.blogjava.net/fortune/archive/2006/04/04/39257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跟我学XML Schema</title><link>http://www.blogjava.net/fortune/archive/2006/03/27/37659.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 27 Mar 2006 10:01:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/27/37659.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/37659.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/27/37659.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/37659.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/37659.html</trackback:ping><description><![CDATA[
		<div>如何写一个最简单的XML Schema文档呢？ 
<p></p><p>首先，我们写出一个最简单的XML文档.</p><p>hello.xml<br />-------------------<br />&lt;?xml version="1.0"?&gt; <br />&lt;greeting&gt;Hello World!!&lt;/greeting&gt;</p><p>（一个根元素：greeting；且这个元素不含属性，无子元素，内容是字符串。）</p><p>hello.xsd<br />－－－－－－－－－－<br />&lt;?xml version="1.0"?&gt; <br />&lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />  &lt;xsd:element name="greeting" type="xsd:string"/&gt;<br />&lt;/xsd:schema&gt;</p><p>XML Schema文档后缀名是.xsd，完全符合XML语法，根元素是schema，命名空间xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema</font></a>，用元素&lt;element&gt;定义实例文档中的元素，如greeting。<br /></p><div>跟我学XML Schema(2):含子元素的稍复杂Schema文档  
<p></p><p>假设实例文档是如下的：</p><p>customer.xml<br />-----------<br />&lt;customer&gt;<br />  &lt;name&gt;teiki&lt;/name&gt;<br />  &lt;address&gt;No.237, Road Waitan, Shanghai&lt;/address&gt;<br />&lt;/customer&gt;</p><p>则可以写出以下的XML Schema文档：<br />customer.xsd<br />----------------<br />1: &lt;?xml version="1.0"?&gt;<br />2: &lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />3:   &lt;xsd:element name="customer"&gt;<br />4:    &lt;xsd:complexType&gt;<br />5:      &lt;xsd:sequence&gt;<br />6:        &lt;xsd:element name="name" type="xsd:string"/&gt;<br />7:        &lt;xsd:element name="address" type="xsd:string" /&gt;<br />8:      &lt;/xsd:sequence&gt;<br />9:    &lt;/xsd:complexType&gt;<br />10:  &lt;/xsd:element&gt;<br />11: &lt;/xsd:schema&gt;</p><p>实例文档customer.xml中，&lt;customer&gt;元素含有两个子元素，所以我们在Schema文档中采用ComplexType来定义该元素。</p><p>sequence表示子元素依次出现的顺序。<br /></p><div>跟我学XML Schema(3):含子元素和孙元素的更复杂Schema文档 
<p></p><p>这次我们给出一个更加复杂一些的文档：</p><p>address.xml<br />---------------<br />&lt;customer&gt;<br />  &lt;name&gt;Teiki&lt;/name&gt;<br />  &lt;address&gt;<br />    &lt;!-- address追加一个地址子元素 --&gt;<br />    &lt;prefecture&gt;Zhejiang&lt;/prefecture&gt;<br />    &lt;city&gt;Hangzhou&lt;/city&gt;<br />    &lt;street&gt;Xilu Road, No.121, 7F&lt;/street&gt;<br />  &lt;/address&gt;<br />&lt;/customer&gt;</p><p><br />为此，我们需要一个更加复杂一点的Schema文档：</p><p>address.xsd<br />-----------------<br />1: &lt;?xml version="1.0"?&gt;<br />2: &lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />3:<br />4:   &lt;xsd:element name="customer"&gt;<br />5:     &lt;xsd:complexType&gt;<br />6:       &lt;xsd:sequence&gt;<br />7:         &lt;xsd:element name="name" type="xsd:string"/&gt;<br />8:         &lt;!-- 追加子元素address--&gt;<br />9:         &lt;xsd:element name="address"&gt;<br />10:          &lt;xsd:complexType&gt;<br />11:            &lt;xsd:sequence&gt;<br />12:              &lt;xsd:element name="prefecture" type="xsd:string"/&gt;<br />13:              &lt;xsd:element name="city" type="xsd:string" /&gt;<br />14:              &lt;xsd:element name="street" type="xsd:string" /&gt;<br />15:            &lt;/xsd:sequence&gt;<br />16:          &lt;/xsd:complexType&gt;<br />17:        &lt;/xsd:element&gt;<br />18:        &lt;!-- end --&gt;<br />19:      &lt;/xsd:sequence&gt;<br />20:    &lt;/xsd:complexType&gt;<br />21:  &lt;/xsd:element&gt;<br />22:<br />23:&lt;/xsd:schema&gt;<br />不过，我们还可以采用ref元素来重新编写这个Schema文档：<br />address2.xsd<br />----------------------<br />1: &lt;?xml version="1.0"?&gt;<br />2: &lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />3:<br />4:   &lt;xsd:element name="customer"&gt;<br />5:     &lt;xsd:complexType&gt;<br />6:       &lt;xsd:sequence&gt;<br />7:         &lt;xsd:element name="name" type="xsd:string"/&gt;<br />8:         &lt;xsd:element ref="address"/&gt;<br />9:       &lt;/xsd:sequence&gt;<br />10:    &lt;/xsd:complexType&gt;<br />11:  &lt;/xsd:element&gt;<br />12:<br />13:  &lt;xsd:element name="address"&gt;<br />14:    &lt;xsd:complexType&gt;<br />15:      &lt;xsd:sequence&gt;<br />16:        &lt;xsd:element name="prefecture" type="xsd:string"/&gt;<br />17:        &lt;xsd:element name="city" type="xsd:string" /&gt;<br />18:        &lt;xsd:element name="street" type="xsd:string" /&gt;<br />19:      &lt;/xsd:sequence&gt;<br />20:    &lt;/xsd:complexType&gt;<br />21:  &lt;/xsd:element&gt;<br />22:<br />23: &lt;/xsd:schema&gt;<br />使用ref元素可以直接将其指向另一个模块，使文档更加具有可读性。<br />跟我学XML Schema(4):如何定义属性呢？  </p><p></p><p><br />加入实例文档的元素包含属性，怎么办呢？</p><p>customer2.xml<br />---------------<br />&lt;customer id="001718"&gt;<br />  &lt;name&gt;Teiki&lt;/name&gt;<br />  &lt;address&gt;No.237, Road Waitan, Shanghai&lt;/address&gt;<br />&lt;/customer&gt;</p><p>那就这样写Schema文档：<br />customer2.xsd<br />------------------<br />1: &lt;?xml version="1.0"?&gt;<br />2: &lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />3:<br />4:   &lt;xsd:element name="customer"&gt;<br />5:    &lt;xsd:complexType&gt;<br />6:      &lt;xsd:sequence&gt;<br />7:        &lt;xsd:element name="name" type="xsd:string"/&gt;<br />8:        &lt;xsd:element name="address" type="xsd:string" /&gt;<br />9:      &lt;/xsd:sequence&gt;<br />10:      &lt;!-- 增加属性定义 --&gt;<br />11:      &lt;xsd:attribute name="id" type="xsd:string"/&gt;<br />12:    &lt;/xsd:complexType&gt;<br />13:  &lt;/xsd:element&gt;<br />14:<br />15: &lt;/xsd:schema&gt;</p><p>很简单，在&lt;sequence&gt;元素定义完成后，再用&lt;attribute&gt;元素id。<br /></p><div>跟我学XML Schema(5):如何定义相同子元素的数量？  
<p></p><p>先看这个简单的订购数据实例文档：</p><p>order.xml<br />---------<br />&lt;order&gt;<br />  &lt;orderItem&gt;Accounting Book&lt;/orderItem&gt;<br />  &lt;orderItem&gt;Taxation Book&lt;/orderItem&gt;<br />&lt;/order&gt;</p><p>假设&lt;orderItem&gt;元素，即每次的订购书目不能超过10种，那该怎么写这个Schema文档呢？这里要用到&lt;element&gt;的maxOccurs属性。</p><p>order.xsd<br />--------------------<br />1:&lt;?xml version="1.0"?&gt;<br />2:&lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />3:<br />4:  &lt;xsd:element name="order"&gt;<br />5:    &lt;xsd:complexType&gt;<br />6:      &lt;xsd:sequence&gt;<br />7:        &lt;xsd:element name="orderItem"   type="xsd:string"  maxOccurs="10" /&gt;<br />8:      &lt;/xsd:sequence&gt;<br />9:    &lt;/xsd:complexType&gt;<br />10:  &lt;/xsd:element&gt;<br />11:<br />12:&lt;/xsd:schema&gt;</p><p>第7行中的maxOccurs属性为10，代表orderItem元素可以最大有10个。如果，不设定元素个数，则可以用maxOccurs="unbounded"来定义.</p><p>类似，如果要定义最小值，可以使用minOccurs，比如下面这句：<br />&lt;xsd:element name="orderItem" type="xsd:string" minOccurs="5" maxOccurs="10"/&gt;<br />这两个属性缺省值都是1。<br /></p><div>跟我学XML Schema(6):如何定义可选项的子元素？ 
<p></p><p>假如上面的订书数据中，可以用书名或者书号任一一种订购，则实例文档可能如下：</p><p>order2.xml<br />-----------------<br />&lt;order&gt;<br />  &lt;orderItem&gt;<br />    &lt;!--书名订购--&gt;<br />    &lt;name&gt;Accounting Book&lt;/name&gt;<br />  &lt;/orderItem&gt;<br />  &lt;orderItem&gt;<br />    &lt;!--书号订购--&gt;<br />    &lt;id&gt;7-5058-3496-7&lt;/id&gt;<br />  &lt;/orderItem&gt;<br />&lt;/order&gt;</p><p>这时书写Schema文档还需要使用choice元素。</p><p>order2.xsd<br />-------------------------<br />1:&lt;?xml version="1.0"?&gt;<br />2:&lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />3:<br />4:  &lt;xsd:element name="order"&gt;<br />5:    &lt;xsd:complexType&gt;<br />6:      &lt;xsd:sequence&gt;<br />7:        &lt;xsd:element ref="orderItem" maxOccurs="10" /&gt;<br />8:      &lt;/xsd:sequence&gt;<br />9:    &lt;/xsd:complexType&gt;<br />10:  &lt;/xsd:element&gt;<br />11:<br />12:  &lt;xsd:element name="orderItem"&gt;<br />13:    &lt;xsd:complexType&gt;<br />14:      &lt;xsd:choice&gt;<br />15:        &lt;xsd:element name="name" type="xsd:string"/&gt;<br />16:        &lt;xsd:element name="id" type="xsd:string"/&gt;<br />17:      &lt;/xsd:choice&gt;<br />18:    &lt;/xsd:complexType&gt;<br />19:  &lt;/xsd:element&gt;<br />20:<br />21:&lt;/xsd:schema&gt;<br /></p><div>跟我学XML Schema(7):稍微更复杂的可选项子元素 
<p></p><p>再稍微修改一下订书数据的实例文档：</p><p>order3.xml<br />-----------------<br />&lt;order&gt;<br />  &lt;orderItem&gt;<br />    &lt;name&gt;Accounting Book&lt;/name&gt;<br />    &lt;quantity&gt;2&lt;/quantity&gt;<br />  &lt;/orderItem&gt;<br />  &lt;orderItem&gt;<br />    &lt;id&gt;7-5058-3496-7&lt;/id&gt;<br />  &lt;/orderItem&gt;<br />&lt;/order&gt;</p><p>这里假定&lt;quantity&gt;值为1时，缺省。</p><p>如何修改Schema文档呢？</p><p>order3.xsd<br />-----------------<br />1:&lt;?xml version="1.0"?&gt;<br />2:&lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />3:<br />4:  &lt;xsd:element name="order"&gt;<br />5:    &lt;xsd:complexType&gt;<br />6:      &lt;xsd:sequence&gt;<br />7:        &lt;xsd:element ref="orderItem" maxOccurs="10"/&gt;<br />8:      &lt;/xsd:sequence&gt;<br />9:    &lt;/xsd:complexType&gt;<br />10:  &lt;/xsd:element&gt;<br />11:<br />12:  &lt;xsd:element name="orderItem"&gt;<br />13:    &lt;xsd:complexType&gt;<br />14:      &lt;xsd:sequence&gt;<br />15:        &lt;xsd:choice&gt;<br />16:          &lt;xsd:element name="name" type="xsd:string"/&gt;<br />17:          &lt;xsd:element name="id" type="xsd:string"/&gt;<br />18:        &lt;/xsd:choice&gt;<br />19:        &lt;xsd:element name="quantity" type="xsd:string" minOccurs="0"/&gt;<br />20:      &lt;/xsd:sequence&gt;<br />21:    &lt;/xsd:complexType&gt;<br />22:  &lt;/xsd:element&gt;<br />23:<br />24:&lt;/xsd:schema&gt;</p><p>19行中的quantity最少出现值为0，也就是可以有，也可以没有。<br />当然，也可以直接在&lt;choice&gt;元素中，包含quantity,然后定义它的minOccurs。</p><div>跟我学XML Schema(8):内置简单类型 
<p></p><p>内建于XML Schema的简单类型有44种。他们在XML Schema推荐标准的第二部分中公布，下面这是一张内置类型的层次结构图：</p><p><a class="contentlink" href="http://www.w3.org/TR/2001/PR-xmlschema-2-20010330/type-hierarchy.jpg" target="_blank"><font color="#4455aa">http://www.w3.org/TR/2001/PR-xmlschema-2-20010330/type-hierarchy.jpg</font></a><br /></p><div>跟我学XML Schema(9):自定义简单类型 
<p></p><p>如果内置简单类型的44种还不能满足要求，怎么办呢？下面学习自定义简单类型。(XML的扩展性充分体现在这里)</p><p>例如这个实例文档：</p><p>order4.xml<br />-----------------<br />&lt;order&gt;<br />  &lt;orderItem&gt;<br />    &lt;id&gt;7-5058-3496-7&lt;/id&gt;<br />    &lt;quantity&gt;5&lt;/quantity&gt;<br />  &lt;/orderItem&gt;<br />&lt;/order&gt;</p><p>ID是一个标准的ISBN编码，我们怎么定义这个ISBN编码呢？</p><p>&lt;xsd:simpleType name="idType"&gt;<br />  &lt;xsd:restriction base="xsd:string"&gt;<br />    &lt;xsd:pattern <i>value</i>="\d{1}-\d{4}-\d{4}-\d{1}"/&gt;<br />  &lt;/xsd:restriction&gt;<br />&lt;/xsd:simpleType&gt;</p><p>idType是一个自定义的简单类型。<br />我们对它做了限制：<br />&lt;xsd:restriction base="xsd:string"&gt;代表它是基于一个字符串类型。再用pattern元素来描述该字符串的形式。</p><p><i>value</i>="\d{1}-\d{4}-\d{4}-\d{1}"这是一个正则表达式，关于正则表达式，以后再介绍。嘻嘻！</p><p>利用这个自定义的简单类型，我们可以重新写Schema文档：</p><p>order4.xsd<br />---------------<br />1:&lt;?xml version="1.0"?&gt;<br />2:&lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />3:<br />4:  &lt;xsd:element name="order"&gt;<br />5:    &lt;xsd:complexType&gt;<br />6:      &lt;xsd:sequence&gt;<br />7:        &lt;xsd:element ref="orderItem" maxOccurs="10"/&gt;<br />8:      &lt;/xsd:sequence&gt;<br />9:    &lt;/xsd:complexType&gt;<br />10:  &lt;/xsd:element&gt;<br />11:<br />12:  &lt;xsd:element name="orderItem"&gt;<br />13:    &lt;xsd:complexType&gt;<br />14:      &lt;xsd:sequence&gt;<br />15:        &lt;xsd:element name="id" type="idType"/&gt;<br />16:        &lt;xsd:element name="quantity" type="xsd:integer"/&gt;<br />17:      &lt;/xsd:sequence&gt;<br />18:    &lt;/xsd:complexType&gt;<br />19:  &lt;/xsd:element&gt;<br />20:  <br />21:  &lt;xsd:simpleType name="idType"&gt;<br />22:    &lt;xsd:restriction base="xsd:string"&gt;<br />23:      &lt;xsd:pattern <i>value</i>="\d{1}-\d{4}-\d{4}-\d{1}"/&gt;<br />24:    &lt;/xsd:restriction&gt;<br />25:  &lt;/xsd:simpleType&gt;<br />26:  <br />27:&lt;/xsd:schema&gt;</p><p><br />假如我们事先确定好ID只有3个，即只有3个ISBN是可选的，那怎么办？我们可以用enumeration元素来进行列举。</p><p>&lt;xsd:simpleType name="idType"&gt;<br />  &lt;xsd:restriction base="xsd:string"&gt;<br />    &lt;xsd:enumeration <i>value</i>="7-5058-3496-7"/&gt;<br />    &lt;xsd:enumeration <i>value</i>="7-5005-6450-3"/&gt;<br />    &lt;xsd:enumeration <i>value</i>="7-3020-6069-7"/&gt;<br />  &lt;/xsd:restriction&gt;<br />&lt;/xsd:simpleType&gt;</p><p><br />再来看订购量quantity的值，如果我们设定其值必须在1－10之间，该怎么办呢？可以这些自定义一个简单类型。</p><p>&lt;xsd:simpleType name="quantityType"&gt;<br />  &lt;xsd:restriction base="xsd:integer"&gt;<br />    &lt;xsd:minInclusive <i>value</i>="1"/&gt;<br />    &lt;xsd:maxInclusive <i>value</i>="10"/&gt;<br />  &lt;/xsd:restriction&gt;<br />&lt;/xsd:simpleType&gt;</p><p>其中，minInclusive,maxInclusive分别代表该类型的取值范围。</p><p>所以最终修改后的Schema文档如下：</p><p>order4-1.xsd<br />----------------------<br />1:&lt;?xml version="1.0"?&gt;<br />2:&lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />3:<br />4:  &lt;xsd:element name="order"&gt;<br />5:    &lt;xsd:complexType&gt;<br />6:      &lt;xsd:sequence&gt;<br />7:        &lt;xsd:element ref="orderItem" maxOccurs="10"/&gt;<br />8:      &lt;/xsd:sequence&gt;<br />9:    &lt;/xsd:complexType&gt;<br />10:  &lt;/xsd:element&gt;<br />11:<br />12:  &lt;xsd:element name="orderItem"&gt;<br />13:    &lt;xsd:complexType&gt;<br />14:      &lt;xsd:sequence&gt;<br />15:        &lt;xsd:element name="id" type="idType"/&gt;<br />16:        &lt;xsd:element name="quantity" type="quantityType"/&gt;<br />17:      &lt;/xsd:sequence&gt;<br />18:    &lt;/xsd:complexType&gt;<br />19:  &lt;/xsd:element&gt;<br />20:  <br />21:  &lt;xsd:simpleType name="idType"&gt;<br />22:    &lt;xsd:restriction base="xsd:string"&gt;<br />23:      &lt;xsd:enumeration <i>value</i>="7-5058-3496-7"/&gt;<br />    &lt;xsd:enumeration <i>value</i>="7-5005-6450-3"/&gt;<br />    &lt;xsd:enumeration <i>value</i>="7-3020-6069-7"/&gt;<br />26:    &lt;/xsd:restriction&gt;<br />27:  &lt;/xsd:simpleType&gt;<br />28:  <br />29:  &lt;xsd:simpleType name="quantityType"&gt;<br />30:    &lt;xsd:restriction base="xsd:integer"&gt;<br />31:      &lt;xsd:minInclusive <i>value</i>="1"/&gt;<br />32:      &lt;xsd:maxInclusive <i>value</i>="10"/&gt;<br />33:    &lt;/xsd:restriction&gt;<br />34:  &lt;/xsd:simpleType&gt;<br />35:<br />36:&lt;/xsd:schema&gt;<br /></p><div>跟我学XML Schema(10):定义属性 
<p></p><p>最后，我们再来讲讲元素的属性如何在Schema文档中定义。</p><p>比如上面的order.xml实例文档中：</p><p>&lt;order&gt;<br />  &lt;orderItem id="7-5058-3496-7" /&gt;<br />&lt;/order&gt;</p><p>对此，我们在Schema文档中采用一个attribute来定义：</p><p>order.xsd<br />－－－－－－－－－<br />&lt;xsd:element name="orderItem"&gt;<br />  &lt;xsd:complexType&gt;<br />    &lt;xsd:sequence&gt;　　←空元素<br />    &lt;/xsd:sequence&gt;　 <br />    <br />    &lt;!--定义该元素属性--&gt;<br />    &lt;xsd:attribute name="id" type="xsd:string"/&gt;<br />  &lt;/xsd:complexType&gt;<br />&lt;/xsd:element&gt;</p><p>那么，实例文档中该属性值是必须的还是可有可无的呢？我们可以这样限制：</p><p>&lt;xsd:attribute name="id" type="idType" use="required"/&gt;</p><p>这里我们讲id属性类型作为一种自定义数据类型idType。<br />而且，用attribute元素的use属性来定义是否是必须的属性。<br />required是必须值，optional是可选值，prohibited是无属性值。</p><p><br />那么对于属性的缺省值，我们怎么定义呢？<br />比如：<br />&lt;order&gt;<br />  &lt;orderItem id="4-8443-1780-6" quantity="3"/&gt;<br />&lt;/order&gt;</p><p>我们还可以用attribute元素的另一个属性default来定义：<br />&lt;xsd:attribute name="quantity" type="xsd:integer" default="1"/&gt;</p><p>所以，我们可以重新写出一个Schema文档：</p><p>order2.xsd<br />--------------<br />&lt;xsd:element name="orderItem"&gt;<br />  &lt;xsd:complexType&gt;<br />    &lt;xsd:sequence&gt;&lt;/xsd:sequence&gt;<br />    &lt;xsd:attribute name="id" type="idType" use="required"/&gt;<br />    &lt;xsd:attribute name="quantity" type="xsd:integer" default="1"/&gt;<br />  &lt;/xsd:complexType&gt;<br />&lt;/xsd:element&gt;<br /></p><div>上面的属性我们定义我们还可以采用属性组的办法来重新改写Schema文档。 
<p></p><p>order3.xsd<br />----------------<br />1:    &lt;xsd:element name="orderItem"&gt;<br />2:      &lt;xsd:complexType&gt;<br />3:        &lt;xsd:sequence&gt;&lt;/xsd:sequence&gt;<br />4:        &lt;xsd:attributeGroup ref="orderItemAttributes"/&gt;<br />5:      &lt;/xsd:complexType&gt;<br />6:    &lt;/xsd:element&gt;<br />7:<br />8:    &lt;xsd:attributeGroup name="orderItemAttributes"&gt;<br />9:      &lt;xsd:attribute name="id" type="idType" use="required"/&gt;<br />10:      &lt;xsd:attribute name="quantity" type="xsd:integer" default="1"/&gt;<br />11:    &lt;/xsd:attributeGroup&gt;</p><p>这个属性组就不详细解释了，不过，大家一看就清楚了吧。</p><p>最后，我们写一个完整的订书order.xml的Schema文档。<br />1:  &lt;?xml version="1.0"?&gt;<br />2:  &lt;xsd:schema xmlns:xsd="<a class="contentlink" href="http://www.w3.org/2001/XMLSchema&quot;&gt;" target="_blank"><font color="#4455aa">http://www.w3.org/2001/XMLSchema"&gt;</font></a><br />3:<br />4:    &lt;xsd:element name="order"&gt;<br />5:      &lt;xsd:complexType&gt;<br />6:        &lt;xsd:sequence&gt;<br />7:          &lt;xsd:element ref="orderItem" maxOccurs="10"/&gt;<br />8:        &lt;/xsd:sequence&gt;<br />9:      &lt;/xsd:complexType&gt;<br />10:    &lt;/xsd:element&gt;<br />11:<br />12:    &lt;xsd:element name="orderItem"&gt;<br />13:      &lt;xsd:complexType&gt;<br />14:        &lt;xsd:sequence&gt;&lt;/xsd:sequence&gt;<br />15:        &lt;xsd:attributeGroup ref="orderItemAttributes"/&gt;<br />16:      &lt;/xsd:complexType&gt;<br />17:    &lt;/xsd:element&gt;<br />18:<br />19:    &lt;xsd:attributeGroup name="orderItemAttributes"&gt;<br />20:      &lt;xsd:attribute name="id" type="idType" use="required"/&gt;<br />21:      &lt;xsd:attribute name="quantity" type="xsd:integer" default="1"/&gt;<br />22:    &lt;/xsd:attributeGroup&gt;<br />23:<br />24:    &lt;xsd:simpleType name="idType"&gt;<br />25:      &lt;xsd:restriction base="xsd:string"&gt;<br />26:        &lt;xsd:pattern <i>value</i>="\d{1}-\d{4}-\d{4}-\d{1}"/&gt;<br />27:      &lt;/xsd:restriction&gt;<br />28:    &lt;/xsd:simpleType&gt;<br />29:<br />30:  &lt;/xsd:schema&gt;<br /></p></div></div></div></div></div></div></div></div></div></div>
<img src ="http://www.blogjava.net/fortune/aggbug/37659.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-27 18:01 <a href="http://www.blogjava.net/fortune/archive/2006/03/27/37659.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML Schema用法</title><link>http://www.blogjava.net/fortune/archive/2006/03/27/37585.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 27 Mar 2006 05:03:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/27/37585.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/37585.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/27/37585.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/37585.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/37585.html</trackback:ping><description><![CDATA[
		<font color="#003399">
				<p>你现在应该知道XML只说明数据的结构而并不关心数据是如何具体描述的、数据是否正确。XML文档的强制性结构化需求是通过DTD（文档类型说明）来实现的。那就是本系列文章中先前讲述的主题。在本文里，我们概要介绍DTD所存在的缺点，讨论新型的更为强大的标准XML Schema。</p>
				<p>DTD的麻烦</p>
				<p>使用DTD虽然在指定许可的元素、需要的元素以及给定XML文档中如何组织元素等方面给我们以较大的方便，但是，一旦你想针对特定元素施加数据类型就会遇到麻烦了。DTD规范严格地定义了结构，但只支持相对功能较弱的内容类型规范，而对强制性结构化却无计可施，比如名为Date 的数据如何规定它必须包含有效值呢？ </p>
				<p>这就要指望XML Schema了，XML Schema目前作为建议已经于2001年提交给了W3C ，这意味着它最终将成为一般用途的建议标准。假如你对此感兴趣，你不妨到W3C网站找些官方文档和内容简介之类的材料来看看。注意，其他schema定义也是有的，包括日本的标准RELAX 和微软公司的XDR。可是，XML Schema是唯一受到W3C成为的建议标准，所以我在这篇文章中只对它进行阐述。</p>
				<p>XML Schema不仅可以让你定义XML文档的结构而且还允许你约束文档的内容，这就不同于DTD了。另外，一个 XML Schema自身就是一个XML文档，其基于标签的语法比DTD中的特殊字符要清楚多了。</p>
				<p>
						<br />Schema概述</p>
				<p>XML Schema是用一套预先规定的XML元素和属性创建的，这些元素和属性定义了文档的结构和内容模式。相应的一套精巧的规则（这些规则却很有意思的用DTD来表示）指定了每个Schema元素或者属性的合法用途。如果违反这些规则解析器就会拒绝解析你的Schema以及任何同它相联系的文档。</p>
				<p>现在让就让我们来看看清单A中显示的XML Schema示例，该例对我们以前在清单B中用到的图书目录进行了说明。清单B有了点小改动：作为根元素的catalog现在有了两个新属性，它们通过清单A中的catalog schema与之关联。</p>
				<p>你再看catalog schema，很快你就会注意到它包含了标准的XML头&lt;?xml version = "1.0"?&gt;，这表示schema自己就是一个XML文档。而任何schema的根元素都必须是schema，它有一个或者多个说明自己的属性。在这种情况下，schema的namespace定义属性（xmlns）会定义名称空间为xs，它将用作文档中所有元素的根名称空间。</p>
				<p>
						<br />--------------------------------------------------------------------------------</p>
				<p>什么是名称空间<br />XML把名称空间定义为包装XML元素在一起供以后重用的方式。为了使用XML文档的名称空间中定义的元素，你必须通过xmlns属性声明你希望采用名称空间。你还必须为该名称空间定义快捷方式的前缀（例如xs:）作为你文档中的根元素，从而使得名称空间在文档中都可用。前缀是用于文档的任何导入名称空间的元素的标识符。这一过程就如同在Visual Basic中给库加索引或者导入模块；C++、Java或者.NET下的名称空间也具有同样的含义。</p>
				<p>
						<br />--------------------------------------------------------------------------------</p>
				<p>我们的schema示例中接下来的元素是annotation，它的作用是代表同其父元素有关的文档。annotation可以包含两个子元素之一，或者是documentation或者是appinfo，或者两者都包含进去。前者用于可读的文档，而后者则用来保存供应用程序处理的指令。</p>
				<p>接下来我们定义了两个主要的元素（根元素catalog及其子元素book），它们用在书目文档内，后者采用了两个element元素。这些元素都包含了定义名字的属性和各个元素准许的内容。在这种情况下，catalog元素被定义为catalogtype类型，而book元素则被定义为elementtype类型；这两种类型以后还要在schema文档中被定义。</p>
				<p>什么是类型？<br />我已经说过了，XML Schema可以让你把XML文档中的元素声明为特定的类型，准许解析器检查文档的内容及其结构。XML Schem定义了两种主要的数据类型：预定义简单类型和复杂类型。这两种数据类型之间的主要区别是复杂类型可以象数据一样包含其他元素而简单类型则只能包含数据。简单类型给予了XML Schema低级类型检查能力，允许你把元素定义为图A中的任何类型之一。</p>
				<p>图A</p>
				<p>简单类型 定义</p>
				<p>string 字符串数据。</p>
				<p>boolean 二元类型的True或者False。</p>
				<p>date 历法日期，格式是CCYY-MM-DD。</p>
				<p>dateTime 历法日期和时间。</p>
				<p>time 24小时格式的时间可根据时区调节。</p>
				<p>decimal 任意精度和位数的十进制数。</p>
				<p>integer 整数</p>
				<p>float 标准的32位浮点数。</p>
				<p>
						<br />XML Schema预定义简单类型</p>
				<p>
						<br />你也可以定义自己的简单类型。为了更深入地了解各种XML Schema数据类型，请参看W3C网站上的“XML Schema Part 2: DataTypes”。</p>
				<p>复杂类型由complexType元素定义，它通常至少拥有一个name属性，用在声明其他元素时索引类型，除非它位于某一元素之内（参见下一节）。所有的复杂类型都会包含一个内容定义类型，其主要功能是定义类型能包含的内容模式。某些可用的内容模式请见图B。</p>
				<p>图B</p>
				<p>复杂类型 定义</p>
				<p>sequence 在其定义范围之内的所有元素都必须按顺序出现，范围由minOccurs和 maxOccurs指定。</p>
				<p>choice 其范围内有且只有一个元素必须出现。</p>
				<p>any 定义的任何元素都必须出现。</p>
				<p>simpleContent 这种复杂类型只包含了非嵌套元素。可以通过包含扩展元素的方式扩展先前定义的简单类型。</p>
				<p>complexContent 这种复杂类型只能包含其他元素。可以通过包含扩展元素的方式扩展先前定义的复杂类型。</p>
				<p>attribute 这种复杂类型只能包含命名属性。</p>
				<p>
						<br />一些准许的XML Schema复杂类型</p>
				<p>我们示例schema中的第一个complexType元素定义了booktype类型，你能从文档注释元素中看出，该类型给目录中单一的书建模型。Booktype包含一个sequence元素，通过它告诉解析器这种复杂类型的元素必须按照同样准确的顺序包含出现在sequence标签内出现的所有元素。就booktype而言，元素author、title、genre、price和publish_date都必须出现在 booktype元素之内。</p>
				<p>Description又是怎么一回事呢？它出现在sequence元素内，有没有这个必要呢？当然没有。description元素有一个minOccurs属性，它定义了复杂类型中元素可以出现的最小次数。在这种情况下，minOccurs的值是零，因此description是一个可选的元素。</p>
				<p>author元素也是这样。它有一个maxOccurs属性，但却没有设值，意思是说author元素可以在sequence中出现无限次，显然，一本图书的作者至少有一个但却不一定只有一个。既没有minOccurs也没有maxOccurs属性的元素必须而且仅仅只能在sequence中出现一次，因此，booktype sequence中的所有其他元素都是必要的而且只能出现一次。</p>
				<p>在我们的示例catalog schema中定义的第二个同时也是最后一个复杂类型是catalogtype复杂类型。它也是包含一个以上的sequence，你可以从无界的maxOccurs属性看出这一点。</p>
				<p>深入解释<br />看你的背景知识有多少了，本文用到的示例schema的结构对你来说要不本该如何要不只会叫你发昏，对book和catalog元素不采用正规复杂类型声明来定义catalog schema也是可能的，清单C就是这样。注意，清单C中的complexType元素嵌套在了element元素之内，catalog的sequence元素的子元素具有一个ref属性通过它告诉解析器它有一个引用指向先前定义的book元素。</p>
				<p>我曾经听到很多人这样问：“很好，如果是这样的话，那么你为什么要采用以上那些费工夫的办法呢？”很简单，我们绕来饶去只是为了说明XML Schema的重要一点：它是可扩展的。通过定义类型的方式你就可以在多个文档中重用它们，甚至还可以用不同的schema对其进行扩展，这就像你在开发应用程序的时候重用或者扩展抽象数据类型或对象是一个道理。</p>
				<p>
						<br />工具</p>
				<p>到目前为止，你应该意识到XML Schema的语法并不简单。虽然可以用简单的文本编辑器手工创建schema，不过，这样做也许会叫你累得吐血。为了更好地利用它，你可以采用若干种XML工具，最近出现的一些工具甚至提供了创建XML Schema的图形界面。XML Spy和Cape Clear Studio都是具有XML Schema创建功能的全方位XML综合开发环境。dtd2xs是一种DTD-to-XML的Schema转换工具，它有两种形式：单独运行的应用程序和Java类。同DTD一样，标准的XML Schema定义非常多，你可以根据自己的需要在应用程序的开发中采用。</p>
				<p>
						<br />结论<br />XML Schema具有强制文档内容和结构的能力，它是XML世界中的一种不但重要而且强大的新标准。在这篇文章里，我仅仅浮光掠影地大致解释了其基本原理，但我希望这些阐述能给你打下一个继续前进的基础。</p>
		</font>
<img src ="http://www.blogjava.net/fortune/aggbug/37585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-27 13:03 <a href="http://www.blogjava.net/fortune/archive/2006/03/27/37585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设置 SAX 解析器</title><link>http://www.blogjava.net/fortune/archive/2006/03/26/37502.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Sun, 26 Mar 2006 13:44:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/26/37502.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/37502.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/26/37502.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/37502.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/37502.html</trackback:ping><description><![CDATA[
		<blockquote>本文是技巧文章系列的第一篇文章，这些技巧文章将作为在 Java 编程语言中使用 XML 的综合指南。 我从讨论 SAX API 开始。本篇技巧文章回顾了如何获取 SAX 解析器实例以及如何对该解析器设置各种功能和属性。</blockquote>
		<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
		<!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
		<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
		<p>在 Java 中使用 XML 是一个内容相当丰富的主题；可以使用多个 API，而且许多 API 使得使用 XML 简单得如同从文本文档读取行。基于树的 API（如 DOM）展现了一个内存中的 XML 结构，该结构对于 GUI 和编辑器来说是最理想的，基于流的 API（如 SAX）对于只需要获取文档数据的高性能应用程序来说很重要。在本技巧文章系列中，我将从基础知识开始一步步地教您如何在 Java 中使用 XML。同时，您将学习许多甚至连众多专业人士都不知道的诀窍，所以即使您已经具有一些 XML 经验，也应该仔细阅读本教程。 </p>
		<p>我从 SAX（Simple API for XML）开始。虽然该 API 或许是 Java 和 XML API 中最难以掌握的，但它可能也是功能最强的 API。另外，大多数其它 API 实现（象 DOM 解析器、JDOM 和 dom4j 等）都部分地基于 SAX 解析器。对于用 XML 和 Java 语言所做的每一件事情，理解 SAX 会给予您一个良好的开端。特别在本篇技巧文章中，我将讨论如何获取 SAX 解析器实例以及如何对该解析器设置一些基本功能和属性。</p>
		<p>
				<i>
						<b>注</b>：我假设您已经下载了一个符合 SAX 的解析器（如 Apache Xerces-J）（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/tips/x-tipsaxp/index.html#3"><font color="#996699">参考资料</font></a>以获取链接）。Apache 站点有大量关于如何进行设置的信息，但是，基本上您只需要将已下载的 JAR 文件放入 <code>CLASSPATH</code> 中。这些示例假设您的解析器可用。 </i>
		</p>
		<p>
				<a name="0">
						<span class="atitle">
								<font face="Arial" size="4">获取解析器</font>
						</span>
				</a>
		</p>
		<p>使用 SAX 的第一步实际上是获取解析器实例。在 SAX 中，由 <code>org.xml.sax.XMLReader</code> 类的实例表示解析器。我在上一篇技巧文章（“Achieving vendor independence with SAX”— 请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/tips/x-tipsaxp/index.html#3"><font color="#996699">参考资料</font></a>）中对它进行了详细讨论，所以我将不会在这里花大量的时间在上面。清单 1 显示了在无需编写与供应商相关的代码的情况下获取新 SAX 解析器实例的正确方法。 </p>
		<br />
		<a name="c1">
				<b>清单 1. 获取 SAX 解析器实例</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); 
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>通过使用这个方法，您需要将系统属性 <code>org.xml.sax.driver</code> 设置成想要装入的解析器的类名。这是特定于供应商的类；对于 Xerces，它应该是 <code>org.apache.xerces.parsers.SAXParser</code> 。用 <code>-D</code> 开关将这个参数指定给 Java 编译器： </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser some.sample.Class
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>当然，您要确保指定的类存在并在类路径上。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/xml/tips/x-tipsaxp/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="1">
						<span class="atitle">
								<font face="Arial" size="4">功能</font>
						</span>
				</a>
		</p>
		<p>一旦有了解析器实例，就需要配置它。请注意，这与设置解析器来处理 XML 中的错误、内容或结构不同；相反，配置是实际告诉解析器如何操作的过程。您可以打开验证、关闭名称空间检查及扩展实体。这些行为完全独立于特定的 XML 文档，因此涉及与新解析器实例的交互。 </p>
		<p>
				<i>
						<b>注：</b>对于那些过于急燥的人来说（我知道您不是这样的），我当然会处理内容、错误处理及类似的东西。然而，这些主题将在未来的技巧文章中讨论，所以您还得复查。眼下，我们只关注配置、功能和属性。 </i>
		</p>
		<p>可以用两种方法配置解析器：功能和属性。 <b>功能</b>包括打开或关闭特定功能，比如验证。 <b>属性</b>包括设置解析器所使用的特定项的值，如用来验证所有文档的模式位置。我将先讨论功能，然后在下一节研究属性。 </p>
		<p>功能是通过解析器上名为 <code>setFeature()</code> 的方法设置的，这一点并不奇怪。语法类似于清单 2 所示。 </p>
		<br />
		<a name="c2">
				<b>清单 2. 设置 SAX 解析器的功能</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); 

String featureName = "some feature URI";
boolean featureOn = true;

try {
  parser.setFeature(featureName, featureOn);
} catch (SAXNotRecognizedException e) {
  System.err.println("Unknown feature specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
  System.err.println("Unsupported feature specified: " + e.getMessage());
} catch (SAXException e) {
  System.err.println("Error in setting feature: " + e.getMessage());
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这相当清楚，不需要说明；关键是知道可用于 SAX 解析器的常见功能。每个功能均由一个特定的 URI 标识。可以从 SAX 网站在线获得这些 URI 的完整列表（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/tips/x-tipsaxp/index.html#3"><font color="#996699">参考资料</font></a>）。一些最常见的功能是验证和名称空间处理。清单 3 显示了设置这两种属性的示例。 </p>
		<br />
		<a name="c3">
				<b>清单 3. 一些常见功能</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); 

try {
  // Turn on validation
  parser.setFeature("http://xml.org/sax/features/validation", true);
  // Ensure namespace processing is on (the default)
  parser.setFeature("http://xml.org/sax/features/namespaces", true);
} catch (SAXNotRecognizedException e) {
  System.err.println("Unknown feature specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
  System.err.println("Unsupported feature specified: " + e.getMessage());
} catch (SAXException e) {
  System.err.println("Error in setting feature: " + e.getMessage());
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>请注意，虽然解析器有几个标准 SAX 功能，但这些解析器可以自由地添加自己的特定于供应商的功能。例如，Apache Xerces-J 添加了一些考虑动态验证以及遇到致命错误之后继续处理的功能。请参考解析器供应商的文档，以获取相关的功能 URI。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/xml/tips/x-tipsaxp/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="2">
						<span class="atitle">
								<font face="Arial" size="4">属性</font>
						</span>
				</a>
		</p>
		<p>一旦理解了功能，就很容易理解属性。除了属性将对象作为参数而功能获取布尔值外，它们以完全相同的方式操作。我们使用 <code>setProperty()</code> 方法来设置属性，如清单 4 所示。 </p>
		<br />
		<a name="c4">
				<b>清单 4. 设置 SAX 解析器的属性</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); 

String propertyName = "some property URI";

try {
  parser.setProperty(propertyName, obj-arg);
} catch (SAXNotRecognizedException e) {
  System.err.println("Unknown property specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
  System.err.println("Unsupported property specified: " + e.getMessage());
} catch (SAXException e) {
  System.err.println("Error in setting property: " + e.getMessage());
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这里使用相同的错误处理框架，所以您可以容易地在两种类型的配置选项之间复制代码。和功能一样，SAX 提供了一组标准属性，供应商可以添加他们自己的扩展。常见的 SAX 标准的属性考虑到了设置词法处理程序（Lexical Handler）和声明处理程序（Declaration Handler）（我将在以后的技巧文章中讨论这两个处理程序）。像 Apache Xerces 之类的解析器对它们进行了扩展，例如，使它们能够设置输入缓冲区大小以及要在验证中使用的外部模式的位置。清单 5 显示了几个实际使用中的属性。</p>
		<br />
		<a name="c5">
				<b>清单 5. 一些常见属性</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); 

try {
  // Set the chunk to read in by SAX
  parser.setProperty("http://apache.org/xml/properties/input-buffer-size", 
      new Integer(2048));
  // Set a LexicalHandler
  parser.setProperty("http://xml.org/sax/properties/lexical-handler", 
      new MyLexicalHandler());
} catch (SAXNotRecognizedException e) {
  System.err.println("Unknown feature specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
  System.err.println("Unsupported feature specified: " + e.getMessage());
} catch (SAXException e) {
  System.err.println("Error in setting feature: " + e.getMessage());
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/fortune/aggbug/37502.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-26 21:44 <a href="http://www.blogjava.net/fortune/archive/2006/03/26/37502.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>xsd的两个例子</title><link>http://www.blogjava.net/fortune/archive/2006/03/26/37498.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Sun, 26 Mar 2006 12:47:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/26/37498.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/37498.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/26/37498.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/37498.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/37498.html</trackback:ping><description><![CDATA[
		<p>noNamspace schema的：<br /><br />&lt;?xml version="1.0" encoding="gb2312"?&gt;<br />&lt;!-- PRODUCTDATA是根元素--&gt;<br />&lt;PRODUCTDATA xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" xsi:noNamespaceSchemaLocation="F:\XML\2\BookSaleS.XSD"&gt;<br /> &lt;PRODUCT&gt;<br />  &lt;BookTitle&gt;JAVA核心技术&lt;/BookTitle&gt;<br />  &lt;BookISBN&gt;I001&lt;/BookISBN&gt;<br />  &lt;FAuthor&gt;John Sun&lt;/FAuthor&gt;<br />  &lt;LAuthor&gt;May Rose&lt;/LAuthor&gt;<br />  &lt;BookPrice&gt;45&lt;/BookPrice&gt;<br /> &lt;/PRODUCT&gt;<br />&lt;/PRODUCTDATA&gt;</p>
		<p>
				<br />下面是XSD文件（BookSales.xsd）</p>
		<p>&lt;xsd:schema xmlns:xsd="<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>"&gt;<br /> &lt;xsd:element name="PRODUCTDATA" type="PRODATA"/&gt;<br /> &lt;xsd:complexType name="PRODATA"&gt;<br />  &lt;xsd:sequence&gt;<br />   &lt;xsd:element name="PRODUCT" type="PROC"/&gt;<br />  &lt;/xsd:sequence&gt;<br /> &lt;/xsd:complexType&gt;<br /> &lt;xsd:complexType name="PROC"&gt;<br />  &lt;xsd:sequence&gt;<br />   &lt;xsd:element name="BookTitle" type="xsd:string"/&gt;<br />   &lt;xsd:element name="BookISBN" type="xsd:string"/&gt;<br />   &lt;xsd:element name="FAuthor" type="xsd:string"/&gt;<br />   &lt;xsd:element name="LAuthor" type="xsd:string"/&gt;<br />   &lt;xsd:element name="BookPrice" type="xsd:positiveInteger"/&gt;<br />  &lt;/xsd:sequence&gt;<br /> &lt;/xsd:complexType&gt;<br />&lt;/xsd:schema&gt;<br /><br />有命名空间的：<br />&lt;?xml version="1.0" encoding="GBK"?&gt;<br />&lt;qqq:MOVIEINFO xmlns:qqq="n" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" xsi:schemaLocation="n<br />F:\4\4.2\Movie.xsd"&gt;<br /> &lt;MOVIES&gt;<br />  &lt;MOVIE ID="Q0024"&gt;<br />   &lt;MOVIETYPE&gt;<br />    &lt;ROMANTIC&gt;浪漫&lt;/ROMANTIC&gt;<br />   &lt;/MOVIETYPE&gt;<br />   &lt;MOVIEDATE&gt;2003-12-12&lt;/MOVIEDATE&gt;<br />   &lt;MOVIENAME&gt;人鬼情未了&lt;/MOVIENAME&gt;<br />   &lt;PLAYACTORS&gt;<br />    &lt;PLAYACTOR&gt;Tom1&lt;/PLAYACTOR&gt;<br />    &lt;PLAYACTOR&gt;Tom2&lt;/PLAYACTOR&gt;<br />    &lt;PLAYACTOR&gt;Tom3&lt;/PLAYACTOR&gt;<br />    &lt;PLAYACTOR&gt;Tom3&lt;/PLAYACTOR&gt;<br />   &lt;/PLAYACTORS&gt;<br />   &lt;DIRECT&gt;Tom Jone&lt;/DIRECT&gt;<br />   &lt;HORTATION&gt;100万&lt;/HORTATION&gt;<br />  &lt;/MOVIE&gt;<br />  &lt;MOVIE ID="Q0404"&gt;<br />   &lt;MOVIETYPE&gt;<br />    &lt;COMEDY&gt;浪漫&lt;/COMEDY&gt;<br />   &lt;/MOVIETYPE&gt;<br />   &lt;MOVIEDATE&gt;2003-12-12&lt;/MOVIEDATE&gt;<br />   &lt;MOVIENAME&gt;人鬼情未了&lt;/MOVIENAME&gt;<br />   &lt;PLAYACTORS&gt;<br />    &lt;PLAYACTOR&gt;Tom1&lt;/PLAYACTOR&gt;<br />    &lt;PLAYACTOR&gt;Tom2&lt;/PLAYACTOR&gt;<br />    &lt;PLAYACTOR&gt;Tom3&lt;/PLAYACTOR&gt;<br />    &lt;PLAYACTOR&gt;Tom3&lt;/PLAYACTOR&gt;<br />   &lt;/PLAYACTORS&gt;<br />   &lt;DIRECT&gt;Tom Jone&lt;/DIRECT&gt;<br />   &lt;HORTATION&gt;100万&lt;/HORTATION&gt;<br />  &lt;/MOVIE&gt;<br /> &lt;/MOVIES&gt;<br />&lt;/qqq:MOVIEINFO&gt;</p>
		<p>
				<br />XSD文件：(Movie.xsd)</p>
		<p>&lt;s:schema xmlns:s="<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>" targetNamespace="n" xmlns:a="n"&gt;<br /> &lt;s:include schemaLocation="Id.xsd"/&gt;<br /> &lt;s:element name="MOVIEINFO" type="a:suType"/&gt;<br /> &lt;s:complexType name="suType"&gt;<br />  &lt;s:sequence&gt;<br />   &lt;s:element name="MOVIES" type="a:ppType"/&gt;<br />  &lt;/s:sequence&gt;<br /> &lt;/s:complexType&gt;<br /> &lt;s:complexType name="ppType"&gt;<br />  &lt;s:sequence&gt;<br />   &lt;s:element name="MOVIE" type="a:uuType" maxOccurs="5"/&gt;<br />  &lt;/s:sequence&gt;<br /> &lt;/s:complexType&gt;<br /> &lt;s:complexType name="uuType"&gt;<br />  &lt;s:sequence&gt;<br />   &lt;s:element name="MOVIETYPE" type="a:prd"/&gt;<br />   &lt;s:element name="MOVIEDATE" type="s:string"/&gt;<br />   &lt;s:element name="MOVIENAME" type="s:string"/&gt;<br />   &lt;s:element name="PLAYACTORS" type="a:pod"/&gt;<br />   &lt;s:element name="DIRECT" type="s:string"/&gt;<br />   &lt;s:element name="HORTATION" type="s:string"/&gt;<br />  &lt;/s:sequence&gt;<br />  &lt;s:attribute name="ID" type="a:ppp"/&gt;<br /> &lt;/s:complexType&gt;<br /> &lt;s:complexType name="prd"&gt;<br />  &lt;s:choice&gt;<br />   &lt;s:element name="DROLLNESS" type="s:string"/&gt;<br />   &lt;s:element name="ROMANTIC" type="s:string"/&gt;<br />   &lt;s:element name="COMEDY" type="s:string"/&gt;<br />   &lt;s:element name="DRAMA" type="s:string"/&gt;<br />   &lt;s:element name="ACTION" type="s:string"/&gt;<br />  &lt;/s:choice&gt;<br /> &lt;/s:complexType&gt;<br /> &lt;s:complexType name="pod"&gt;<br />  &lt;s:sequence&gt;<br />   &lt;s:element name="PLAYACTOR" type="s:string" maxOccurs="5"/&gt;<br />  &lt;/s:sequence&gt;<br /> &lt;/s:complexType&gt;<br />&lt;/s:schema&gt;</p>
		<p>XSD文件：（ID.xsd）</p>
		<p>&lt;xsd:schema targetNamespace="n" xmlns:xsd="<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>"&gt;<br /> &lt;xsd:simpleType name="ppp"&gt;<br />  &lt;xsd:restriction base="xsd:string"&gt;<br />   &lt;xsd:pattern value="[Q]{1}\d{4}"/&gt;<br />  &lt;/xsd:restriction&gt;<br /> &lt;/xsd:simpleType&gt;<br />&lt;/xsd:schema&gt;<br /></p>
<img src ="http://www.blogjava.net/fortune/aggbug/37498.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-26 20:47 <a href="http://www.blogjava.net/fortune/archive/2006/03/26/37498.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>给XML文件定义DTD </title><link>http://www.blogjava.net/fortune/archive/2006/03/24/37150.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Fri, 24 Mar 2006 02:13:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/24/37150.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/37150.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/24/37150.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/37150.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/37150.html</trackback:ping><description><![CDATA[
		<table class="tablenormal">
				<tbody>
						<tr>
								<td valign="top" height="150">
										<!--帖子评价 -->
										<!--是否正解 -->
										<!--内容 -->近来研究XML，发现有必要对XML文件有更细致的了解<br />找来些东东，很早了，希望有用。。。<br /><br />    DTD实际上可以看作一个或多个XML文件的模板，这些XML文件中的元素、元素的属性、元素的排列方式/顺序、元素能够包含的内容等，都必须符合DTD中的定义。XML文件中的元素，即我们所创建的标记，是根据我们应用的实际情况来创建的。想要创建一份完整性高、适应性广的DTD是非常困难的，因为各行各业都有他们自己的行业特点，所以DTD通常是以某种应用领域为定义的范围，如：医学、建筑、工商、行政。DTD定义的元素含盖范围越广泛，那么就越复杂。<br /><br />    DTD可以是一个完全独立的文件，也可以在XML文件中直接设定。所以，DTD分为外部DTD（在XML文件中调用另外已经编辑好的DTD）和内部DTD（在XML文件中直接设定DTD）两种。比如，有几十家相互联系的、合作伙伴关系的公司、厂商，他们相互之间的交换电子文档都是用XML文档。那么我们可以将这些XML文档的DTD放在某个地方，让所有交换的XML文档都使用此DTD，这是最方便的做法，同时也适用于公司内部的XML文件使用。<br /><br />内部DTD<br /><br />内部DTD是在XML文件的文件序言区域中定义的。语法：<br /><br />〈!DOCTYPE element-name[........<br /><br />]〉  <br /><br /><br />〈!DOCTYPE ：表示开始设定DTD，注意DOCUTYPE是大写。<br /><br />Element-name ：指定此DTD的根元素的名称，一个XML文件只能有一个根元素。注意，如果 XML文件使用了DTD，那么文件中的根元素就在这里指定。<br /><br />[.........]〉 ：在[ ]标记里面定义XML文件使用元素，然后用〉结束DTD的定义。<br /><br />下面，我们来看一下怎样给XML文件定义DTD，请见例1。<br /><br />例1中的DTD定义区可以看作是一个DTD定义的大概框架，为其他XML文件定义DTD，结构和例1的DTD差不多，只是可能需要添加、删除或者更改一些东西而已。在DTD定义的中间是元素设定，这是一个DTD的最主要部分，其主要语法如下：<br /><br />〈!ELEMENT element-name element-definition〉  <br /><br /><br />〈!ELEMENT：表示开始元素设置，注意此处ELEMENT关键字是大写。<br /><br />element-name：表示要设置的元素的名称。<br /><br />element-definition：指明要对此元素进行怎样的定义，就是说〈元素〉...〈/元素〉之间能够包含什么内容，是其他元素还是一般性的文字。<br /><br />在例1中，大家可以看到，〈!ELEMENT 参考资料 (书籍)〉这个元素设定是声明了“参考资料”这个元素，并且它是作为“书籍”这个元素的父元素。〈!ELEMENT 书籍 (名称,作者,价格)〉这个元素设定声明了“书籍”这个元素，并且它是作为“名称”、“作者”、“价格”这三个元素的父元素。而〈!ELEMENT 名称 (#PCDATA)〉这个元素设定声明了“名称”这个元素，但是此元素仅仅包含一般文字，是基本元素，这是由#PCDATA关键字定义的。<br /><br />在元素设置中，如果元素包含多个子元素，如：〈!ELEMENT 书籍 (名称,作者,价格)〉这种含多个子元素的声明，那么“名称”、“作者”、“价格”这些标记在XML文件中必须以上面排列的顺序出现，每个标记必须而且只能够出现一次。如果在设定元素时，按照〈!ELEMENT 书籍ANY〉，这样在元素下就可以包含任意被设定过的元素，出现的次数和顺序也不受限制，并且在该元素下，除了可以包含子元素以外，还能够包含一般的文字。有时候，在XML文件中，一个标记可能多次出现（或者不出现），那么我们除了在它们的父元素中用ANY关键字之外，还可以在元素的旁边加上特定的符号来控制标记出现的次数。这些符号见表1。<br /><br />表1  符号<br />代表标记出现的次数<br /><br />？<br />不出现或只出现一次 <br /><br />*<br />不出现或可出现多次<br /><br />+<br />必须出现一次以上<br /><br />无符号<br />只能出现一次<br /><br /><br />例如：〈!ELEMENT 参考资料(书籍,报纸+,杂志?,网站)〉这个元素设定，“书籍”标记在XML文件中可以不出现或者出现多次；“报纸”标记必须出现一次以上；“杂志”标记可以不出现或只出现一次；而“网站”标记必须出现而且只能出现一次。<br /><br />在一些父元素的声明中，有可能它包含的子元素是在多个子元素中选择一个来使用，那么我们声明此父元素时，就可以把它声明成选择性元素，例如：〈!ELEMENT 配偶 (妻子|丈夫)〉。可供选择的子元素用“|”分隔，这样，我们在XML文件中可以这样写：<br /><br />〈配偶〉<br /><br />〈丈夫〉张三〈/丈夫〉<br /><br />〈/配偶〉  <br /><br /><br />只从中选择一个子元素。<br /><br />在我们的XML文件中，还可能包括很多“空元素”，即：元素是单独存在的，没有〈/元素〉这样的结束标记。那么在DTD中是用EMPTY关键字来声明的。如：〈!ELEMENT 元素名 EMPTY〉。在XML文件中，空元素不需要结束标记，但必须以〈/空元素名〉这样的写法。<br /><br />在DTD中，还可以声明一些称为Entity的东西，让DTD和XML文件使用。我们可以把Entity看作是一个常量，它有一定的值。在DTD中，Entity的声明语法为：〈!ENTITY entity-name entity-definition〉。例如：我们在DTD中声明〈!ENTITY PC "(#PCDATA)"〉 ，那么在后面的元素设定中，就可以使用这个Entity来代替“(#PCDATA)”这个字符串，如：〈!ELEMENT 作者 (#PCDATA)〉可以写成〈!ELEMENT 作者 &amp;&amp;PC;〉。引用Entity的时候，必须要在Entity名称前面加上“&amp;&amp;”符号，后面加上“；”符号。<br /><br />在例1中，〈!ATTLIST 价格 货币单位 CDATA #REQUIRED〉这一句是设定元素的属性，关于元素属性设置的语法为：〈!ATTLIST element-name attribute-name Type Default-value〉 。其中，〈!ATTLIST是开始属性的设定（注意大小写）。element-name是指明此属性设定是针对什么元素的；attribute-name是设定的属性的名称；Type是该属性的属性值的类别，属性值有多种，可以是一般的文字，或从几种属性值中取一种等，属性值的种类见表2。Default-value是指该属性的内定值种类，有四种不同的属性内定值（见表3）。<br /><br />下面我们举几个例子来看一下几个常用的元素属性的设定。例：<br /><br />〈!ATTLIST 姓名 性别 (男|女) "男"〉 <br /><br />此元素属性设定是为“姓名”这个元素设定一个名为“性别”的属性，此属性的属性值类别是Enumerated，取值范围为“男”或者“女”（用“|”分隔）。如果在XML文件中没有为此属性赋值，那么就取值为“男”，因为属性内定值是一个字符串“男”。<br /><br />〈!ATTLIST 姓名 号码 ID #REQUIRED〉<br /><br />该属性设定是为“姓名”元素设定一个名为“号码”的属性，属性值类别是ID，意味着在XML文件中为此属性赋值的时候，值在此XML文件中是唯一的，如在同一份XML文件中出现下面的XML语句：<br /><br />〈姓名 号码="1234567"〉张三〈/姓名〉<br /><br />〈姓名 号码="1234567"〉李四〈/姓名〉<br /><br />注意：“号码”属性的值重复了，这样，在解析过程中将会出现错误信息。此属性设定中的属性内定值为#REQUIRED，表示这个属性在XML文件的〈姓名〉标记中必须出现，否则解析会发生错误。<br /><br />〈!ATTLIST 电话号码 国家代码 CDATA #FIX "86"〉 <br /><br />该属性设定是为“电话号码”这个元素设定一个名为“国家代码”的属性，该属性的值是一般的文字。在〈电话号码〉标记中不能够设定该属性，因为这个属性被设为具有固定值的属性（#FIX关键字），解析器会自动地将该属性以及值“86”加到〈电话号码〉标记中。<br /><br />表2  属性值类别<br />描述 <br /><br />cdata<br />属性值仅仅是一般的文字。 <br /><br />enumerated<br />列出该属性的取值范围，一次只能有一个属性值能够赋予属性。 <br /><br />nmtoken<br />表示属性值只能由字母、数字、下划线、. 、：、-这些符号组成。 <br /><br />nmtokens<br />表示属性值能够由多个nmtoken组成，每个nmtoken之间用空格隔开。 <br /><br />id<br />该属性在xml文件中是唯一的，常用来表示人的身份证号码。 <br /><br />idref<br />表示该属性值是参考了另一个id属性。 <br /><br />idrefs<br />表示该属性值是参考了多个id属性，这些id属性的值用空格隔开。 <br /><br />entity<br />表示该属性的设定值是一个外部的entity，如一个图片文件。 <br /><br />entities<br />该属性值包含了多个外部entity，不同的entity之间用空格隔开。 <br /><br />notation<br />属性值是在dtd中声明过的notation（声明用什么应用软件解读某些二进制文件，如图片）。<br /><br /><br />在XML的规范中，还规定了两个内定的属性，即：xml:space和xml:lang ，内定的属性名称以xml:开头，而你自己定义的属性名不能以xml:开头，否则在解析时会发生错误。<br /><br />我们前面已经讲过，空白格在XML文件是有含义的，xml:space属性就是来设置解析器将XML文件中的空白格传给应用程序后的处理方法。xml:space是一个Enumerated类型的属性，只能够在default和preserver之间取值。xml:space="defaule"表示解析器将空白格传递给应用程序后，由应用程序内定的方法来处理这些空白格。如果没有设定xml:space属性，则解析器会默认用default来设定该属性。xml:space="preserver"是表示解析器将空白格传递给应用程序后，要求应用程序保留这些空白格。<br /><br />xml:lang属性是用来设置标记中的文字信息是使用哪种语言，ISO-639规定了不同语言的代表缩写，如：xml:lang="en" 表示英文；xml:lang="la"表示拉丁文；xml:lang="zh" 表示中文资料；xml:lang="zh-CN" 表示中文（简体）；xml:lang="zh-TW" 表示中文（繁体）。系统内定是xml:lang="en"，即标记中间的文字信息都是英文。<br /><br />外部DTD<br /><br />外部DTD是一个独立于XML文件的文件，实际上也是一个文本文件，只是使用.dtd为文件扩展名。因为外部DTD独立于XML文件，那么它可以供多个XML文件使用，就像用同一个模板可以写出多个不同内容的文件一样，这多个XML文件因为是引用同一个外部DTD，所以它们的结构大致相同。<br /><br />外部DTD的创建方式、语法和内部DTD是一样的，把例1的内部DTD的例子用外部DTD来写，文件如下所示。文件存为后缀名为 .dtd的文件。<br /><br />〈?xml version="1.0" encoding="GB2312" ?〉<br /><br />〈!ELEMENT 参考资料 (书籍*)〉<br /><br />〈!ELEMENT 书籍 (名称,作者,价格)〉<br /><br />〈!ELEMENT 名称 (#PCDATA)〉<br /><br />〈!ELEMENT 作者 (#PCDATA)〉<br /><br />〈!ELEMENT 价格 (#PCDATA)〉<br /><br />〈!ATTLIST 价格 货币单位 CDATA #REQUIRED〉  <br /><br /><br />除了没有内部DTD中的〈!DOCTYPE 参考资料 [.....]〉语句外，其他都一样。而且有关元素数目、排列顺序、空元素设定、选择性元素、Entity声明、属性设定等都和内部DTD是一样的。<br /><br />XML文件使用〈!DOCTYPE element-name SYSTEM DTD-URL〉或者〈!DOCTYPE element-name PUBLIC DTD-name DTD-URL〉来引用创建好的外部DTD文件。<br /><br />表3  属性内定值<br />描述<br /><br />#required<br />表示在标记中必须出现此属性。 <br /><br />#implied<br />标记中可以不出现此属性。 <br /><br />#fix<br />属性的值是固定的某个值。 <br /><br />字符串<br />标记中如没有指定属性的值，那么此字符串就是此属性的值。<br /><br /><br />此语句必须位于XML文件的文件序言区，其中，〈!DOCTYPE表示开始声明应用外部DTD；element-name是指该DTD的根元素的名称；SYSTEM是指该外部DTD文件是私有的，即我们自己创建的，没有公开发行，只是个人或在公司内部或者几个合作单位之间使用；而PUBIC关键字是指该外部DTD是公用的，经过了公开讨论，用PUBLIC的DTD都有一个逻辑名称——DTD-name，我们必须在调用时指明这个逻辑名称。DTD-URL是用URL的方式指明外部DTD文件的位置。例如，我们这份DTD文件存放在URL为：http://www.xml.com/这个地方，文件名为ckzl.dtd。那么在XML文件中的声明如下：<br /><br />〈?xml version="1.0" encoding="GB2312" ?〉<br /><br />〈!DOCTYPE 参考资料 SYSTEM "http://www.xml.com/ckzl.dtd"〉<br /><br />...  <br /><br /><br />Schema简介<br /><br />DTD的语法相当复杂，并且它不符合XML文件的标准，自成一个体系。上面的介绍也仅仅是作了一个简介，目的是帮助大家能读懂DTD文件以及在必要时创建简单的DTD文件，因为现在很多的XML应用是建立在DTD之上的。<br /><br />另外，一个代替DTD的就是W3C定义的Schema，Schema相对于DTD的明显好处是XML Schema文档本身也是XML文档，而不是像DTD一样使用自成一体的语法。这就方便了用户和开发者，因为可以使用相同的工具来处理XML Schema和其他XML信息，而不必专门为Schema使用特殊工具。Schema简单易懂，懂得XML语法、规则的人都可以立刻理解它。Schema的概念提出已久，但W3C的标准最近才出来，相应的应用支持尚未完善，但采用Schema已成为XML发展的一个趋势。<br /><br /><br /><br />例1<br /><br />DTD定义区:<br /><br />〈?xml version="1.0" encoding="GB2312" ?〉<br /><br />〈!DOCTYPE 参考资料 [<br /><br />〈!ELEMENT 参考资料 (书籍)〉<br /><br />〈!ELEMENT 书籍 (名称,作者,价格)〉<br /><br />〈!ELEMENT 名称 (#PCDATA)〉<br /><br />〈!ELEMENT 作者 (#PCDATA)〉<br /><br />〈!ELEMENT 价格 (#PCDATA)〉<br /><br />〈!ATTLIST 价格 货币单位 CDATA #REQUIRED〉<br /><br />]〉<br /><br />〈参考资料〉<br /><br />〈书籍〉<br /><br />〈名称〉XML入门精解〈/名称〉<br /><br />〈作者〉张三〈/作者〉<br /><br />〈价格 货币单位="人民币"〉20.00〈/价格〉<br /><br />〈/书籍〉<br /><br />〈书籍〉<br /><br />〈名称〉XML语法〈/名称〉<br /><br />〈!-- 即将出版 --〉<br /><br />〈作者〉李四〈/作者〉<br /><br />〈价格 货币单位="人民币"〉18.00〈/价格〉<br /><br />〈/书籍〉<br /><br />〈/参考资料〉 </td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/fortune/aggbug/37150.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-24 10:13 <a href="http://www.blogjava.net/fortune/archive/2006/03/24/37150.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>标题：Xml文档验证—基础篇</title><link>http://www.blogjava.net/fortune/archive/2006/03/23/37094.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Thu, 23 Mar 2006 14:01:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/23/37094.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/37094.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/23/37094.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/37094.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/37094.html</trackback:ping><description><![CDATA[
		<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体">
				<font class="f14">
						<font color="#000099">
								<b>一、Xml可扩展性的优势与隐患 </b>
						</font>
						<br />
						<br />　　从Xml（Extensible Markup Language可扩展标记语言）这个名字就可以知道，Xml是易于扩展的。的确，作为一种描述"元数据"的标记语言，Xml规范虽然为构建Xml文档提供了一些基本语法，但是并没有定义确切的标记，任何人都能够根据需要使用自定义的元素和属性为Xml文档提供结构信息以扩充标记集。 <br /><br />　　Xml的可扩展是不难理解的，作为一种新标记语言，Xml语言提供了一个可扩展的、强有力的标准来描述数据，使得数据可以在应用程序中使用或在不同平台、不同应用中交换。Xml只关心如何描述数据，并不指定如何为一个最终用户或者系统显示数据。（当然，你可以通过Xml相关的其他技术如XPath、XSlt或者程序语言来操纵和显示这些数据）。 <br /><br />　　在这一点上，Xml与同样继承自SGML（Standard Generalized Markup Language 标准通用标记语言）并且也是SGML子集的Html有很大的不同。Html的目的是通过一个（例如一个浏览器）来显示数据，你只能使用那些预先定义的特定标记。例如，要建立一个链接，你必须使用&lt;a&gt;标记，并且，你只能在这个标记内使用"href"属性指定链接目标所在的位置；同样，要在Html中导入一幅图象，你也只能使用&lt;img&gt;标记，并且只能在这个标记中使用"src"属性指定图象文件的路径。其他Html的元素和属性也一样，它们都被预定义了特定的名称。 <br /><br />　　Xml这种允许自由地创建标记和属性的特点为应用带来了极大的方便。根据应用需要，你可以为那些标记指定更有意义的、自描述的名称而不用一味遵循那些有可能并不合适的某种限制。比如，你大可用&lt;Link&gt;取代&lt;a&gt;标记，用"path"取代"href"属性使链接一目了然。放心，这在Xml规范中是允许的。 <br /><br />　　实际上也正是由于Xml可扩展的优点，Xml文档在各个领域（如科技词典、法律词汇表、医学词汇表、计算机词汇表、公用电话交换网络词汇等）的标准化建设中得到了广泛的应用。 <br /><br />　　这种定制Xml文档标记的"自由"无疑具有明显的优势，并且在特定的环境下的确是这样。然而， Xml文档很多时候被用于数据交换，Xml为标记那些可以在应用程序之间以平台无关的方式进行交换的数据提供了一种非常有用而且可以扩展的框架。它被广泛地用于在应用程序对象之间、不同平台应用中，甚至是Internet上交换数据。这个时候，创建你自己的Xml文档元素和属性名字的能力确实需要付出一定的代价，当你想要与其他的不熟悉你的文当结构的客户或者应用程序交换Xml文档时，这种代价尤为突出。所有这些参与者（平台、应用程序及人）都能正确使用这些Xml文档吗？它们中的自定义标记能够被识别吗？ <br /><br />　　乍看起来，这样似乎已经导致了混乱。毕竟，如果每个人都可以使用不遵循任何命名规范的标记来创建Xml文档，其他人怎么能够使用这些文档呢？ <br /><br /><br />　　<font color="#000099"><b>二、Xml验证-自由的相对性 </b></font><br />　　看来，完全遵循xml规范的格式正确的文档并不总能满足需要。许多情况下还需要保证文档的有效性。这时，一种"元数据"文档被创建来定义这个Xml文档中包含什么样的元素、属性和其他项目。有三种这样的"元数据"文档，它们是DTD、XML-DR Schema以及W3C Schema，它们定义了一个Xml文档必须遵循什么样的结构才是有效的。通过定义Xml文档的结构，应用能够在执行任何计算和转换之前对文档进行验证。 <br /><br />　　现在很清楚了，你尽可以在xml文档中自定义所需要的标记以描述数据，任何想使用这个文档的人也可以使用它，只要你为他们提供一个文档是如何组织以及使用什么样的标记描述数据的定义即可！由于XSD Schema是万维网联盟W3C的推荐标准，下面的验证均只针对它展开。 <br /><br /><br /><br />　　<font color="#000099"><b>三、从Xml文档内部引用Xml Schema验证 </b></font><br />　　在创建了一个Xml Schema文档之后，就可以用它来验证xml文档的有效性了。做起来很简单，只需要在xml文档根元素内引用该schema文件就可以了。不过，根据xml schema文档是否包含targetNamespace属性，xml文档内的引用有以下两种方式： <br /><br />　<font color="#0480fb">　1、使用noNamespceSchemaLocation属性引用schema文件 </font><br /><br />　　当xml schema文档不包括targetNamespace属性时，应当通过xml文档根元素的noNamespaceSchemaLocation属性及W3C的schmea实例命名空间(xmlns:xsi="http://www.w3.org/2001/XMLScheam-instance")来引用名xml schema文件。下面的例子引用不包含"targetNamespace"属性的名为"noTargetNS.xsd"的架构文件： </font>
		</span>
		<table width="100%" border="0">
				<tbody>
						<tr>
								<td width="100%" bgcolor="#ffffff">
										<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体">
												<font class="f14">&lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />&lt;Employees Xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance<br />"xsi:noNamespaceSchemaLocation="noTargetNS.xsd"&gt;<br />&lt;Name&gt;LinY&lt;/Name&gt;<br />&lt;Age&gt;42&lt;/Age&gt;<br />&lt;/Employees&gt;</font>
										</span>
								</td>
						</tr>
				</tbody>
		</table>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: 20pt; mso-line-height-rule: exactly">
				<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体">
						<font class="f14">
								<br />
								<br />　<font color="#0480fb">　2、使用schemaLocation属性引用schema文件 </font><br /><br />　　然而，如果xml schmea文件包含了一个targetNamespace 属性，在xml文档中就将通过schemaLocation属性而不是noNamespaceSchemaLocation属性来引用schema文档。而且，这个属性所指定的值必须是完整的。它需要包含以空格分开的两部分，前一部分是Uri，这个Uri与schema文档的targetNamespace属性内部引用的Uri是一致的；后一部分是schema文件完整路径及名称。另外，Xml文档的根元素也必须声明schema实例名字空间(xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance")，下面的例子引用包含"targetNamespace"属性的名为yesTargetNS.xsd架构文件： </font>
				</span>
		</p>
		<table width="100%" border="0">
				<tbody>
						<tr>
								<td width="100%" bgcolor="#ffffff">
										<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体">
												<font class="f14">&lt;?Xml version="1.0" encoding="utf-8" ?&gt;<br />&lt;Employees Xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />xsi:schemaLocation="http://www.tuha.net yesTargetNS.xsd"<br />Xmlns="http://www.tuha.net"&gt;<br />&lt;Name&gt;XiaoM&lt;/Name&gt;<br />&lt;Age&gt;25&lt;/Age&gt;<br />&lt;/Employees&gt;</font>
										</span>
								</td>
						</tr>
				</tbody>
		</table>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: 20pt; mso-line-height-rule: exactly">
				<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体">
						<font class="f14">
								<br />　　在xml文档内部正确地引用schema文件之后，在解析xml文档时将执行验证。 <br /><br />　　<b><font color="#000099">四、在Visual Studio.Net IDE中使用Xml Schmea验证 </font></b><br /><br />　　Visual Studio.Net IDE为使用xml架构提供了丰富的支持。其集成的xml架构设计器，能够以组件拖放的方式创建xml架构文档；集成的xml文档设计器，能够基于现有xml文档创建xml架构。这之后，你可以关联xml文档和xml架构文件并执行xml文档的正确性及有效性验证操作。这样做时，你只需要作简单的代码修改甚至不用手写一行代码就能完整文档验证的所有工作。 <br /><br />　<font color="#0480fb">　1、创建xml架构 </font><br />　　可以通过任何文本编辑器创建xml架构文件，显然，这样做比较麻烦的，你必须熟知架构文档的规范。作为补充，Visual Studio.Net IDE中提供了好几种创建Xml架构文档的简单方式。使用Xml 架构设计器，从工具箱中拖入你需要的节点元素组件，就可以完成xml架构文档创建的绝大部分工作（如果你不需要修改节点数据类型的话，这也是创建xml架构文件的全部工作）。特别地，如果你已经创建了xml文档，你可以基于现有 XML 文件创建架构，通过简单的操作，就可以生成此xml文档应遵循的xml架构文件： <br />　　◇将Xml源文档（.xml 文件）加载到"Xml设计器"中。 <br />　　◇从IDE菜单栏中选择"XML"菜单项并单击"创建架构"。 <br />　　就这么简单，查看项目"所有文件"，你会发现，与xml文档同名的 XML 架构（.xsd 文件）生成了。 <br /><br />　　不过，以这种方法产生xml架构时，所有数据类型都被默认设置为 xsd:string类型，因此，可能需要修改它们以符合 Xml文档的需要。 <br /><br />　　<font color="#0480fb">2、关联xml文档和xml架构文件 </font><br /><br />　　如果已经创建了xml源文件和Xml架构文件，要使该xml架构文件对xml文档发生作用，必须将xml源文件和xml架构文件关联起来。在Visual Studio.Net IDE（集成开发环境）中，实现这一关联非常简单，通过定义Xml文件的targetSchema属性就可以完成： <br />　　◇将Xml 文件加载到"Xml 设计器"中。 <br />　　◇切换到"Xml"视图模式。 <br />　　◇在属性窗口中，从"targetSchema"属性的下拉列表中选择与名字空间相关联的的架构文件。 <br /><br />　　这时你应该会注意到，targetSchema属性的下拉框将列出该项目包括的所有xml架构及一些建议的规范，包括相应的名字空间。这同时也告诉我们，如果所需要的xml架构并不包含在该项目中，你将需要在这里键入将用于验证 XML 文档的架构的统一资源标识符 (URI)。 <br /><br />　　完成这几步后，返回查看你的xml源文件，会发现，在根元素内，xml架构以默认名字空间被引用。 <br /><br />　　附带说明一下，清除targetSchema属性的内容就可以移除xml文档与xml架构间的关联。 <br /><br />　　<font color="#0480fb">3、执行验证操作 </font><br />　　将xml架构文件与 Xml源文件关联后，"Xml 设计器"的验证功能可以检查Xml文件是否有效： <br />　　◇将要检查的 XML 文件加载到"XML 设计器"中。 <br />　　◇从"XML"菜单选择"验证 Xml 数据"。 <br /><br />　　这时，执行验证操作。这一过程也同时检查xml文档的正确性，如果发现错误，状态栏将予以指示。如果发生有效性错误，系统将提示"发现验证错误"并在"任务列表"中提供详细说明，否则，系统提示"未找到验证错误"而通过验证。 </font>
				</span>
		</p>
<img src ="http://www.blogjava.net/fortune/aggbug/37094.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-23 22:01 <a href="http://www.blogjava.net/fortune/archive/2006/03/23/37094.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实战SWT布局</title><link>http://www.blogjava.net/fortune/archive/2006/03/23/37067.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Thu, 23 Mar 2006 09:00:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/23/37067.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/37067.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/23/37067.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/37067.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/37067.html</trackback:ping><description><![CDATA[
		<strong>标准的SWT布局类<br /></strong>FillLayout：在容器中以相同的大小单行或单列的排列组件<br />RowLayout：以单行或多行的方式使用几个选项(fill,wrap,spacing,justify,type)定制组件的排列方式<br />GridLayout：类似于swing的GridLayout的方式以格子的方式排列组件<br />FormLayout（SWT 2.0的新特性）：通过定义组件四个边的“粘贴”位置来排列组件，被引用的相对的组件可以父组件，也可以是同一容器中的其它组件。<br />在SWT中，可以由用户自定义布局类。<br /><br />在简单的布局中，使用FillLayout和RowLayout也许就够用了，也比较简单。但是通常的布局都比较复杂，而且要求很精确。无论复杂程度如何，都可以由GridLayout或FormLayout来完成。通常GridLayout与FormLayout可以做成同样的效果，但是使用FormLayout更有效，不会像GridLayout产生resize导致的布局错位，也更简单。下面通过一个例子简单介绍FormLayout的使用。<br /><br /><b>布局效果</b><br /><img src="http://www.javaresearch.org/members/efly/formlayout.jpg" /><br /><br /><b>布局实施</b><br />1.首先定义窗口和它的空白边<br />Display.getDefault().dispose();  //移去平台核心启动画面<br />        display = new Display();<br />        shell = new Shell(display, SWT.TITLE);<br />        FormLayout layout = new FormLayout();<br />        layout.marginHeight = 10;<br />        layout.marginWidth = 20;<br />        shell.setLayout(layout);<br />        shell.setText("用户登录");<br /><br />2.创建窗口上的元素，其中下面的两个button由一个使用RowLayout的组件来包容。<br />        name = new Label(shell, SWT.NONE);<br />        name.setText("用户名");<br />        nameText = new Text(shell, SWT.SINGLE | SWT.BORDER);<br />        pass = new Label(shell, SWT.NONE);<br />        pass.setText("密码");<br />        passText = new Text(shell, SWT.SINGLE | SWT.BORDER);<br />        passText.setEchoChar('*');<br />        passText.setTabs(2);<br />        bottom = new Composite(shell, SWT.NONE);<br />        RowLayout rowLayout = new RowLayout();<br />        rowLayout.justify = true;  //justify定义组件在容器中分散开，效果类似于swing的FlowLayout<br />        bottom.setLayout(rowLayout);<br /><br />3.定义name标签的位置。它的顶边离父组件（窗口shell）的空白边距离是父组件clientArea（除空白边以外的空间）高度(height)的15%，偏移的点数(points)为0。<br />FormData data = new FormData();<br />        data.top = new FormAttachment(15, 0);<br />        name.setLayoutData(data);<br /><br />4.定义name文本输入的位置。它的顶边在name标签的中心位置（这不是正确的表达，但程序是这样解释，事实上它的中心位置与name标签在同一条水平线上），左边距name标签的右边有10个点。<br />data = new FormData();<br />        data.top = new FormAttachment(name, 0, SWT.CENTER);<br />        data.left = new FormAttachment(name, 10, SWT.RIGHT);<br />        nameText.setLayoutData(data);<br /><br />5.定义pass标签的位置。它的顶边距name标签的底边有10个点数的偏移。<br />data = new FormData();<br />        data.top = new FormAttachment(name, 10, SWT.BOTTOM);<br />        pass.setLayoutData(data);<br /><br />6.定义pass文本输入的位置。它的顶边在name标签的中心位置（同上），左边与name文本框的左边对齐。<br />data = new FormData();<br />        data.top = new FormAttachment(pass, 0, SWT.CENTER);<br />        data.left = new FormAttachment(nameText, 0, SWT.LEFT);<br />        passText.setLayoutData(data);<br /><br />7.定义bottom组件的位置。它的顶边距pass标签的底边15个点数，左边与pass标签的左边对齐，右边与pass文本输入的右边对齐。<br />        data = new FormData();<br />        data.top = new FormAttachment(pass, 15, SWT.BOTTOM);<br />        data.left = new FormAttachment(pass, 0, SWT.LEFT);<br />        data.right = new FormAttachment(passText, 0, SWT.RIGHT);<br />        bottom.setLayoutData(data);<br /><br /><b>完整的源码</b><br />import org.eclipse.swt.SWT;<br />import org.eclipse.swt.events.SelectionAdapter;<br />import org.eclipse.swt.events.SelectionEvent;<br />import org.eclipse.swt.graphics.Rectangle;<br />import org.eclipse.swt.layout.FormAttachment;<br />import org.eclipse.swt.layout.FormData;<br />import org.eclipse.swt.layout.FormLayout;<br />import org.eclipse.swt.layout.RowLayout;<br />import org.eclipse.swt.widgets.Button;<br />import org.eclipse.swt.widgets.Composite;<br />import org.eclipse.swt.widgets.Display;<br />import org.eclipse.swt.widgets.Label;<br />import org.eclipse.swt.widgets.Shell;<br />import org.eclipse.swt.widgets.Text;<br /><br />import cn.com.efly.clientframe.core.Hook;<br /><br />/**<br /> * @author efly<br /> * @version 1.0.0,11/22/02<br /> */<br />public final class LoginUI {<br />    private Display display;<br />    private Shell shell;<br />    private Composite bottom;<br />    private Label name;<br />    private Label pass;<br />    private Text nameText;<br />    private Text passText;<br />    private Button ok;<br />    private Button exit;<br />    private Rectangle clientArea;<br />    private RootHook rootHook;<br /><br />    public LoginUI(Hook hook) {<br />        rootHook = (RootHook) hook;<br />    }<br /><br />    /**<br />     * 显示登陆界面<br />     */<br />    public void show() {<br />        Display.getDefault().dispose();<br />        display = new Display();<br />        clientArea = display.getClientArea();<br />        shell = new Shell(display, SWT.TITLE);<br />        FormLayout layout = new FormLayout();<br />        layout.marginHeight = 10;<br />        layout.marginWidth = 20;<br />        shell.setLayout(layout);<br />        shell.setText("用户登录");<br /><br />        name = new Label(shell, SWT.NONE);<br />        name.setText("用户名");<br />        nameText = new Text(shell, SWT.SINGLE | SWT.BORDER);<br />        pass = new Label(shell, SWT.NONE);<br />        pass.setText("密码");<br />        passText = new Text(shell, SWT.SINGLE | SWT.BORDER);<br />        passText.setEchoChar('*');<br />        passText.setTabs(2);<br />        bottom = new Composite(shell, SWT.NONE);<br />        RowLayout rowLayout = new RowLayout();<br />        rowLayout.justify = true;<br />        bottom.setLayout(rowLayout);<br />        ok = new Button(bottom, SWT.PUSH);<br />        ok.setText("确定");<br />        ok.addSelectionListener(new SelectionAdapter() {<br />            public void widgetSelected(SelectionEvent event) {<br />                ok();<br />            }<br />        });<br />        exit = new Button(bottom, SWT.PUSH);<br />        exit.setText("取消");<br />        exit.addSelectionListener(new SelectionAdapter() {<br />            public void widgetSelected(SelectionEvent event) {<br />                cancel();<br />            }<br />        });<br /><br />        FormData data = new FormData();<br />        data.top = new FormAttachment(15, 0);<br />        name.setLayoutData(data);<br /><br />        data = new FormData();<br />        data.top = new FormAttachment(name, 0, SWT.CENTER);<br />        data.left = new FormAttachment(name, 10, SWT.RIGHT);<br />        nameText.setLayoutData(data);<br /><br />        data = new FormData();<br />        data.top = new FormAttachment(name, 10, SWT.BOTTOM);<br />        pass.setLayoutData(data);<br /><br />        data = new FormData();<br />        data.top = new FormAttachment(pass, 0, SWT.CENTER);<br />        data.left = new FormAttachment(nameText, 0, SWT.LEFT);<br />        passText.setLayoutData(data);<br /><br />        data = new FormData();<br />        data.top = new FormAttachment(pass, 15, SWT.BOTTOM);<br />        data.left = new FormAttachment(pass, 0, SWT.LEFT);<br />        data.right = new FormAttachment(passText, 0, SWT.RIGHT);<br />        bottom.setLayoutData(data);<br /><br />        shell.pack();<br />        Rectangle shellBounds = shell.getBounds();<br />        shell.setLocation(<br />            (clientArea.width - shellBounds.width) / 2,<br />            (clientArea.height - shellBounds.height) / 2);<br /><br />        shell.open();<br /><br />        while (!shell.isDisposed()) {<br />            if (!display.readAndDispatch())<br />                display.sleep();<br />        }<br />    }<br /><br />    private void dispose() {<br />        display.dispose();<br /><br />    }<br /><br />    private void cancel() {<br />        dispose();<br />    }<br /><br />    private void ok() {<br />        verify();<br />    }<br /><br />    private void verify() {<br />        rootHook.runPlatform();<br />    }<br /><br />        public static void main(String[]){<br />                new LoginUI(null).show();<br />        }<br />}<br /><img src ="http://www.blogjava.net/fortune/aggbug/37067.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-23 17:00 <a href="http://www.blogjava.net/fortune/archive/2006/03/23/37067.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Dom4j 学习笔记 </title><link>http://www.blogjava.net/fortune/archive/2006/03/22/36891.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Wed, 22 Mar 2006 09:50:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/22/36891.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/36891.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/22/36891.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/36891.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/36891.html</trackback:ping><description><![CDATA[
		<div class="postbody">
				<p>Dom4j 学习笔记<br />The dom4j Project Homepage: <a href="http://www.dom4j.org/">http://www.dom4j.org</a></p>
				<p>Loading XML Data<br />以下代码从File中或一个URL中读取一个XML文件，并产生一个Document对象。一个Document对象表示了内存中的一棵XML树，可以在这个XML树中进行遍历、查询、修改等操作。</p>
				<p>
						<br />import java.io.*;<br />import java.net.*;<br />import org.dom4j.Document;<br />import org.dom4j.DocumentException;<br />import org.dom4j.io.SAXReader;</p>
				<p>public class XMLLoader {<br />    <br />    private Document doc = null;<br />    <br />    public void parseWithSAX(File file)<br />    throws MalformedURLException, DocumentException {<br />        SAXReader xmlReader = new SAXReader();<br />        this.doc = xmlReader.read(file);<br />        return;<br />    }<br />    <br />    public void parseWithSAX(URL url)<br />    throws MalformedURLException, DocumentException {<br />        SAXReader xmlReader = new SAXReader();<br />        this.doc = xmlReader.read(url);<br />        return;<br />    }<br />}<br />        <br />QName and Namespace<br />QName对象表示了一个XML元素或属性的qualified name，即一个namespace和一个local name的二元组。</p>
				<p>Namespace对象表示了QName二元组中的namespace部分，它由prefix和URI两部分组成。</p>
				<p>
						<br />/******************** SAMPLE XML FILE *************************<br />  &lt;heavyz:Sample<br />    xmlns:heavyz="<a href="http://www.heavyzheng.com/schema/sample.xsd">http://www.heavyzheng.com/schema/sample.xsd</a>"&gt;<br />    &lt;heavyz:HelloWorld/&gt;<br />  &lt;/heavyz:Sample&gt;<br />  *************************************************************/<br />  <br />public void printRootQNameInfo(Document doc) {<br />    Element root = doc.getRootElement();<br />    QName qname = root.getQName();<br />    System.out.println("local name      : " + qname.getName());<br />    System.out.println("namespace prefix: " + qname.getNamespacePrefix());<br />    System.out.println("namespace URI   : " + qname.getNamespaceURI());<br />    System.out.println("qualified name  : " + qname.getQualifiedName());<br />    return;<br />}</p>
				<p>/************************* OUTPUT *****************************<br />  localname       : Sample<br />  namespace prefix: heavyz<br />  namespace URI   : <a href="http://www.heavyzheng.com/schema/sample.xsd">http://www.heavyzheng.com/schema/sample.xsd</a><br />  qualified name  : heavyz:Sample<br />  *************************************************************/<br />        <br />可以调用Namespace(String prefix, String uri)构造方法构造一个新的Namespace对象；也可以调用Namespace.get(String prefix, String uri)静态方法获得一个新的Namespace对象。</p>
				<p>可以调用QName(String name)构造方法构造一个没有namespace的qualified name；或者调用QName(String name, Namespace namespace)构造方法构造一个有namespace的qualified name。</p>
				<p>Navigating Through an XML Tree<br />对Document对象调用getRootElement()方法可以返回代表根节点的Element对象。拥有了一个Element对象后，可以对该对象调用elementIterator()方法获得它的子节点的Element对象们的一个iterator。使用(Element)iterator.next()方法遍历一个iterator并把每个取出的元素转化为Element类型。</p>
				<p>通过递归的方法，以下代码可以根据Document对象打印出完整的XML树。</p>
				<p>
						<br />public void printXMLTree(Document doc) {<br />    Element root = doc.getRootElement();<br />    printElement(root,0);<br />    return;<br />}<br />    <br />private void printElement(Element element, int level) {<br />    // print indent<br />    for (int i=0; i&lt;level; i++) {<br />        System.out.print(" ");<br />    }<br />    System.out.println(element.getQualifiedName());<br />    Iterator iter = element.elementIterator();<br />    while (iter.hasNext()) {<br />        Element sub = (Element)iter.next();<br />        printElement(sub,level+2);<br />    }<br />    return;<br />}<br />        <br />Getting Information from an Element<br />可以通过Element类提供的方法访问一个XML元素中含有的信息： Method Comment <br />getQName() 元素的QName对象 <br />getNamespace() 元素所属的Namespace对象 <br />getNamespacePrefix() 元素所属的Namespace对象的prefix <br />getNamespaceURI() 元素所属的Namespace对象的URI <br />getName() 元素的local name <br />getQualifiedName() 元素的qualified name <br />getText() 元素所含有的text内容，如果内容为空则返回一个空字符串而不是null <br />getTextTrim() 元素所含有的text内容，其中连续的空格被转化为单个空格，该方法不会返回null <br />attributeIterator() 元素属性的iterator，其中每个元素都是Attribute对象 <br />attributeValue() 元素的某个指定属性所含的值 <br />elementIterator() 元素的子元素的iterator，其中每个元素都是Element对象 <br />element() 元素的某个指定（qualified name或者local name）的子元素 <br />elementText() 元素的某个指定（qualified name或者local name）的子元素中的text信息 <br />getParent 元素的父元素 <br />getPath() 元素的XPath表达式，其中父元素的qualified name和子元素的qualified name之间使用"/"分隔 <br />isTextOnly() 是否该元素只含有text或是空元素 <br />isRootElement() 是否该元素是XML树的根节点 </p>
				<p>
						<br />要取出Element对象中某个属性的信息，可以调用attributeIterator()方法获得一个Attribute对象的iterator，然后再遍历它。也可以直接调用attributeValue()方法获得指定属性的值。该方法接受四种类型的参数： </p>
				<p>attributeValue(QName qname)：通过指定qualified name获得属性值，如果无法找到指定的属性，则返回null。 <br />attributeValue(QName qname, String defaultValue)：通过指定qualified name获得属性值，如果无法找到指定的属性，则返回defaultValue。 <br />attributeValue(String name)：通过指定local name获得属性值，而忽略属性的namespace，如果无法找到指定的属性，则返回null。 <br />attributeValue(String name, String defaultValue)：通过指定local name获得属性值，而忽略属性的namespace，如果无法找到指定的属性，则返回defaultValue。 </p>
				<p>对于一个Attribute对象，可以使用它的以下方法访问其中的信息： Method Comment <br />getQName() 属性的QName对象 <br />getNamespace() 属性所属的Namespace对象 <br />getNamespacePrefix() 属性所属的Namespace对象的prefix <br />getNamespaceURI() 属性所属的Namespace对象的URI <br />getName() 属性的local name <br />getQualifiedName() 属性的qualified name <br />getValue() 属性的值 </p>
				<p>
						<br />Writing an XML Tree to OutputStream<br />Dom4j通过XMLWriter将由Document对象表示的XML树写入一个文件，并使用OutputFormat格式对象指定写入的风格和编码方法。调用OutputFormat.createPrettyPrint()方法可以获得一个默认的pretty print风格的格式对象。对OutputFormat对象调用setEncoding()方法可以指定XML文件的编码方法。</p>
				<p>
						<br />public void writeTo(OutputStream out, String encoding)<br />throws UnsupportedEncodingException, IOException {<br />    OutputFormat format = OutputFormat.createPrettyPrint();<br />    format.setEncoding("gb2312");<br />    XMLWriter writer = new XMLWriter(System.out,format);<br />    writer.write(doc);<br />    writer.flush();<br />    return;<br />}<br />        <br />Creating an XML Tree<br />使用DocumentFactory对象创建一个空的Document对象。DocumentFactory对象由DocumentFactory.getInstance()静态方法产生。对Document对象调用addElement()方法将创建XML根节点，并将该节点返回。也可以手工创建一个Element对象并调用Document.setRootElement()方法把它设置为根节点</p>
				<p>
						<br />import org.dom4j.DocumentFactory;<br />import org.dom4j.Document;<br />import org.dom4j.Element;</p>
				<p>public class XMLSaver {<br />    <br />    private DocumentFactory factory = null;<br />    private Document doc = null;<br />    private Element root = null;<br />    <br />    public XMLSaver() {<br />        factory = DocumentFactory.getInstance();<br />        doc = factory.createDocument();<br />    }<br />    <br />    public Element generateRoot(String name) {<br />        root = doc.addElement(name);<br />        return root;<br />    }<br />    <br />    public Element generateRoot(QName qname) {<br />        root = doc.addElement(qname);<br />        return root;<br />    }<br />    <br />    public Element generateRoot(Element element) {<br />        doc.setRootElement(element);<br />        root = element;<br />        return root;<br />    }<br />}<br />        <br />Adding Information into an Element<br />Element通过addElement()为自己增加一个子节点到当前所有子节点的后面。该方法可以接受三种不同类型的参数：(QName qname)、(String name)或者(String qualifiedName, String namespaceURI)。该方法返回增加的子节点的Element对象。</p>
				<p>Element通过addAttribute()为自己增加属性。该方法可以接受两种不同类型的参数：(QName qname, String value)或者(String name, String value)。该方法返回自身的Element对象。</p>
				<p>Element通过addText()为自己增加文本内容。该方法只接受String类型参数，并返回自身的Element对象。</p>
				<p>
						<br />public void addAuthors(Element bookElement) {</p>
				<p>    Element author1 = bookElement.addElement("author");<br />    author1.addAttribute("name","Toby");<br />    author1.addAttribute("location","Germany");<br />    author1.addText("Tobias Rademacher");</p>
				<p>    Element author2 = bookElement.addElement("author");<br />    author2.addAttribute("name","James");<br />    author2.addAttribute("name","UK");<br />    author2.addText("James Strachan");<br />    <br />    return;<br />}<br />        <br />Deleting Elements and Attributes<br />要删除XML树上的一棵子树，首先要找到该子树的根节点，然后对该节点调用detach()方法。注意：如果对根节点调用了detach()方法，将导致该XML树不再完整（一个XML文件需要有且仅有一个根节点）。</p>
				<p>
						<br />public void deleteSubtree(Element subtreeRoot) {<br />    subtreeRoot.detach();<br />    return;<br />}<br />        <br />要清除Element下的所有子节点（包括Element和text），可以对该Element调用clearContent()方法。该方法不会清除Element的属性。</p>
				<p>要清除Element下的某个Attribute，首先要获得该Attribute对象，然后把它作为参数调用Element的remove()方法。</p>
				<p>Updating an Attribute<br />要更新一个属性的内容，首先要获得该Attribute对象，然后可以调用setNamespace()方法更新它所属的namespace；调用setValue()方法更新它的属性值。</p>
				<p>Updating an Element's Text<br />可以对一个Element对象调用isTextOnly()方法判断它是否只含有text或者是空节点。对Element对象调用addText()方法将把一个字符串附加到Element中，但不会修改它原来拥有的text或者子节点。如果Element是isTextOnly()，要修改原来含有的text，可以先调用clearContent()，再调用addText()并把新值传入。</p>
				<p>
						<br />public void updateText(Element element, String newText) {<br />    if (element.isTextOnly()) {<br />        element.clearContent();<br />        element.addText(newText);<br />    }<br />    return;<br />}</p>
		</div>
<img src ="http://www.blogjava.net/fortune/aggbug/36891.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-22 17:50 <a href="http://www.blogjava.net/fortune/archive/2006/03/22/36891.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 domj4 API 创建与修改 XML 文档</title><link>http://www.blogjava.net/fortune/archive/2006/03/20/36453.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 20 Mar 2006 14:20:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/20/36453.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/36453.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/20/36453.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/36453.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/36453.html</trackback:ping><description><![CDATA[
		<span class="postbody">
				<font size="2">
						<span style="FONT-WEIGHT: bold">使用 domj4 API 创建与修改 XML 文档</span>
						<br />级别：入门 <br /><br />Deepak Vohra (dvohra09@yahoo.com) <br />Web 开发人员 <br />2004 年 4 月 <br /><br />dom4j 是一种解析 XML 文档的开放源代码 XML 框架。本文介绍如何使用包含在 dom4j 中的解析器创建并修改 XML 文档。 <br />dom4j API 包含一个解析 XML 文档的工具。本文中将使用这个解析器创建一个示例 XML 文档。清单 1 显示了这个示例 XML 文档，catalog.xml。 <br /><br />清单 1. 示例 XML 文档（catalog.xml） <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br />&lt;catalog&gt; <br />&lt;!--An XML Catalog--&gt; <br />&lt;?target instruction?&gt; <br />  &lt;journal title="XML Zone" <br />                  publisher="IBM developerWorks"&gt; <br /><br />&lt;article level="Intermediate" date="December-2001"&gt; <br /> &lt;title&gt;Java configuration with XML Schema&lt;/title&gt; <br /> &lt;author&gt; <br />     &lt;firstname&gt;Marcello&lt;/firstname&gt; <br />     &lt;lastname&gt;Vitaletti&lt;/lastname&gt; <br /> &lt;/author&gt; <br />  &lt;/article&gt; <br />  &lt;/journal&gt; <br />&lt;/catalog&gt;</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">然后使用同一个解析器修改 catalog.xml，清单 2 是修改后的 XML 文档，catalog-modified.xml。 <br /><br />清单 2. 修改后的 XML 文档（catalog-modified.xml） <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br />&lt;catalog&gt; <br />&lt;!--An XML catalog--&gt; <br />&lt;?target instruction?&gt; <br />  &lt;journal title="XML Zone" <br />                   publisher="IBM developerWorks"&gt; <br /><br />&lt;article level="Introductory" date="October-2002"&gt; <br /> &lt;title&gt;Create flexible and extensible XML schemas&lt;/title&gt; <br /> &lt;author&gt; <br />     &lt;firstname&gt;Ayesha&lt;/firstname&gt; <br />     &lt;lastname&gt;Malik&lt;/lastname&gt; <br /> &lt;/author&gt; <br />  &lt;/article&gt; <br />  &lt;/journal&gt; <br />&lt;/catalog&gt;</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">与 W3C DOM API 相比，使用 dom4j 所包含的解析器的好处是 dom4j 拥有本地的 XPath 支持。DOM 解析器不支持使用 XPath 选择节点。 <br /><br />本文包括以下几个部分： <br /><br />预先设置 <br />创建文档 <br />修改文档 <br />预先设置 <br />这个解析器可以从 </font>
				<a href="http://dom4j.org/" target="_blank">
						<font color="#006699" size="2">http://dom4j.org</font>
				</a>
				<font size="2"> 获取。通过设置使 dom4j-1.4/dom4j-full.jar 能够在 classpath 中访问，该文件中包括 dom4j 类、XPath 引擎以及 SAX 和 DOM 接口。如果已经使用了 JAXP 解析器中包含的 SAX 和 DOM 接口，向 classpath 中增加 dom4j-1.4/dom4j.jar。dom4j.jar 包括 dom4j 类和 XPath 引擎，但是不含 SAX 与 DOM 接口。 <br /><br />创建文档 <br />本节讨论使用 dom4j API 创建 XML 文档的过程，并创建示例 XML 文档 catalog.xml。 <br /><br />使用 import 语句导入 dom4j API 类： <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">import org.dom4j.Document; <br />import org.dom4j.DocumentHelper; <br />import org.dom4j.Element;</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">使用 DocumentHelper 类创建一个文档实例。DocumentHelper 是生成 XML 文档节点的 dom4j API 工厂类。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">Document document = DocumentHelper.createDocument();</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">使用 addElement() 方法创建根元素 catalog。 addElement() 用于向 XML 文档中增加元素。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">Element catalogElement = document.addElement("catalog");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">在 catalog 元素中使用 addComment() 方法添加注释“An XML catalog”。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">catalogElement.addComment("An XML catalog");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">在 catalog 元素中使用 addProcessingInstruction() 方法增加一个处理指令。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">catalogElement.addProcessingInstruction("target","text");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">在 catalog 元素中使用 addElement() 方法增加 journal 元素。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">Element journalElement =  catalogElement.addElement("journal");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">使用 addAttribute() 方法向 journal 元素添加 title 和 publisher 属性。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">journalElement.addAttribute("title", "XML Zone"); <br />         journalElement.addAttribute("publisher", "IBM developerWorks");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">向 article 元素中添加 journal 元素。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">Element articleElement=journalElement.addElement("article");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">为 article 元素增加 level 和 date 属性。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">articleElement.addAttribute("level", "Intermediate"); <br />      articleElement.addAttribute("date", "December-2001");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">向 article 元素中增加 title 元素。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">Element titleElement=articleElement.addElement("title");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">使用 setText() 方法设置 article 元素的文本。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">titleElement.setText("Java configuration with XML Schema");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">在 article 元素中增加 author 元素。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">Element authorElement=articleElement.addElement("author");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">在 author 元素中增加 firstname 元素并设置该元素的文本。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">Element  firstNameElement=authorElement.addElement("firstname"); <br />     firstNameElement.setText("Marcello");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">在 author 元素中增加 lastname 元素并设置该元素的文本。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">Element lastNameElement=authorElement.addElement("lastname"); <br />     lastNameElement.setText("Vitaletti");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">可以使用 addDocType() 方法添加文档类型说明。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">document.addDocType("catalog", null,"file://c:/Dtds/catalog.dtd");</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">这样就向 XML 文档中增加文档类型说明： <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">&lt;!DOCTYPE catalog SYSTEM "file://c:/Dtds/catalog.dtd"&gt;</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">如果文档要使用文档类型定义（DTD）文档验证则必须有 Doctype。 <br /><br />XML 声明 &lt;?xml version="1.0" encoding="UTF-8"?&gt; 自动添加到 XML 文档中。 <br /><br />清单 3 所示的例子程序 XmlDom4J.java 用于创建 XML 文档 catalog.xml。 <br /><br />清单 3. 生成 XML 文档 catalog.xml 的程序（XmlDom4J.java） <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">import org.dom4j.Document; <br />import org.dom4j.DocumentHelper; <br />import org.dom4j.Element; <br />import org.dom4j.io.XMLWriter; <br />import java.io.*; <br /><br />public class XmlDom4J{ <br /><br />public void generateDocument(){ <br />Document document = DocumentHelper.createDocument(); <br />     Element catalogElement = document.addElement("catalog"); <br />     catalogElement.addComment("An XML Catalog"); <br />     catalogElement.addProcessingInstruction("target","text"); <br />     Element journalElement =  catalogElement.addElement("journal"); <br />     journalElement.addAttribute("title", "XML Zone"); <br />     journalElement.addAttribute("publisher", "IBM developerWorks"); <br /><br /><br />     Element articleElement=journalElement.addElement("article"); <br />     articleElement.addAttribute("level", "Intermediate"); <br />     articleElement.addAttribute("date", "December-2001"); <br />     Element  titleElement=articleElement.addElement("title"); <br />     titleElement.setText("Java configuration with XML Schema"); <br />     Element authorElement=articleElement.addElement("author"); <br />     Element  firstNameElement=authorElement.addElement("firstname"); <br />     firstNameElement.setText("Marcello"); <br />     Element lastNameElement=authorElement.addElement("lastname"); <br />     lastNameElement.setText("Vitaletti"); <br /><br />     document.addDocType("catalog", <br />                           null,"file://c:/Dtds/catalog.dtd"); <br />    try{ <br />    XMLWriter output = new XMLWriter( <br />            new FileWriter( new File("c:/catalog/catalog.xml") )); <br />        output.write( document ); <br />        output.close(); <br />        } <br />     catch(IOException e){System.out.println(e.getMessage());} <br />} <br /><br />public static void main(String[] argv){ <br />XmlDom4J dom4j=new XmlDom4J(); <br />dom4j.generateDocument(); <br />} <br />} <br /></td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">这一节讨论了创建 XML 文档的过程，下一节将介绍使用 dom4j API 修改这里创建的 XML 文档。 <br /><br />修改文档 <br />这一节说明如何使用 dom4j API 修改示例 XML 文档 catalog.xml。 <br /><br />使用 SAXReader 解析 XML 文档 catalog.xml： <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">SAXReader saxReader = new SAXReader(); <br /> Document document = saxReader.read(inputXml);</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">SAXReader 包含在 org.dom4j.io 包中。 <br /><br />inputXml 是从 c:/catalog/catalog.xml 创建的 java.io.File。使用 XPath 表达式从 article 元素中获得 level 节点列表。如果 level 属性值是“Intermediate”则改为“Introductory”。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">List list = document.selectNodes("//article/@level" ); <br />      Iterator iter=list.iterator(); <br />        while(iter.hasNext()){ <br />            Attribute attribute=(Attribute)iter.next(); <br />               if(attribute.getValue().equals("Intermediate")) <br />               attribute.setValue("Introductory"); <br />       }</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">获取 article 元素列表，从 article 元素中的 title 元素得到一个迭代器，并修改 title 元素的文本。 <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">list = document.selectNodes("//article" ); <br />     iter=list.iterator(); <br />   while(iter.hasNext()){ <br />       Element element=(Element)iter.next(); <br />      Iterator iterator=element.elementIterator("title"); <br />   while(iterator.hasNext()){ <br />   Element titleElement=(Element)iterator.next(); <br />   if(titleElement.getText().equals("Java configuration with XML Schema")) <br />     titleElement.setText("Create flexible and extensible XML schema"); <br /><br />    }} <br /> </td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">通过和 title 元素类似的过程修改 author 元素。 <br /><br />清单 4 所示的示例程序 Dom4JParser.java 用于把 catalog.xml 文档修改成 catalog-modified.xml 文档。 <br /><br />清单 4. 用于修改 catalog.xml 的程序（Dom4Jparser.java） <br /><br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">import org.dom4j.Document; <br />import org.dom4j.Element; <br />import org.dom4j.Attribute; <br />import java.util.List; <br />import java.util.Iterator; <br />import org.dom4j.io.XMLWriter; <br />import java.io.*; <br />import org.dom4j.DocumentException; <br />import org.dom4j.io.SAXReader; <br /><br />public class Dom4JParser{ <br /><br /> public void modifyDocument(File inputXml){ <br /><br />  try{ <br />   SAXReader saxReader = new SAXReader(); <br />   Document document = saxReader.read(inputXml); <br /><br />   List list = document.selectNodes("//article/@level" ); <br />   Iterator iter=list.iterator(); <br />   while(iter.hasNext()){ <br />    Attribute attribute=(Attribute)iter.next(); <br />    if(attribute.getValue().equals("Intermediate")) <br />      attribute.setValue("Introductory"); <br /><br />       } <br />    <br />   list = document.selectNodes("//article/@date" ); <br />   iter=list.iterator(); <br />   while(iter.hasNext()){ <br />    Attribute attribute=(Attribute)iter.next(); <br />    if(attribute.getValue().equals("December-2001")) <br />      attribute.setValue("October-2002"); <br /><br />       } <br /><br />   list = document.selectNodes("//article" ); <br />   iter=list.iterator(); <br />   while(iter.hasNext()){ <br />    Element element=(Element)iter.next(); <br />    Iterator iterator=element.elementIterator("title"); <br />      while(iterator.hasNext()){ <br />        Element titleElement=(Element)iterator.next(); <br />        if(titleElement.getText().equals("Java configuration with XML <br /><br />      Schema")) <br />        titleElement.setText("Create flexible and extensible XML schema"); <br /><br />                                          } <br /><br />                                } <br /><br />    list = document.selectNodes("//article/author" ); <br />    iter=list.iterator(); <br />     while(iter.hasNext()){ <br />     Element element=(Element)iter.next(); <br />     Iterator iterator=element.elementIterator("firstname"); <br />     while(iterator.hasNext()){ <br />      Element firstNameElement=(Element)iterator.next(); <br />      if(firstNameElement.getText().equals("Marcello")) <br />      firstNameElement.setText("Ayesha"); <br />                                     } <br /><br />                              } <br /><br />    list = document.selectNodes("//article/author" ); <br />    iter=list.iterator(); <br />     while(iter.hasNext()){ <br />      Element element=(Element)iter.next(); <br />      Iterator iterator=element.elementIterator("lastname"); <br />     while(iterator.hasNext()){ <br />      Element lastNameElement=(Element)iterator.next(); <br />      if(lastNameElement.getText().equals("Vitaletti")) <br />      lastNameElement.setText("Malik"); <br /><br />                                  } <br /><br />                               } <br />     XMLWriter output = new XMLWriter( <br />      new FileWriter( new File("c:/catalog/catalog-modified.xml") )); <br />     output.write( document ); <br />     output.close(); <br />   } <br />  <br />  catch(DocumentException e) <br />                 { <br />                  System.out.println(e.getMessage()); <br />                            } <br /><br />  catch(IOException e){ <br />                       System.out.println(e.getMessage()); <br />                    } <br /> } <br /><br /> public static void main(String[] argv){ <br /><br />  Dom4JParser dom4jParser=new Dom4JParser(); <br />  dom4jParser.modifyDocument(new File("c:/catalog/catalog.xml")); <br /><br />                                        } <br /><br />   }</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">这一节说明了如何使用 dom4j 中的解析器修改示例 XML 文档。这个解析器不使用 DTD 或者模式验证 XML 文档。如果 XML 文档需要验证，可以解释用 dom4j 与 JAXP SAX 解析器。 <br /><br />结束语 <br />包含在 dom4j 中的解析器是一种用于解析 XML 文档的非验证性工具，可以与JAXP、Crimson 或 Xerces 集成。本文说明了如何使用该解析器创建和修改 XML 文档。 <br /><br />参考资料 <br /><br />请访问 dom4j Web 站点，那里有一个很有用的 FAQ。 <br /><br />阅读 XML.com 上的文章“dom4j: the flexible XML framework for Java”。 <br /><br />通过 Dennis Sosnoski 的 developerWorks 文章“文档模型，第一部分：性能”（2001 年9 月）和“Java 文档模型的用法”（2002 年 2 月）进一步研究 dom4j。 <br /><br />通过 Elliotte Rusty Harold 的“Processing XML with Java”了解如何编制读写 XML 文档的 Java 程序。 <br /><br />在 developerWorks XML 和 Web 服务专区可以找到更多的 XML 资源。也可以订阅每周一期的 Web 服务/XML 技巧新闻邮件。 <br /><br />在 developerWorks Developer Bookstore 可以找到各种关于 XML 的书籍。 <br /><br />了解如何才能成为一名 IBM 认证的 XML 及相关技术的开发人员。 </font>
				<br />
				<span class="postbody">
						<font size="2">CSDN上的参考。 <br /></font>
						<a href="http://dev.csdn.net/develop/article/22/22753.shtm" target="_blank">
								<font color="#006699" size="2">http://dev.csdn.net/develop/article/22/22753.shtm</font>
						</a>
						<br />
				</span>
		</span>
<img src ="http://www.blogjava.net/fortune/aggbug/36453.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-20 22:20 <a href="http://www.blogjava.net/fortune/archive/2006/03/20/36453.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>dom4j使用简介</title><link>http://www.blogjava.net/fortune/archive/2006/03/20/36428.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 20 Mar 2006 13:03:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/20/36428.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/36428.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/20/36428.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/36428.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/36428.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Dom4j																				is an easy to use, open source library for working with XML, XPath and XSLT on the Java platform using the Java Collections Framework and with full support for DOM, SAX ...&nbsp;&nbsp;<a href='http://www.blogjava.net/fortune/archive/2006/03/20/36428.html'>阅读全文</a><img src ="http://www.blogjava.net/fortune/aggbug/36428.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-20 21:03 <a href="http://www.blogjava.net/fortune/archive/2006/03/20/36428.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于dom4j</title><link>http://www.blogjava.net/fortune/archive/2006/03/20/36414.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 20 Mar 2006 12:08:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/20/36414.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/36414.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/20/36414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/36414.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/36414.html</trackback:ping><description><![CDATA[今天就简单介绍一下处理XML文档的常用东西，关于xml document的话，w3c的document结构确实让人感到头痛，所以很多开发者都转向使用其他的document对象。其中dom4j是一个成功的开源项目，从java的对象概念的角度出发，按照通常的使用规范来处理xml文档，可以说，在java社区里，dom4j使用的最为广泛了，以下是dom4j的官方地址：<a href="http://www.dom4j.org/">http://www.dom4j.org/</a>。如，众所周知的o/r mapping工具hibernate就是使用dom4j来解释xml文档的（ejb3.0就是基于hibernate实现的），由此可见，dom4j的使用广泛之处。dom4j的一个最大的实用之处是支持XPath表达式的查询，这样，我们可以在dom4j的Document结构中使用这种简单的表达式就可以快速找到我们需要的某个元素了。
<p>      下载dom4j开发包：<a href="http://sourceforge.net/project/showfiles.php?group_id=16035">http://sourceforge.net/project/showfiles.php?group_id=16035</a>。在前言我已说过，由于都采用了使用类似的发布框架，所以对程序员来说极为容易上手。下载完dom4j之后，在dom4j的docs/cookbook.html里有详细的入门手册，而在src/samples里面则是一些样例，src/test文件夹里面是JUnit的测试例子。这些东西都已经很详细的介绍了怎样进行入门介绍。这里，我打算小结一下dom4j的Document结构：</p><p>      首先，要明白的是dom4j是基于面向接口的样式来实现处理xml文档的，这种方法在面向对象的领域里特别常见。使用的常用接口都封装在org.dom4j包里，而怎样读取xml文档呢？则是使用一系列的api函数，这些常用方法都封装在org.dom4j.io。</p><p>（1）从面向对象的角度来看，dom4j对XML的文档结构进行了封装，从一个文档的角度来说（我们不考虑内存中的数据结构的话），可以简单的把一个XML文档就当做一个org.dom4j.Document：</p><p>         我们现在使用dom4j的Document结构，而不是使用w3c的Document结构，读取一个文件，在内存中构造一个Document结构：Document doc=new SAXReader().read(new File("...")); 就可以获得一个Document结构。注意，dom4j同时也对w3c的Document结构，SAX Event的支持，具体的使用可以参看docs/cookbook.html中的内容。这里不一一介绍。</p><p>（2）获得一个dom4j的Document结构之后，从面向对象的角度，我们自然而然的想起的是XML中的element，dom4j根据这种想法对这些进行了封装org.dom4j.Element类就是对这些进行了封装，从Document中获得Element：</p><p>         首先获得一个root元素，Element root=doc.getRootElement();而其他的元素也可以根据这个root元素来获得。</p><p>（4）一个元素的属性的话，则是Attribute，在Element类中，有非常容易操作的方法添加于获得Attribute，addAttritue();attribute()等函数原型都提供了操作。</p><p>（5）dom4j同时也提供了在内存中的数据结构的构造，不降低处理的灵活性。如：Node就是对一个xml文档树的节点的封装，而Branch则是对一个树的分支的封装，通过使用这些，可以灵活的按照树的结构来处理xml文档。敏感的朋友可能会注意到，Document和Element都是Node与Branch的子类，这种不同功能的领域的封装可以按照对象的处理与数据结构的结合，灵活的处理xml文档。</p><p>         以上是一点简单的介绍入门dom4j的Document结构，详细的请看docs/cookbook.html文件，里面太详细了，：-）。</p><img src ="http://www.blogjava.net/fortune/aggbug/36414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-20 20:08 <a href="http://www.blogjava.net/fortune/archive/2006/03/20/36414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java  流与文件</title><link>http://www.blogjava.net/fortune/archive/2006/03/14/35251.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Tue, 14 Mar 2006 08:13:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/14/35251.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/35251.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/14/35251.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/35251.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/35251.html</trackback:ping><description><![CDATA[<FONT size=4>在java中可以读出一系列字节的对象称为“输入流”，而能向其写入一系列字节的对象称为“输出流”。这2种对象分别是用抽象类InputStream和OutputStream来实现的。对于Unicode格式保存的信息（每个字符都用了2个字节来存储），有专门的类处理，这些类是从抽象类Reader和Writer继承而来。<BR><BR>java以这4个抽象类为基础，衍生出一系列具体的类，几乎可以完成所有的输入/输出过程。<BR><BR>InputStream类提供了一个抽象方法：abstract&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;read（）<BR>读取一个字节并将它返回，由此类衍生出来的其它具体类都会覆盖这个方法，以提供有用的功能。<BR>类似的，OutputStream类定义了抽象方法abstract&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;write（int&nbsp; b）<BR><BR>完成流的读写操作后应记住要用close（）方法将其关闭。关闭输出流的同时也会刷新输出流使用的缓冲区：在缓冲区中等待组合成一个较大的数据包的临时存储的字符，都会通过网络传送出去。特别是，加入没有关闭一个文件，最后一个字节报可能永远都不会投递出去。<BR><BR>InputStream和OutputStream类允许我们读取单独的字节和字节数组，它们不对字符串及数字进行读写。DataInputStream和DataOutputStream允许对所有基本java类型进行读写。<BR>对于Unicode文本，需使用Reader和Writer衍生出的类，它提供的基本方法和InputStream和OutputStream类似：abstract&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;read（）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;abstract&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;write（int&nbsp; b）<BR>read方法返回的要么是个Unicode字符（0-65535间的一个整数）要么是-1（已抵达文件末尾）<BR>无论是read还是write方法都会阻塞线程的运行，直到字节被实际读出或写入为止。利用available方法，我们可以检查目前能够读取的字节数。<BR><BR>int&nbsp;&nbsp;&nbsp;byteAvailable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp; System.in.available（）；<BR>if&nbsp;&nbsp;&nbsp;（byteAvailable&nbsp; 〉 0） <BR>{byte[]&nbsp;&nbsp; data&nbsp; =&nbsp; new byte [byteAvailable]；<BR>&nbsp;&nbsp;&nbsp;System.in.read（data）；<BR>}<BR><BR><FONT face="Courier New">FileInputStream</FONT>&nbsp;和 <TT>FileOutputStream</TT> 使我们能将磁盘文件和输入流及输出流关联起来。<BR>FileInputStream fin = new FileInputStream("employee.dat");<BR>也可以<BR>File f = new File("employee.dat");<BR>FileInputStream fin = new FileInputStream(f);<BR><BR><FONT face="Courier New">与InputStream</FONT> and <TT>OutputStream</TT> 类似， 它也仅支持字节级的读写操作，只能从fin对象中读取字节和字节数组：byte b = (byte) fin.read();<BR><BR>FileOutputStream（String name）新建一个name指定的文件输出流，该方法会自动删除同名的任何现存文件！！！<BR><BR>文本流<BR><BR>二进制的输入输出速度很快效率很高但是人无法看懂这种格式。java使用的是Unicode字符<BR><BR>File, File(Input/Output)Stream, RandomAccessFile是处理本地文件的类<BR><BR>Data(Input/Output)Stream是一个过滤流的子类,借此可以读写各种基本数据, 在文件和网络中经常使用.如: readByte, writeBoolean等. <BR><BR>Buffered(Input/Output)Stream的作用是在数据送到目的之前先缓存,达到一定数量时再送到目的,用已减少阻塞次数. <BR><BR>Piped(Input/Output)Stream适合与一个处理的输出作为另一个处理的输入的情况<BR><BR><BR><BR>&nbsp;</FONT> ！要想以二进制格式写入数据，使用DataOutputStream，要想以文本格式写入数据，使用PrintWriter<BR>二进制读入使用DataInputStream，可读取文本格式的数据Java并未提供这样的类。唯一用来处理文本输入的是BufferedReader类它包含了一个方法readLine。<BR><BR><BR><BR><img src ="http://www.blogjava.net/fortune/aggbug/35251.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-14 16:13 <a href="http://www.blogjava.net/fortune/archive/2006/03/14/35251.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT Basic Controls -- Text</title><link>http://www.blogjava.net/fortune/archive/2006/03/13/35074.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 13 Mar 2006 08:30:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/13/35074.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/35074.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/13/35074.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/35074.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/35074.html</trackback:ping><description><![CDATA[<STRONG>Text Hierarchy<BR><BR><BR><IMG height=70 alt=graphics/07inf07.gif src="mk:@MSITStore:E:\java学习资料\swt教程\Addison.Wesley.Professional.SWT.The.Standard.Widget.Toolkit.Volume.1.Jun.2004.eBook-DDU.chm::/0321256638/images/0321256638/graphics/07inf07.gif" width=132 border=0><BR><BR>Text Styles<BR></STRONG><BR>
<TABLE cellSpacing=0 cellPadding=4 rules=rows frame=hsides>
<THEAD>
<TR>
<TH class=thead style="BACKGROUND-COLOR: #dddddd" vAlign=top align=left>
<P class=docText><SPAN class=docEmphBoldItalic>Style</SPAN></P></TH>
<TH class=thead style="BACKGROUND-COLOR: #dddddd" vAlign=top align=left>
<P class=docText><SPAN class=docEmphBoldItalic>Description</SPAN></P></TH></TR></THEAD>
<TBODY>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.SINGLE</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Allow a single line to be edited&nbsp; 单行</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.MULTI</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Allow multiple lines to be edited&nbsp; 多行</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.READ_ONLY</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Make the control noneditable&nbsp;&nbsp;&nbsp;&nbsp; 不可编辑</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.WRAP</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Allow strings to wrap instead of scrolling 自动换行</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.LEFT</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Left-align the contents of the control&nbsp;&nbsp;&nbsp; 左对齐</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.CENTER</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Center-align the contents of the control&nbsp; 中间对齐</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.RIGHT</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Right-align the contents of the control&nbsp;&nbsp; 右对齐</P></TD></TR></TBODY></TABLE><BR><BR><STRONG>Text Events</STRONG><BR><BR>
<TABLE cellSpacing=0 cellPadding=4 rules=rows frame=hsides>
<THEAD>
<TR>
<TH class=thead style="BACKGROUND-COLOR: #dddddd" vAlign=top align=left>
<P class=docText><SPAN class=docEmphBoldItalic>Event</SPAN></P></TH>
<TH class=thead style="BACKGROUND-COLOR: #dddddd" vAlign=top align=left>
<P class=docText><SPAN class=docEmphBoldItalic>&nbsp;&nbsp;&nbsp;&nbsp; Description</SPAN></P></TH></TR></THEAD>
<TBODY>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.DefaultSelection</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>&nbsp;&nbsp;&nbsp;&nbsp; Default selection occurred (user pressed &lt;Enter&gt;)</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.Modify</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>&nbsp;&nbsp;&nbsp;&nbsp; Text has changed in the control&nbsp; 控件中的文本内容发生了改变</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.Verify</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>&nbsp;&nbsp;&nbsp;&nbsp; Text is to be validated in the control&nbsp; 文本内容需要验证</P></TD></TR></TBODY></TABLE><BR>text控件支持"plain"text，这意味着text中的字符必须都是同样的字体和颜色，如果需要 更多的功能就使用<SPAN class=docEmphasis>org.eclipse.swt.custom.StyledText（eclipse为用户定制的）注意StyledText不是本地（native）控件<BR><BR>一共有2种类型的text控件：单行的和多行的<BR><BR><BR><STRONG>Single-Line and Multiline Text Controls</STRONG><BR><BR>SWT.SINGLE <BR><BR>Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);<BR>text.setText("Texan");<BR></SPAN><BR><BR>&nbsp;SWT.MULTI<BR>与单行的text不同它可以含有scroll bar&nbsp; （通过设置SWT.H_SCROLL or SWT.V_SCROLL ）<BR><BR>int style =<BR>&nbsp;&nbsp;&nbsp; SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL;<BR>Text text = new Text(parent, style);<BR><BR><BR><STRONG>String Operations</STRONG><BR><BR><SPAN class=docEmphStrong>setText(String string)</SPAN><BR><BR><SPAN class=docEmphStrong>getText()</SPAN> <BR><BR><SPAN class=docEmphStrong>getText(int start, int end)&nbsp; 获取text的文本内容从start到end<BR><SPAN class=docEmphStrong>getCharCount()</SPAN>&nbsp; 返回字符的数目<BR><BR><BR><STRONG>Passwords and the Echo Character</STRONG><BR><BR>int style = SWT.SINGLE | SWT.BORDER | SWT.PASSWORD;<BR><BR>Text text = new Text(parent, style);<BR><BR>text.setText("fred54"); //在text上不会显示"fred54"，而是以echo字符代替<BR><BR>注意在不同的平台上echo字符是不同的，我们常见的密码echo字符是“*”，可以自己设置echo字符<BR><SPAN class=docEmphStrong><BR>setEchoChar(char echo)如果设置的字符是'\0'则不再隐藏字符，当前的字符被显示</SPAN><BR><SPAN class=docEmphStrong>getEchoChar()</SPAN> 返回setEchoChar函数设置的echo，如果未设置则返回'\0'，如果使用了SWT.PASSWORD 则返回的字符不确定<BR>通常来说自己设置echo字符是不明智的，因为这是平台look and feel的一部分。<BR><BR><BR><STRONG>&nbsp;Lines and Line Height</STRONG><BR><BR><SPAN class=docEmphStrong>getLineCount()</SPAN> 返回行数<BR><SPAN class=docEmphStrong>getLineHeight()</SPAN> 返回每行高度（像素）该值与字符的高度并不相同，因为行间有空隙<BR><BR>public static void main(String[] args) {<BR><BR>&nbsp;&nbsp;&nbsp; Display display = new Display();<BR><BR>&nbsp;&nbsp;&nbsp; Shell shell = new Shell(display);<BR><BR>&nbsp;&nbsp;&nbsp; Text text = new Text(shell, SWT.H_SCROLL|SWT.V_SCROLL);<BR><BR>&nbsp;&nbsp;&nbsp; int rows = 5, columns = 10;<BR><BR>&nbsp;&nbsp;&nbsp; GC gc = new GC(text);<BR><BR>&nbsp;&nbsp;&nbsp; FontMetrics fm = gc.getFontMetrics();<BR><BR>&nbsp;&nbsp;&nbsp; gc.dispose();<BR><BR>&nbsp;&nbsp;&nbsp; int height = rows * text.getLineHeight();<BR><BR>&nbsp;&nbsp;&nbsp; int width = columns * fm.getAverageCharWidth();<BR><BR>&nbsp;&nbsp;&nbsp; text.setSize(text.computeSize (width, height));<BR><BR>&nbsp;&nbsp;&nbsp; shell.pack();<BR><BR>&nbsp;&nbsp;&nbsp; shell.open();<BR><BR>&nbsp;&nbsp;&nbsp; while (!shell.isDisposed()) {<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!display.readAndDispatch()) display.sleep();<BR><BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; display.dispose();<BR><BR>&nbsp; }<BR><BR><BR><STRONG>&nbsp;Line Delimiters<BR></STRONG>行定义符号<BR><BR><BR><BR><BR><BR><BR><BR></SPAN><BR><BR><img src ="http://www.blogjava.net/fortune/aggbug/35074.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-13 16:30 <a href="http://www.blogjava.net/fortune/archive/2006/03/13/35074.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT Basic Controls -- Button</title><link>http://www.blogjava.net/fortune/archive/2006/03/13/35062.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 13 Mar 2006 08:11:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/13/35062.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/35062.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/13/35062.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/35062.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/35062.html</trackback:ping><description><![CDATA[<P class=docText><SPAN class=docEmphStrong><SPAN class=docEmphStrong><STRONG>Button Hierarchy</STRONG><BR><BR><IMG height=53 alt=graphics/07inf05.gif src="mk:@MSITStore:E:\java学习资料\swt教程\Addison.Wesley.Professional.SWT.The.Standard.Widget.Toolkit.Volume.1.Jun.2004.eBook-DDU.chm::/0321256638/images/0321256638/graphics/07inf05.gif" width=119 border=0><BR><BR><BR><STRONG>Button Styles<BR></STRONG><BR></P></SPAN>
<P class=docText>
<TABLE cellSpacing=0 cellPadding=4 rules=rows frame=hsides>
<TBODY>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.ARROW</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Draw an arrow instead of text or an image 将button的形状显示为箭头</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.CHECK</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Create a check button </P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.PUSH</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Create a push button</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.RADIO</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Create a radio button</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.TOGGLE</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Create a toggle button</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.FLAT</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Draw the button with a flat look&nbsp; 使button看起来是flat的</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.UP</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Draw an up arrow&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 箭头向上（arrow时才有效）</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.DOWN</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Draw a down arrow&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;箭头向下（arrow时有效）</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.LEFT</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Left-align the button (or draw a left arrow)文字向左对齐或箭头向左（arrow时）</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.RIGHT</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Right-align the button (or draw a right arrow)文字向右对齐或箭头向右（arrow时）</P></TD></TR>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.CENTER</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>Center align the button&nbsp; button上的文字中间对齐</P></TD></TR></TBODY></TABLE></P>
<P class=docText><BR></SPAN><BR><STRONG>Button Events</STRONG><BR><BR></P>
<P class=docText>
<TABLE cellSpacing=0 cellPadding=4 rules=rows frame=hsides>
<TBODY>
<TR>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>SWT.Selection</P></TD>
<TD class=docTableCell vAlign=top align=left>
<P class=docText>&nbsp;&nbsp;&nbsp;The button was selected&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; button被选中事件</P></TD></TR></TBODY></TABLE></P>
<P class=docText>&nbsp;<BR>button是活动控件，当用户点击他们会发送事件<BR><BR><STRONG>Text and Images</STRONG><BR><BR>button支持显示文本和图像，它的使用大体上与label相同，但是它不支持SWT.WARP和换行符，既button上的文本字符只能是一行，而且它能只能显示文本或图像中的一种不能同时都显示</P>
<P class=docText><SPAN class=docEmphStrong>setText(String string)</SPAN> <BR><SPAN class=docEmphStrong>getText()</SPAN> <BR><SPAN class=docEmphStrong>setImage(Image image)</SPAN> <BR><SPAN class=docEmphStrong>getImage()</SPAN> </P>
<P class=docText>尽管button支持图片显示但是通常不这么使用，一般使用Tool bars 来代替<BR><BR><STRONG>Alignment</STRONG><BR><BR><SPAN class=docEmphStrong>setAlignment(int alignment)</SPAN>&nbsp;&nbsp; 设置对齐方式&nbsp; SWT.LEFT, SWT.CENTER, or SWT.RIGHT中的一种<BR><SPAN class=docEmphStrong>getAlignment()</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回对齐方式<BR><BR>通常很少使用这2个函数，因为默认的对齐一般都很好<BR><BR><STRONG>Push Buttons</STRONG><BR><BR>SWT.PUSH，它们通常用来产生一个动作，与其它类型的button不同push&nbsp; button不会在 SWT.Selection 事件中保持选中或未选中状态。它们通常被认为是未选中。<BR>Button button = new Button(parent, SWT.PUSH);<BR>button.setText("Ok");<BR><BR><STRONG>Check Buttons</STRONG><BR><BR>SWT.CHECK。它与push&nbsp; button不同的是它会保持一个选中的状态，用户使用鼠标或者键盘选择这个状态<BR><BR>你可以使用方法设置check&nbsp; button的选中状态<BR><SPAN class=docEmphStrong>setSelection(boolean selection)&nbsp; 设置该button为选中状态check, radio, or toggle button时有效<BR><SPAN class=docEmphStrong>getSelection()</SPAN> 返回该button是否被选中<BR><BR>Button button = new Button(parent, SWT.CHECK);<BR>button.setText("Overwrite when typing");<BR>button.setSelection(true);<BR><BR>注意：调用&nbsp;setSelection() 不会产生一个SWT.Selection 事件，SWT的编程新手经常会对这个感到很困惑。<BR><BR>当用户点击一个check，就会触发一个动作事件。你可以设置动作监听器<BR><BR>ActionListener listener =....<BR>bold.addActionListener(listener);<BR>italic.addActionListener(listener);<BR>监听器的actionPerformed方法将查询bold和italic两个check&nbsp; button的状态并且相应地把面板中的字体设为普通、加粗、倾斜以及后两种组合。<BR>public void actionPerformed(ActionEvent event)<BR>{<BR>&nbsp;&nbsp;&nbsp;int mode = 0;<BR>&nbsp;&nbsp;&nbsp;if (bold.isSelected()) mode +=Font.BOLD;<BR>&nbsp;&nbsp;&nbsp;if (italic.isSelected()) mode += Font.ITALIC;<BR>&nbsp;&nbsp;&nbsp;label.setFont(new Font("Serif", mode, FONTSIZE));<BR>}<BR><BR><STRONG>Radio Buttons</STRONG><BR><BR>SWT.RADIO 与check&nbsp; button一样它们会保持一个布尔状态，但是当多个radio&nbsp; button都是属于一个parent时，一次只能有一个被选中<BR></SPAN>Button button1 = new Button(parent, SWT.RADIO);<BR>button1.setText("Don't wrap");<BR>button1.setSelection(true);<BR>Button button2 = new Button(parent, SWT.RADIO);<BR>button2.setText("Wrap to window");<BR>Button button3 = new Button(parent, SWT.RADIO);<BR>button3.setText("Wrap to ruler");<BR><BR><BR><STRONG>Toggle Buttons</STRONG><BR><BR>SWT.TOGGLE&nbsp;&nbsp;&nbsp; toggle&nbsp; button是当被选中时一直停留在pressed状态下的push&nbsp; button<BR><BR><BR><STRONG>Arrow Buttons</STRONG><BR>SWT.ARROW<BR>Button button = new Button(parent, SWT.ARROW);<BR>button.setAlignment(SWT.RIGHT);<BR><BR>arrow&nbsp; button主要用于显示“上一页”或“下一页”时使用<BR><BR><STRONG>Button Events</STRONG><BR><BR><STRONG>SWT.Selection (SelectionEvent)</STRONG><BR><BR>button.addListener(SWT.Selection, new Listener() {<BR><BR>&nbsp;&nbsp;&nbsp; public void handleEvent(Event event) {<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Ok Pressed");<BR><BR>}<BR><BR>});<BR><BR><STRONG>Using SWT.Selection with Radio Buttons</STRONG><BR><BR>SWT.Selection 很少与radio一起使用，与check button一样，它们通常使用于对话框，对于绝大多数的操作系统，程序不会产生一个action直到dialog被关闭<BR>令人意外的是当用户在一组radio button中选择一个radio时，2个SWT.Selection 事件被发送：前一个被选中的radio button接收到一个 SWT.Selection 事件通知它的选中状态改为false，新的被选中的radio button接收到一个 SWT.Selection事件通知它已被选中<BR><BR>Listener listener = new Listener() {<BR>&nbsp;&nbsp;&nbsp; public void handleEvent(Event event) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Button button = (Button) event.widget;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!button.getSelection()) return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Arriving " + button.getText());<BR>&nbsp;&nbsp;&nbsp; }<BR>};<BR>Button land = new Button(shell, SWT.RADIO);<BR>land.setText("By Land");<BR>land.addListener(SWT.Selection, listener);<BR>Button sea = new Button(shell, SWT.RADIO);<BR>sea.setText("By Sea");<BR>sea.addListener(SWT.Selection, listener);<BR>sea.setSelection(true);<BR><BR><BR><BR><BR><BR><BR></P><img src ="http://www.blogjava.net/fortune/aggbug/35062.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-13 16:11 <a href="http://www.blogjava.net/fortune/archive/2006/03/13/35062.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT Basic Controls -- Label</title><link>http://www.blogjava.net/fortune/archive/2006/03/13/35026.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 13 Mar 2006 06:24:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/13/35026.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/35026.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/13/35026.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/35026.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/35026.html</trackback:ping><description><![CDATA[<STRONG>&nbsp;Label Hierarchy<BR><BR><IMG height=52 alt=graphics/07inf02.gif src="mk:@MSITStore:E:\java学习资料\swt教程\Addison.Wesley.Professional.SWT.The.Standard.Widget.Toolkit.Volume.1.Jun.2004.eBook-DDU.chm::/0321256638/images/0321256638/graphics/07inf02.gif" width=111 border=0><BR><BR>Label Styles</STRONG><BR><BR>
<P class=docText>SWT.WRAP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;自动调整label中的内容行以适应可见区域的大小（既label内容自动换行）<BR>SWT.LEFT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; label内容左对齐<BR>SWT.CENTER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label内容中间对齐<BR>SWT.RIGHT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label内容右对齐<BR>SWT.SEPARATOR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;画一个分割符<BR>SWT.HORIZONTAL&nbsp;&nbsp;&nbsp;使分割符水平（仅在画分割符时使用）<BR>SWT.VERTICAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使分割符垂直（仅在画分割符时使用）<BR>SWT.SHADOW_IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使分割符有“SHADOW_IN&nbsp;”的效果（仅在画分割符时使用）<BR>SWT.SHADOW_OUT&nbsp;&nbsp;使分割符有“SHADOW_OUT”的效果&nbsp;（仅在画分割符时使用）</P>
<P class=docText><STRONG>Label Events (none)</STRONG><BR><BR>label是一个静态组件可用来放置文本，图像，分隔符，一个静态的控件既不含有焦点（focus）也不参与tab traversal，鼠标点击不产生任何影响<BR><BR>Label label = new Label(parent, SWT.NONE);<BR>label.setText("User Name:");<BR><BR><STRONG>Text and Images</STRONG><BR><BR>label允许你设置文本或图像在上面如果你什么都不设置则label显示的是background color<BR><SPAN class=docEmphStrong><BR>setText(String string)&nbsp;&nbsp;&nbsp; 设置label显示文本内容string<BR><SPAN class=docEmphStrong>getText()</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回label的文本内容<BR><SPAN class=docEmphStrong>setImage(Image image) 设置label显示的图像<BR></SPAN><SPAN class=docEmphStrong>getImage()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回图像<BR><BR>注意：文本和图像只能设置其中的一种，若你想在label上文本和图像都加入，你要使用CLabel<BR><BR></SPAN><BR></SPAN><BR><BR><BR><BR></P><img src ="http://www.blogjava.net/fortune/aggbug/35026.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-13 14:24 <a href="http://www.blogjava.net/fortune/archive/2006/03/13/35026.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于clone函数</title><link>http://www.blogjava.net/fortune/archive/2006/03/13/34986.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 13 Mar 2006 02:34:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/13/34986.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/34986.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/13/34986.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/34986.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/34986.html</trackback:ping><description><![CDATA[今天看core java看到了clone函数<BR>要想使用clone函数首先必须实现接口Cloneable，重新定义clone函数为公有的，并调用super.clone（）<BR><BR>class Employee implements Cloneable<BR>{<BR>&nbsp;&nbsp;&nbsp;public Object clone()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return super.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (CloneNotSupportedException e) { return null; }<BR>}<BR>..........<BR>}<BR><BR>使用clone函数是要注意一个浅拷贝和深拷贝的问题，默认的拷贝操作都是浅拷贝——没有克隆对象内部引用的其他对象，所以要实现深拷贝，需要克隆可变实例字段需重建立clone方法<BR><BR>具体知识可参考core java章节--接口和内部类<img src ="http://www.blogjava.net/fortune/aggbug/34986.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-13 10:34 <a href="http://www.blogjava.net/fortune/archive/2006/03/13/34986.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT Layout - FormLayout</title><link>http://www.blogjava.net/fortune/archive/2006/03/09/34463.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Thu, 09 Mar 2006 05:51:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/09/34463.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/34463.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/09/34463.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/34463.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/34463.html</trackback:ping><description><![CDATA[<SPAN lang=EN-US style="mso-ansi-language: EN-US">MarginWidth, MarginHeight<BR>离页边宽度和高度，与GridLayout中相似<BR><SPAN lang=EN-US style="BACKGROUND: white; mso-ansi-language: EN-US; mso-highlight: white"><BR>Display display = <SPAN style="COLOR: navy">new</SPAN> Display ();<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-ansi-language: EN-US; mso-highlight: white">Shell shell = <SPAN style="COLOR: navy">new</SPAN> Shell (display);<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-ansi-language: EN-US; mso-highlight: white">FormLayout layout= <SPAN style="COLOR: navy">new</SPAN> FormLayout ();<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-ansi-language: EN-US; mso-highlight: white">layout.marginHeight = 5;<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US">layout.marginWidth = 5;<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-ansi-language: EN-US; mso-highlight: white">shell.setLayout (layout);</SPAN><BR><BR><SPAN lang=EN-US style="BACKGROUND: white; mso-ansi-language: EN-US; mso-highlight: white">FormData<BR>指定了每个widget在FormLayout中怎样排列<BR>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">很典型地，一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormData</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">实例在一个合成器内被帮定于各个子</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">。因为对于一个表格布局其核心思想就是指明各个子</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">的相对位置，所以不同于其他的布局，给予各个子</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">提供设置用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">data</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">非常重要。如果一个给定的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">没有一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormData</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">实例来描述它，则它会被默认为放置于合成器的左上角，而这种位置是你极少期望的。宽度和高度属性用象素来指明一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">的方位。顶部、底部和左右属性较为重要，且都持有一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">实例。这些</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">attachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">描绘了在一个合成器内</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">间的关系。<BR>注意：如果多个widgets未指明任何attachment，他们都会在缺省值指定的位置重叠起来<BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">指明关系</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">理解</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">是使用表格布局的一个非常重要的方面。就像早先提起的，每一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">实例描述了一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">某一面的位置。你可以以两种不同的方式使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">首先，你可以使用父合成器的百分比来指明一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">。例如，如果一个左侧的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormData</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">被设定为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">50%</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，则</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">的右边际会处于合成器的水平中央。同样地，如果设定顶端边界为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">75%</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">则</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">会处于合成器自上而下的四分之三处。表</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">6.3</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">总结了用以指定百分比的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">构造器。以百分比的形式来指明</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">是有用的，但你不能总是应用这种方法。将你的所有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">通用百分比方式作说明和用绝对的象素点来指明他们没有太大的区别：因为当合成器被重定大小时，如何快速定位每一个元素会变得相当困难，因为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">并不会如你所愿地在该位置上。使用表格式布局的关键点是在于确定</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">间的相互位置，而这正是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachement</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">所允许的。<BR><BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-ansi-language: EN-US; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">基于百分比</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-ansi-language: EN-US; mso-fareast-font-family: 宋体; mso-bidi-font-family: 宋体; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-ansi-language: EN-US; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">构造器</SPAN><BR>
<TABLE class=MsoNormalTable style="BORDER-RIGHT: black 1pt outset; BORDER-TOP: black 1pt outset; BORDER-LEFT: black 1pt outset; WIDTH: 100%; BORDER-BOTTOM: black 1pt outset; mso-cellspacing: 0cm; mso-border-alt: outset black .75pt; mso-padding-alt: 0cm 0cm 0cm 0cm" cellSpacing=0 cellPadding=0 width="100%" border=1>
<THEAD>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 37%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="37%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">构造器</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 63%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="63%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">描述</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR></THEAD>
<TBODY>
<TR style="mso-yfti-irow: 1">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 37%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="37%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment(int numerator)</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 63%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="63%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">假定分母为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">100</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，意味着参数即被视为一个百分比。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">仅在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SWT 3.0</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">中可用。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 2">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 37%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="37%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment(int numerator, int offset)</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 63%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="63%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">假定分母为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">100</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，意味着参数即被视为一个百分比。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">偏移量</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">offset</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">是在百分比定位的基础上再行偏移的象素数目。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 3; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 37%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="37%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment(int numerator, int denominator, int offset)</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 63%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="63%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">假定分母为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><FONT size=3>denominator</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，意味着参数即被视为一个百分比。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">偏移量</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">offset</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">是在百分比定位的基础上再行偏移的象素数目。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR></TBODY></TABLE><BR>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">第二系列的构造器是基于对其他</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">的参照。它们常常将一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">的边缘与相邻的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">相对定位。通过为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">button1</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">设定</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormData</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">右属性到一个基于</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">button2</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">而构建的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，你可以说</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">button1</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">应该总是定位与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">button2</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">的右侧。将你的绝大多数</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">依照这种方式去定位有多种好处。你的布局代码目的就变得很容易理解：在过去的象素或是百分壁基础上的那个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">与哪个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">相邻的表达方式被取代后，就变得很明显了，例如：名为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">foo</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">应该位于工具条之下；其次，表格式布局也容易维持你的这种布局意图。无论合成器的尺寸如何大小变化，它总是能够维持其正确的相对位置。<BR></P>
<P class=Code style="MARGIN-LEFT: 18pt"><SPAN lang=EN-US style="BACKGROUND: white; mso-ansi-language: EN-US; mso-highlight: white">FormData formData = <SPAN style="COLOR: navy">new</SPAN> FormData();<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-ansi-language: EN-US; mso-highlight: white">formData.top = <SPAN style="COLOR: navy">new</SPAN> FormAttachment(30,70,10);<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-ansi-language: EN-US; mso-highlight: white">button1.setLayoutData(formData);</SPAN><BR>指的是加入该Composite含有70个单元则该button1的顶部位于Composite从上数30个单元再加10个像素的位移<BR><BR><BR><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-ansi-language: EN-US; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">作为指定相对位置之用的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-ansi-language: EN-US; mso-fareast-font-family: 宋体; mso-bidi-font-family: 宋体; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">FormAttachment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-ansi-language: EN-US; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">构造器有若干种形式，具体总结如下<BR>：</SPAN><BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<TABLE class=MsoNormalTable style="BORDER-RIGHT: black 1pt outset; BORDER-TOP: black 1pt outset; BORDER-LEFT: black 1pt outset; WIDTH: 100%; BORDER-BOTTOM: black 1pt outset; mso-cellspacing: 0cm; mso-border-alt: outset black .75pt; mso-padding-alt: 0cm 0cm 0cm 0cm" cellSpacing=0 cellPadding=0 width="100%" border=1>
<THEAD>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 39%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="39%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">构造器</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 61%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="61%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">描述</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR></THEAD>
<TBODY>
<TR style="mso-yfti-irow: 1">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 39%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="39%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment(Control control)</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 61%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="61%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">将现有小部件添于邻接的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">一侧的参数。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 2">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 39%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="39%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment(Control control, int offset)</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 61%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="61%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">将现有小部件添于邻接的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">一侧的参数，并且有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">offset</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">数量象素的偏移量。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 3; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 39%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="39%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FormAttachment(Control control, int offset, int alignment)</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 61%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="61%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">排列</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">alignment</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">必须为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> SWT.TOP</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> SWT.BOTTOM</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SWT.LEFT</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> SWT.RIGHT</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">或</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SWT.CENTER</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">其中之一。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">将现有小部件添于邻接的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">一侧的参数，并且有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">offset</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">数量象素的偏移量。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR></TBODY></TABLE><BR>注意：对于top和left的offset应该为正数，对于bottom和right的offset应该为负数<BR><BR><BR>相对于另一个 widget进行定位<BR><BR>FormData formData = <SPAN style="COLOR: navy">new</SPAN> FormData();<BR><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">formData.top = <SPAN style="COLOR: navy">new</SPAN> FormAttachment(20,0);<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">button1.setLayoutData(formData);</SPAN><SPAN lang=EN-US>&nbsp;<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">FormData formData2 = <SPAN style="COLOR: navy">new</SPAN> FormData();<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">formData2.top = <SPAN style="COLOR: navy">new</SPAN> FormAttachment(button1,10);<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">button2.setLayoutData(formData2);<BR><BR>上面这段代码的意思就是首先将button1顶部放置在距离Composite顶部20%处，然后将button2的顶部放置在button1下10个像素位移处，当窗口大小改变时，button1会一直随着改变并处于20%处，而button2也一直在button1下方10个像素处<BR><BR><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">formData2.top = <SPAN style="COLOR: navy">new</SPAN> FormAttachment(button1,0,SWT.TOP);<o:p> 指定button2的顶部和button1相同也处于20%处<BR><BR><BR>
<P class=Code style="MARGIN-LEFT: 36pt; tab-stops: 18.0pt 36.0pt 2.0cm 72.0pt 3.0cm 99.25pt 126.0pt 144.0pt 162.0pt 180.0pt 198.0pt 216.0pt 234.0pt 252.0pt 270.0pt 288.0pt 306.0pt 324.0pt 342.0pt 360.0pt 378.0pt 396.0pt 414.0pt"><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">FormData formData = <SPAN style="COLOR: navy">new</SPAN> FormData(50,50);<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">formData.top = <SPAN style="COLOR: navy">new</SPAN> FormAttachment(20,0);<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">button1.setLayoutData(formData);<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">FormData formData2 = <SPAN style="COLOR: navy">new</SPAN> FormData();<BR></SPAN><SPAN lang=EN-US>FormData2.left = <SPAN style="COLOR: navy">new</SPAN> FormAttachment(button1,5);<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">formData2.top = <SPAN style="COLOR: navy">new</SPAN> FormAttachment(button1,0,SWT.TOP);<BR></SPAN><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">button2.setLayoutData(formData2);</SPAN></P>上面的代码说明button1大小为50*50像素，距离顶部20%，button2的左边与button1距离差5个像素，顶部与button1相同<BR><SPAN style="BACKGROUND: white; mso-highlight: white">若将上面改为formData.top = <SPAN style="COLOR: navy">new</SPAN> FormAttachment(button1,0,SWT.CENTER);则button2在button1左边5个像素处且在垂直方向上处于button1的中间<BR><BR>注意：千万不要定义重复的attachment，如定义button2的左边连着button1的右边，又定义button1的右边连着button2的左边，这样会导致未定义错误，所以一定要确定你的weidget没有重复限制他们的位置，仅定义 需要限制位置的widget</SPAN><BR><BR><BR>参考：<A href="http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm">http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm</A><BR><BR><BR><BR><BR><BR><BR><BR><BR></o:p></SPAN><BR><BR><BR><BR><BR><BR><BR><BR></SPAN><BR><BR></SPAN></SPAN><img src ="http://www.blogjava.net/fortune/aggbug/34463.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-09 13:51 <a href="http://www.blogjava.net/fortune/archive/2006/03/09/34463.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT Layout - RowLayout</title><link>http://www.blogjava.net/fortune/archive/2006/03/08/34328.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Wed, 08 Mar 2006 11:01:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/08/34328.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/34328.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/08/34328.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/34328.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/34328.html</trackback:ping><description><![CDATA[RowLayout要比FillLayout使用多些，每个widget的长度和宽度都可以通过方法setLayout（）设定widget的RowData。<BR><BR>Type域<BR>指定按行或列排列&nbsp;&nbsp;如：&nbsp;new RowLayout(SWT.HORIZONTAL);default：horizontal<BR><BR>Wrap域<BR>指定该行或列空间不足放下当前控件时是否自动换行；default：true<BR><BR>Pack域<BR>指定Layout中的widgets是否采用它们的自然大小，如果pack为false则所有widget强制为相同大小default：true<BR><BR>Justify域<BR>true表明Layout中的所有widgets每行都从左到右平均距离展开default：false<BR>
<H4><A name=_Toc509864533><SPAN lang=EN-US style="mso-ansi-language: EN-US">MarginLeft, MarginTop, MarginRight, MarginBottom and Spacing</SPAN></A></H4>
<H4>前面4个是指定于边框距离的，spacing指定widget之间的间隔</H4>
<H4><SPAN lang=EN-US style="mso-ansi-language: EN-US"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p>&nbsp;&nbsp; RowLayout rowLayout = <SPAN style="COLOR: navy">new</SPAN> RowLayout();</o:p></SPAN></H4>
<H4><SPAN lang=EN-US style="mso-ansi-language: EN-US"><o:p><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>rowLayout.wrap = false;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>rowLayout.pack = false;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>rowLayout.justify = true;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>rowLayout.type = SWT.VERTICAL;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>rowLayout.marginLeft = 5;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>rowLayout.marginTop = 5;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>rowLayout.marginRight = 5;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>rowLayout.marginBottom = 5;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>rowLayout.spacing = 0;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>shell.setLayout(rowLayout)</SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"></SPAN>&nbsp;</H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US">下面的代码使用RowData对象来改变button的大小</SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US">
<P class=Code><SPAN lang=EN-US style="COLOR: navy; mso-ansi-language: EN-US">import</SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"> org.eclipse.swt.*;<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="COLOR: navy; mso-ansi-language: EN-US">import</SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"> org.eclipse.swt.widgets.*;<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="COLOR: navy; mso-ansi-language: EN-US">import</SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"> org.eclipse.swt.layout.*;<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US">&nbsp;<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="COLOR: navy; mso-ansi-language: EN-US">public</SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"> <SPAN style="COLOR: navy">class</SPAN> RowDataExample {<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US">&nbsp;<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN><SPAN style="COLOR: navy">public</SPAN> <SPAN style="COLOR: navy">static</SPAN> <SPAN style="COLOR: navy">void</SPAN> main(String[] args) {<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Display display = <SPAN style="COLOR: navy">new</SPAN> Display();<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Shell shell = <SPAN style="COLOR: navy">new</SPAN> Shell(display);<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>shell.setLayout(<SPAN style="COLOR: navy">new</SPAN> RowLayout());<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Button button1 = <SPAN style="COLOR: navy">new</SPAN> Button(shell, SWT.PUSH);<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>button1.setText(<SPAN style="COLOR: teal">"Button 1"</SPAN>);<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>button1.setLayoutData(<SPAN style="COLOR: navy">new</SPAN> RowData(50, 40));<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Button button2 = <SPAN style="COLOR: navy">new</SPAN> Button(shell, SWT.PUSH);<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>button2.setText(<SPAN style="COLOR: teal">"Button 2"</SPAN>);<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>button2.setLayoutData(<SPAN style="COLOR: navy">new</SPAN> RowData(50, 30));<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Button button3 = <SPAN style="COLOR: navy">new</SPAN> Button(shell, SWT.PUSH);<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>button3.setText(<SPAN style="COLOR: teal">"Button 3"</SPAN>);<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>button3.setLayoutData(<SPAN style="COLOR: navy">new</SPAN> RowData(50, 20));<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>shell.pack();<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>shell.open();<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: navy">while</SPAN> (!shell.isDisposed()) {<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: navy">if</SPAN> (!display.readAndDispatch()) display.sleep();<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US">}</SPAN></P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"></SPAN>&nbsp;</P>
<P class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US">参考：<A href="http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm">http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm</A><o:p></o:p></SPAN></P></SPAN></H4></o:p></SPAN><img src ="http://www.blogjava.net/fortune/aggbug/34328.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-08 19:01 <a href="http://www.blogjava.net/fortune/archive/2006/03/08/34328.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT Layout-FillLayout</title><link>http://www.blogjava.net/fortune/archive/2006/03/08/34303.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Wed, 08 Mar 2006 09:17:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/08/34303.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/34303.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/08/34303.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/34303.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/34303.html</trackback:ping><description><![CDATA[<P>下图是SWT中的一些术语说明<BR><BR><BR><IMG height=296 src="http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts_files/image001.png" width=520 border=0><BR><BR>SWT共有4种Layout：FillLayout，RowLayout，GridLayout，FormLayout<BR><BR>FillLayout<BR>FillLayout是最简单的Layout，它将widgets放在单行或单列上，强制使它们具有相同的大小，也就是说每个widget的高度和宽度都和其中最高或最宽的那个widget一样<BR><A href="http://help.eclipse.org/help31/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/layout/FillLayout.html#marginHeight"><STRONG><FONT face="Courier New">marginHeight</FONT></STRONG></A> （与上下边框的距离），<A href="http://help.eclipse.org/help31/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/layout/FillLayout.html#marginWidth"><STRONG><FONT face="Courier New" color=#002c99>marginWidth</FONT></STRONG></A> （与左右边框的距离）（since3.0）<BR><BR><BR>spacing，指定widgets之间的间隔距离（since3.0）<BR><BR>public class Snippet172 {<BR>&nbsp;public static void main (String [] args) {<BR>&nbsp;&nbsp;Display display = new Display ();<BR>&nbsp;&nbsp;Shell shell = new Shell (display);<BR>&nbsp;&nbsp;FillLayout fillLayout = new FillLayout ();<BR>&nbsp;&nbsp;fillLayout.type = SWT.VERTICAL;<BR>&nbsp;&nbsp;fillLayout.marginHeight = 20;<BR>&nbsp;&nbsp;fillLayout.marginWidth = 15;<BR>&nbsp;&nbsp;fillLayout.spacing = 10;<BR>&nbsp;&nbsp;shell.setLayout (fillLayout);</P>
<P>&nbsp;&nbsp;Button button0 = new Button (shell, SWT.PUSH);<BR>&nbsp;&nbsp;button0.setText ("button0");</P>
<P>&nbsp;&nbsp;Button button1 = new Button (shell, SWT.PUSH);<BR>&nbsp;&nbsp;button1.setText ("button1");</P>
<P>&nbsp;&nbsp;Button button2 = new Button (shell, SWT.PUSH);<BR>&nbsp;&nbsp;button2.setText ("button2");</P>
<P>&nbsp;&nbsp;shell.pack ();<BR>&nbsp;&nbsp;shell.open ();</P>
<P>&nbsp;&nbsp;while (!shell.isDisposed ()) {<BR>&nbsp;&nbsp;&nbsp;if (!display.readAndDispatch ())<BR>&nbsp;&nbsp;&nbsp;&nbsp;display.sleep ();<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;display.dispose ();<BR>&nbsp;}<BR>}<BR><BR>参考：<A href="http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm">http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm</A><BR></P><img src ="http://www.blogjava.net/fortune/aggbug/34303.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-08 17:17 <a href="http://www.blogjava.net/fortune/archive/2006/03/08/34303.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT Layout--GridLayout</title><link>http://www.blogjava.net/fortune/archive/2006/03/08/34267.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Wed, 08 Mar 2006 06:34:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/08/34267.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/34267.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/08/34267.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/34267.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/34267.html</trackback:ping><description><![CDATA[<H4><A name=_Toc509864538><SPAN lang=EN-US style="mso-ansi-language: EN-US">NumColumns</SPAN></A><FONT color=#000000>(列数)是GridLayout中最重要的域，它将Composite划分成NumColumns列，往上添加控件时依次从左至右排列当控件数多于列数时换行</FONT></H4>
<P>Display display = <SPAN style="COLOR: navy">new</SPAN> Display();<BR><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>Shell shell = <SPAN style="COLOR: navy">new</SPAN> Shell(display);<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>GridLayout gridLayout = <SPAN style="COLOR: navy">new</SPAN> GridLayout();<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>gridLayout.numColumns = 3;<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>shell.setLayout(gridLayout);<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN><SPAN style="COLOR: navy">new</SPAN> Button(shell, SWT.PUSH).setText(<SPAN style="COLOR: teal">"B1"</SPAN>);<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN><SPAN style="COLOR: navy">new</SPAN> Button(shell, SWT.PUSH).setText(<SPAN style="COLOR: teal">"Wide Button 2"</SPAN>);<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN><SPAN style="COLOR: navy">new</SPAN> Button(shell, SWT.PUSH).setText(<SPAN style="COLOR: teal">"Button 3"</SPAN>);<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN><SPAN style="COLOR: navy">new</SPAN> Button(shell, SWT.PUSH).setText(<SPAN style="COLOR: teal">"B4"</SPAN>);<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN><SPAN style="COLOR: navy">new</SPAN> Button(shell, SWT.PUSH).setText(<SPAN style="COLOR: teal">"Button 5"</SPAN>);<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>shell.pack();<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>shell.open();<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN><SPAN style="COLOR: navy">while</SPAN> (!shell.isDisposed()) {<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN><SPAN style="COLOR: navy">if</SPAN> (!display.readAndDispatch()) display.sleep();<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>}<BR><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p><A name=_Toc509864539><SPAN lang=EN-US style="mso-ansi-language: EN-US"><STRONG>MakeColumnsEqualWidth<BR></STRONG></SPAN></A>使每列的宽度相同，默认值为false<BR><BR><A name=_Toc509864540><SPAN lang=EN-US style="mso-ansi-language: EN-US"><STRONG>MarginWidth, MarginHeight, HorizontalSpacing, and VerticalSpacing</STRONG></SPAN></A><BR>页边宽度，页边高度，水平间隔，垂直间隔<BR><BR><STRONG>GridData<BR></STRONG>GridData是控制小部件布局的对象，例如<BR>&nbsp;&nbsp; GridData gridData = <SPAN style="COLOR: navy">new</SPAN> GridData();<BR><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>gridData.horizontalAlignment = GridData.FILL;//horizontalAlignment是指水平对齐方式<BR>//（有GEGINING，END，CENTRE，FILL）<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>gridData.grabExcessHorizontalSpace = true;<BR></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN>button1.setLayoutData(gridData);<BR><o:p>注意：每个在GridLayout中的widget都有一个自己的GridData，如果没有为它设置则系统会给他一个默认的GridData！<BR></P>
<H4><A name=_Toc509864542><SPAN lang=EN-US style="mso-ansi-language: EN-US">HorizontalAlignment and VerticalAlignment</SPAN></A><SPAN lang=EN-US style="mso-ansi-language: EN-US"> </SPAN></H4>
<H4><SPAN lang=EN-US style="mso-ansi-language: EN-US">每个alignment域指定控件在它的格子单元内水平/垂直怎样对齐，他们是下面4个值中的一个</SPAN></H4>
<H4><SPAN lang=EN-US style="mso-ansi-language: EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN lang=EN-US style="FONT-FAMILY: Symbol; mso-ansi-language: EN-US">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US">BEGINNING（左对齐）</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Symbol; mso-ansi-language: EN-US">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US">CENTER（中间对齐）</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Symbol; mso-ansi-language: EN-US">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US">END右对齐</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Symbol; mso-ansi-language: EN-US">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US">FILL充满格子</SPAN></H4></SPAN>
<H4><SPAN lang=EN-US style="mso-ansi-language: EN-US">缺省值为horizontalAlignment is BEGINNING&nbsp;， verticalAlignment is CENTER</SPAN></H4><SPAN lang=EN-US style="mso-ansi-language: EN-US">
<H4><A name=_Toc509864543><SPAN lang=EN-US style="mso-ansi-language: EN-US">HorizontalIndent</SPAN></A></H4>
<H4 align=justify>允许你将widget向右移动指定的像素位</H4>
<H4 align=justify><SPAN lang=EN-US style="mso-ansi-language: EN-US"><o:p><SPAN lang=EN-US style="mso-ansi-language: EN-US">GridData gridData = <SPAN style="COLOR: navy">new</SPAN> GridData();</SPAN></H4>
<H4 class=Code style="MARGIN-LEFT: 18pt" align=justify><SPAN lang=EN-US style="mso-ansi-language: EN-US"></SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US">gridData.horizontalIndent = 4;<o:p></o:p></SPAN></H4>
<H4 class=Code style="MARGIN-LEFT: 18pt" align=justify><SPAN lang=EN-US style="mso-ansi-language: EN-US">button.setLayoutData(gridData);</SPAN></H4>
<H4 class=Code style="MARGIN-LEFT: 18pt" align=justify><SPAN lang=EN-US style="mso-ansi-language: EN-US"><o:p><A name=_Toc509864544><SPAN lang=EN-US style="mso-ansi-language: EN-US">HorizontalSpan and VerticalSpan</SPAN></A></o:p></SPAN></H4>
<H4 class=Code style="MARGIN-LEFT: 18pt" align=justify><SPAN lang=EN-US style="mso-ansi-language: EN-US"><o:p>span域可使widget占据多个grid单元（仅在horizontalAlignment为Fill时有效）</o:p></SPAN></H4>
<H4 class=Code style="MARGIN-LEFT: 18pt" align=justify><SPAN lang=EN-US style="mso-ansi-language: EN-US"><o:p><SPAN lang=EN-US style="mso-ansi-language: EN-US">GridData gridData = <SPAN style="COLOR: navy">new</SPAN> GridData();<o:p></o:p></SPAN></H4>
<H4 class=Code style="MARGIN-LEFT: 18pt" align=justify>
<P class=Code style="MARGIN-LEFT: 18pt"><SPAN lang=EN-US style="mso-ansi-language: EN-US">gridData.horizontalAlignment = GridData.FILL;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-ansi-language: EN-US"> </SPAN><SPAN lang=EN-US style="mso-ansi-language: EN-US"><o:p></o:p></SPAN></P>
<P class=Code style="MARGIN-LEFT: 18pt"><SPAN lang=EN-US style="mso-ansi-language: EN-US">gridData.horizontalSpan = 2;<o:p></o:p></SPAN></P>
<P class=Code style="MARGIN-LEFT: 18pt"><SPAN lang=EN-US style="mso-ansi-language: EN-US">button5.setLayoutData(gridData);</SPAN></P></o:p></SPAN></H4>
<H4 class=MsoNormal align=justify><SPAN lang=EN-US style="mso-ansi-language: EN-US">&nbsp;也可以它在垂直方向占用多个grid单元（仅在verticalAlignment为Fill时有效）</SPAN></H4>
<H4 class=MsoNormal align=justify><SPAN lang=EN-US style="mso-ansi-language: EN-US">注意：假如所有的widgets总共只有x行则你想让它在垂直方向占有x+1个grid单元是没有作用的</SPAN></H4>
<H4 class=MsoNormal align=justify><SPAN lang=EN-US style="mso-ansi-language: EN-US">
<H4 style="tab-stops: 90.0pt"><A name=_Toc509864545><SPAN lang=EN-US style="mso-ansi-language: EN-US">GrabExcessHorizontalSpace and GrabExcessVerticalSpace</SPAN></A></H4>
<H4 style="tab-stops: 90.0pt"><SPAN lang=EN-US style="mso-ansi-language: EN-US"><o:p>当用户改变窗口大小时，<A name=_Toc509864545><SPAN lang=EN-US style="mso-ansi-language: EN-US">GrabExcessHorizontalSpace 和GrabExcessVerticalSpace</SPAN></A>指定该控件是否填充增大的空间</o:p></SPAN></H4>
<H4 style="tab-stops: 90.0pt"><SPAN lang=EN-US style="mso-ansi-language: EN-US"><o:p><SPAN lang=EN-US style="mso-ansi-language: EN-US"><o:p>
<H4><A name=_Toc509864546><SPAN lang=EN-US style="mso-ansi-language: EN-US">WidthHint and HeightHint</SPAN></A></H4>
<H4>指定widget的大小（如果horizontalAlignment或verticalAlignment为FILL的时候就没有意义了）</H4>
<H4>GridData gridData = <SPAN style="COLOR: navy">new</SPAN> GridData();<o:p></o:p></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>gridData.widthHint = 70;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>gridData.heightHint = 40;<o:p></o:p></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>button5.setLayoutData(gridData);</SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US">注：最好不要对大小硬编码</SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"></SPAN>&nbsp;</H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US">
<TABLE class=MsoNormalTable style="BORDER-RIGHT: black 1pt outset; BORDER-TOP: black 1pt outset; BORDER-LEFT: black 1pt outset; WIDTH: 100%; BORDER-BOTTOM: black 1pt outset; mso-cellspacing: 0cm; mso-border-alt: outset black .75pt; mso-padding-alt: 0cm 0cm 0cm 0cm" cellSpacing=0 cellPadding=0 width="100%" border=1>
<THEAD>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Style </SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">常量</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">描述</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR></THEAD>
<TBODY>
<TR style="mso-yfti-irow: 1">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FILL_HORIZONTAL</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">扩展单元来水平地充满任何空余空间。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">指</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">HORIZONTAL_ALIGN_FILL</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 2">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FILL_VERTICAL</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">扩展单元来垂直地充满任何空余空间。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">指</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">VERTICAL_ALIGN_FILL</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 3">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FILL_BOTH</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">水平和垂直地扩展单元空间。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">等价于</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FILL_HORIZONTAL | FILL_VERTICAL.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 4">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">HORIZONTAL_ALIGN_BEGINNING</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">居左排列单元内容。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 5">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">HORIZONTAL_ALIGN_END</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">居右排列单元内容。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 6">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">HORIZONTAL_ALIGN_CENTER</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">水平居中排列单元内容。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 7">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">HORIZONTAL_ALIGN_FILL</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">扩展单元空间充满单元内水平空余空间。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 8">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">VERTICAL_ALIGN_BEGINNING</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">排列单元内容于单元顶部。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 9">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">VERTICAL_ALIGN_END</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">排列单元内容于单元底部。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 10">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">VERTICAL_ALIGN_CENTER</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">排列单元内容于垂直中央。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 11; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 29%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="29%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">VERTICAL_ALIGN_FILL</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 71%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="71%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">扩展单元空间充满单元内垂直空余空间。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR></TBODY></TABLE></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"></SPAN>&nbsp;</H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: center; mso-pagination: widow-orphan" align=center><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Table 6.2 GridData </SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">尺寸属性</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<TABLE class=MsoNormalTable style="BORDER-RIGHT: black 1pt outset; BORDER-TOP: black 1pt outset; BORDER-LEFT: black 1pt outset; WIDTH: 100%; BORDER-BOTTOM: black 1pt outset; mso-cellspacing: 0cm; mso-border-alt: outset black .75pt; mso-padding-alt: 0cm 0cm 0cm 0cm" cellSpacing=0 cellPadding=0 width="100%" border=1>
<THEAD>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 21%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="21%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">属性</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 64%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="64%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">描述</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 15%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="15%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">默认值</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR></THEAD>
<TBODY>
<TR style="mso-yfti-irow: 1">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 21%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="21%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">widthHint</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 64%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="64%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">列的最小宽度。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SWT.DEFAULT</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">指明了没有最小宽度。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 15%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="15%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SWT.DEFAULT</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 2">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 21%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="21%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">heightHint</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 64%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="64%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">行的最小高度。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SWT.DEFAULT</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">指明了没有最小高度。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 15%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="15%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SWT.DEFAULT</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 3">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 21%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="21%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">horizontalIndent</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 64%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="64%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">单元左侧边际与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">control</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">之间的象素间隙数量。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 15%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="15%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">0</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 4">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 21%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="21%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">horizontalSpan</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 64%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="64%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">单元所覆盖的网格的列的数目。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 15%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="15%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">1</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 5; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 21%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="21%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">verticalSpan</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 64%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="64%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">单元所覆盖的网格的行的数目。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: black 1pt inset; PADDING-RIGHT: 0cm; BORDER-TOP: black 1pt inset; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt inset; WIDTH: 15%; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt inset; BACKGROUND-COLOR: transparent; mso-border-alt: inset black .75pt" vAlign=top width="15%">
<P class=MsoNormal style="MARGIN: 4.5pt 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">1</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD></TR></TBODY></TABLE></SPAN></H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US"></SPAN>&nbsp;</H4>
<H4 class=Code><SPAN lang=EN-US style="mso-ansi-language: EN-US">参考：<A href="http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm">http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm</A><o:p></o:p></SPAN></H4></o:p></SPAN></o:p></SPAN></SPAN></H4></H4></o:p></SPAN></SPAN></o:p></SPAN></o:p></SPAN><img src ="http://www.blogjava.net/fortune/aggbug/34267.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-08 14:34 <a href="http://www.blogjava.net/fortune/archive/2006/03/08/34267.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java串口编程（起步</title><link>http://www.blogjava.net/fortune/archive/2006/03/03/33401.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Fri, 03 Mar 2006 03:00:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/03/03/33401.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/33401.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/03/03/33401.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/33401.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/33401.html</trackback:ping><description><![CDATA[1. SerialBean<BR>SerialBean是本类库与其他应用程序的接口。该类库中定义了SerialBean的构造方法以及初始化串口，从串口读取数据，往串口写入数据以及关闭串口的函数。具体介绍如下： <BR><BR>public SerialBean(int PortID)<BR>本函数构造一个指向特定串口的SerialBean，该串口由参数PortID所指定。PortID = 1 表示COM1，PortID = 2 表示COM2，由此类推。<BR><BR>public int Initialize()<BR>本函数初始化所指定的串口并返回初始化结果。如果初始化成功返回1，否则返回-1。初始化的结果是该串口被SerialBean独占性使用，其参数被设置为9600, N, 8, 1。如果串口被成功初始化，则打开一个进程读取从串口传入的数据并将其保存在缓冲区中。<BR><BR>public String ReadPort(int Length)<BR>本函数从串口(缓冲区)中读取指定长度的一个字符串。参数Length指定所返回字符串的长度。<BR><BR>public void WritePort(String Msg)<BR>本函数向串口发送一个字符串。参数Msg是需要发送的字符串。<BR><BR>public void ClosePort()<BR>本函数停止串口检测进程并关闭串口。<BR>package serial;<BR>&nbsp;import java.io.*;<BR>&nbsp;import java.util.*;<BR>&nbsp;import javax.comm.*;<BR>&nbsp;/**<BR>&nbsp; *<BR>&nbsp; * This bean provides some basic functions to implement full dulplex<BR>&nbsp; * information exchange through the srial port.<BR>&nbsp; *<BR>&nbsp; */<BR>&nbsp;public class SerialBean<BR>&nbsp;{<BR>&nbsp; &nbsp;static String PortName;<BR>&nbsp; &nbsp;CommPortIdentifier portId;<BR>&nbsp; &nbsp;SerialPort serialPort;<BR>&nbsp; &nbsp;static OutputStream out;<BR>&nbsp; &nbsp;static InputStream &nbsp;in;<BR>&nbsp; &nbsp;SerialBuffer SB;<BR>&nbsp; &nbsp;ReadSerial &nbsp; RT;<BR>&nbsp; &nbsp; &nbsp;/**<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * Constructor<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * @param PortID the ID of the serial to be used. 1 for COM1,<BR>&nbsp; &nbsp; &nbsp; * 2 for COM2, etc.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; */<BR>&nbsp; &nbsp; &nbsp;public SerialBean(int PortID)<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;PortName = "COM" + PortID;<BR>&nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;/**<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * This function initialize the serial port for communication. It startss a<BR>&nbsp; &nbsp; &nbsp; * thread which consistently monitors the serial port. Any signal capturred<BR>&nbsp; &nbsp; &nbsp; * from the serial port is stored into a buffer area.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; */<BR>&nbsp; &nbsp; &nbsp;public int Initialize()<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;int InitSuccess = 1;<BR>&nbsp; &nbsp; &nbsp; &nbsp;int InitFail &nbsp; &nbsp;= -1;<BR>&nbsp; &nbsp; &nbsp;try<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;portId = CommPortIdentifier.getPortIdentifier(PortName);<BR>&nbsp; &nbsp; &nbsp; &nbsp;try<BR>&nbsp; &nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;serialPort = (SerialPort)<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;portId.open("Serial_Communication", 2000);<BR>&nbsp; &nbsp; &nbsp; &nbsp;} catch (PortInUseException e)<BR>&nbsp; &nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return InitFail;<BR>&nbsp; &nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp; &nbsp;//Use InputStream in to read from the serial port, and OutputStream<BR>&nbsp; &nbsp; &nbsp; &nbsp;//out to write to the serial port.<BR>&nbsp; &nbsp; &nbsp; &nbsp;try<BR>&nbsp; &nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in &nbsp;= serialPort.getInputStream();<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;out = serialPort.getOutputStream();<BR>&nbsp; &nbsp; &nbsp; &nbsp;} catch (IOException e)<BR>&nbsp; &nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return InitFail;<BR>&nbsp; &nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp; &nbsp;//Initialize the communication parameters to 9600, 8, 1, none.<BR>&nbsp; &nbsp; &nbsp; &nbsp;try<BR>&nbsp; &nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; serialPort.setSerialPortParams(9600,<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SerialPort.DATABITS_8,<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SerialPort.STOPBITS_1,<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SerialPort.PARITY_NONE);<BR>&nbsp; &nbsp; &nbsp; &nbsp;} catch (UnsupportedCommOperationException e)<BR>&nbsp; &nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return InitFail;<BR>&nbsp; &nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;} catch (NoSuchPortException e)<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;return InitFail;<BR>&nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;// when successfully open the serial port, &nbsp;create a new serial buffer,<BR>&nbsp; &nbsp; &nbsp;// then create a thread that consistently accepts incoming signals from<BR>&nbsp; &nbsp; &nbsp;// the serial port. Incoming signals are stored in the serial buffer.<BR>&nbsp; &nbsp; &nbsp;SB = new SerialBuffer();<BR>&nbsp; &nbsp; &nbsp;RT = new ReadSerial(SB, in);<BR>&nbsp; &nbsp; &nbsp;RT.start();<BR>&nbsp; &nbsp; &nbsp;// return success information<BR>&nbsp; &nbsp; &nbsp;return InitSuccess;<BR>&nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;/**<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * This function returns a string with a certain length from the incomin<BR>&nbsp; &nbsp; &nbsp; * messages.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * @param Length The length of the string to be returned.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; */<BR>&nbsp; &nbsp; &nbsp;public String ReadPort(int Length)<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;String Msg;<BR>&nbsp; &nbsp; &nbsp; &nbsp;Msg = SB.GetMsg(Length);<BR>&nbsp; &nbsp; &nbsp; &nbsp;return Msg;<BR>&nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;/**<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * This function sends a message through the serial port.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * @param Msg The string to be sent.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; */<BR>&nbsp; &nbsp; &nbsp;public void WritePort(String Msg)<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;int c;<BR>&nbsp; &nbsp; &nbsp; &nbsp;try<BR>&nbsp; &nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for (int i = 0; i &lt; Msg.length(); i++)<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;out.write(Msg.charAt(i));<BR>&nbsp; &nbsp; &nbsp; &nbsp;} catch (IOException e) &nbsp;{}<BR>&nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;/**<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * This function closes the serial port in use.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; */<BR>&nbsp; &nbsp; &nbsp;public void ClosePort()<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;RT.stop();<BR>&nbsp; &nbsp; &nbsp; &nbsp;serialPort.close();<BR>&nbsp; &nbsp; &nbsp;}<BR>&nbsp;}<BR>
<DIV style="MARGIN: 4px 8px 0px" firstchar="">2. SerialBuffer <BR><BR>SerialBuffer是本类库中所定义的串口缓冲区，它定义了往该缓冲区中写入数据和从该缓冲区中读取数据所需要的函数。 <BR><BR>public synchronized String GetMsg(int Length)<BR>本函数从串口(缓冲区)中读取指定长度的一个字符串。参数Length指定所返回字符串的长度。<BR><BR>public synchronized void PutChar(int c)<BR>本函数望串口缓冲区中写入一个字符，参数c 是需要写入的字符。<BR><BR>在往缓冲区写入数据或者是从缓冲区读取数据的时候，必须保证数据的同步，因此GetMsg和PutChar函数均被声明为synchronized并在具体实现中采取措施实现的数据的同步。<BR>package serial;<BR>&nbsp;/**<BR>&nbsp; *<BR>&nbsp; * This class implements the buffer area to store incoming data from the serial<BR>&nbsp; * port.<BR>&nbsp; *<BR>&nbsp; */<BR>&nbsp;public class SerialBuffer<BR>&nbsp;{<BR>&nbsp; &nbsp;private String Content = "";<BR>&nbsp; &nbsp;private String CurrentMsg, TempContent;<BR>&nbsp; &nbsp;private boolean available = false;<BR>&nbsp; &nbsp;private int LengthNeeded = 1;<BR>&nbsp; &nbsp; &nbsp;/**<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * This function returns a string with a certain length from the incomin<BR>&nbsp; &nbsp; &nbsp; * messages.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * @param Length The length of the string to be returned.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; */<BR>&nbsp; &nbsp;public synchronized String GetMsg(int Length)<BR>&nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp;LengthNeeded = Length;<BR>&nbsp; &nbsp; &nbsp;notifyAll();<BR>&nbsp; &nbsp; &nbsp;if (LengthNeeded &gt; Content.length())<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;available = false;<BR>&nbsp; &nbsp; &nbsp; &nbsp;while (available == false)<BR>&nbsp; &nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;try<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;wait();<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} catch (InterruptedException e) { }<BR>&nbsp; &nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;CurrentMsg &nbsp;= Content.substring(0, LengthNeeded);<BR>&nbsp; &nbsp; &nbsp;TempContent = Content.substring(LengthNeeded);<BR>&nbsp; &nbsp; &nbsp;Content = TempContent;<BR>&nbsp; &nbsp; &nbsp;LengthNeeded = 1;<BR>&nbsp; &nbsp; &nbsp;notifyAll();<BR>&nbsp; &nbsp; &nbsp;return CurrentMsg;<BR>&nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;/**<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * This function stores a character captured from the serial port to the<BR>&nbsp; &nbsp; &nbsp; * buffer area.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * @param t The char value of the character to be stored.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; */<BR>&nbsp; &nbsp;public synchronized void PutChar(int c)<BR>&nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp;Character d = new Character((char) c);<BR>&nbsp; &nbsp; &nbsp;Content = Content.concat(d.toString());<BR>&nbsp; &nbsp; &nbsp;if (LengthNeeded &lt; Content.length())<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;available = true;<BR>&nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;notifyAll();<BR>&nbsp; &nbsp;}<BR>&nbsp;}<BR>&nbsp;&nbsp;&nbsp;3. ReadSerial<BR>ReadSerial是一个进程，它不断的从指定的串口读取数据并将其存放到缓冲区中。 <BR><BR>public ReadSerial(SerialBuffer SB, InputStream Port)<BR>本函数构造一个ReadSerial进程，参数SB指定存放传入数据的缓冲区，参数Port指定从串口所接收的数据流。<BR><BR>public void run()<BR>ReadSerial进程的主函数，它不断的从指定的串口读取数据并将其存放到缓冲区中。<BR>package serial;<BR>&nbsp;import java.io.*;<BR>&nbsp;/**<BR>&nbsp; *<BR>&nbsp; * This class reads message from the specific serial port and save<BR>&nbsp; * the message to the serial buffer.<BR>&nbsp; *<BR>&nbsp; */<BR>&nbsp;public class ReadSerial extends Thread<BR>&nbsp;{<BR>&nbsp; &nbsp;private SerialBuffer ComBuffer;<BR>&nbsp; &nbsp;private InputStream ComPort;<BR>&nbsp; &nbsp; &nbsp;/**<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * Constructor<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; * @param SB The buffer to save the incoming messages.<BR>&nbsp; &nbsp; &nbsp; * @param Port The InputStream from the specific serial port.<BR>&nbsp; &nbsp; &nbsp; *<BR>&nbsp; &nbsp; &nbsp; */<BR>&nbsp; &nbsp;public ReadSerial(SerialBuffer SB, InputStream Port)<BR>&nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp;ComBuffer = SB;<BR>&nbsp; &nbsp; &nbsp;ComPort = Port;<BR>&nbsp; &nbsp;}<BR>&nbsp; &nbsp;public void run()<BR>&nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp;int c;<BR>&nbsp; &nbsp; &nbsp;try<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;while (true)<BR>&nbsp; &nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;c = ComPort.read();<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ComBuffer.PutChar(c);<BR>&nbsp; &nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;} catch (IOException e) {}<BR>&nbsp; &nbsp;}<BR>&nbsp;}<BR>4. SerialExample<BR>SerialExample是本类库所提供的一个例程。它所实现的功能是打开串口COM1，<BR>对其进行初始化，从串口读取信息对其进行处理后将处理结果发送到串口。 <BR>import serial.*;<BR>&nbsp;import java.io.*;<BR>&nbsp;/**<BR>&nbsp; *<BR>&nbsp; * This is an example of how to use the SerialBean. It opens COM1 and reads<BR>&nbsp; * six messages with different length form the serial port.<BR>&nbsp; *<BR>&nbsp; */<BR>&nbsp;class SerialExample<BR>&nbsp;{<BR>&nbsp; &nbsp;public static void main(String[] args)<BR>&nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp;//TO DO: Add your JAVA codes here<BR>&nbsp; &nbsp; &nbsp;SerialBean SB = new SerialBean(1);<BR>&nbsp; &nbsp; &nbsp;String Msg;<BR>&nbsp; &nbsp; &nbsp;SB.Initialize();<BR>&nbsp; &nbsp; &nbsp;for (int i = 5; i &lt;= 10; i++)<BR>&nbsp; &nbsp; &nbsp;{<BR>&nbsp; &nbsp; &nbsp; &nbsp;Msg = SB.ReadPort(i);<BR>&nbsp; &nbsp; &nbsp; &nbsp;SB.WritePort("Reply: " + Msg);<BR>&nbsp; &nbsp; &nbsp;}<BR>&nbsp; &nbsp; &nbsp;SB.ClosePort();<BR>&nbsp; &nbsp;}<BR>&nbsp;}<BR>　本类库中使用了Java Communication API (javax.comm)。这是一个Java扩展类库，<BR>并不包括在标准的Java SDK当中。如果你尚未安装这个扩展类库的话，你应该从<BR>Sun公司的Java站点下载这个类库并将其安装在你的系统上。在所下载的包里面包括<BR>一个安装说明，如果你没有正确安装这个类库及其运行环境的话，运行这个程序的时候<BR>你会找不到串口。<BR>正确安装Java Communication API并将上述程序编译通过以后，<BR>你可以按如下方法测试这个程序。如果你只有一台机器，你可以利用一条<BR>RS-232电缆将COM1和COM2连接起来，在COM1上运行SerialExample，<BR>在COM2上运行Windows提供的超级终端程序。如果你有两台机器的话，<BR>你可以利用一条RS-232电缆将两台机器的COM1(或者是COM2)连接起来，在一端运行例程，<BR>另外一端运行Windows提供的超级终端程序。如果有必要的话，可以对SerialExample中<BR>所声明的串口进行相应改动。 <BR>本程序在Windows 2000 + Java SDK 1.3环境下编译通过并成功运行。 <BR></DIV><img src ="http://www.blogjava.net/fortune/aggbug/33401.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-03-03 11:00 <a href="http://www.blogjava.net/fortune/archive/2006/03/03/33401.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>xml新手入门</title><link>http://www.blogjava.net/fortune/archive/2006/02/28/32832.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Tue, 28 Feb 2006 05:35:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/28/32832.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/32832.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/28/32832.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/32832.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/32832.html</trackback:ping><description><![CDATA[1.什么是 XML？&nbsp;&nbsp;<BR>可扩展标记语言（Extensible Markup Language，XML）提供了一种标记内容的方式，可以添加关于数据用途的信息。信息使用 XML 存储之后，称为解析器的应用程序就能够可靠地提取相关信息，并根据不同的需要处理。<BR><BR><BR><BR>2.XML 可用来做什么？&nbsp;&nbsp;<BR>XML 可用于各种不同的应用程序，但其实质是：XML 是一种表示数据的方式。有时候数据是为数据库准备的，有些时候则是供人阅读的。与这两方面应用相关的技术，比如数据验证和 XML 转换也已经随着 XML 自身一起发展起来。<BR><BR>XML 包括验证或者确认的能力、文档结构和文档（在某种意义上的）内容。验证文档有助于防止数据与期望具有特定结构的应用程序进行交互时出现问题，当 XML 与非 XML 的遗留系统交互时这一点尤其有用。最初的 XML 1.0 推荐标准包括对文档类型定义（Document Type Definitions，DTD）的支持，DTD 提供了一些验证能力。W3C XML Schemas 扩展了这种功能，并提供了一种更加类似 XML 的语法。<BR><BR>可通过多种方式使用 XML 封装的数据。一种常见的处理方式是通过使用可扩展样式表语言转换（Extensible Stylesheet Language Transformations，XSLT），开发人员可以使用 XSLT 定义对 XML 文档的操作，以生成特定的结果。这种动态转换信息的能力允许从单个源文档产生多种输出，无论输出到不同的数据库还是输出到不同的浏览器。<BR><BR>XSL 格式化对象（XSL Formatting Objects，XSL-FO）是一种强大而灵活的格式化数据的 XML 词汇表，常与 XSLT 结合使用，把 XML 和 HTML 转化成 PDF（可移植文档格式）。<BR><BR><BR>3.如何在应用程序开发中使用 XML？&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;开发 XML 应用程序时常用到几种模型。您可以使用根据这些模型创建的 API 来分析和操纵 XML 结构，这些模型可以是基于对象的，如文档对象模型（Document Object Model，DOM）和 JDOM；也可以是基于事件的，如 Simple API for XML（SAX）。另外，Java API for XML Parsing（JAXP）提供了使用 DOM、SAX 和 XSLT 处理 XML 文档的通用接口。<BR><BR>其中最常用的 API 是 DOM，在这种模型里文档的每个成分被描述成特定类型的节点。这些节点按照父子关系组织。各种不同的语言中都有 DOM API 的绑定，如 Java、C++、Perl 和 Python。<BR><BR>SAX 是第二种应用最广的 API。和基于对象的 DOM 模型不同，SAX 是一种基于事件的模型，把文档转化成一系列回调，如 startElement()。<BR><BR>因为 XML 实质上是一种简单的文本，任何人都可以创建处理 XML 的 API。事实上，SAX 并不是由正式的组织创建的，而是由 XML-DEV 邮件列表的成员完成的。由松散组织创建的另一种 API 是 JDOM――它是基于对象的。JDOM 和 DOM 类似，但是和 Java 语言的联系更密切。<BR><BR><BR>4.使用的 XML 语言有哪些？&nbsp;&nbsp;<BR>&nbsp;&nbsp; XML 的优势在于它能够在多种环境中使用。大量涌现的各种 XML 词汇表，使人们能够立即互相理解。三种最常用的词汇表是可扩展超文本标记语言（Extensible HyperText Markup Language，XHTML）、资源定义框架（Resource Definition Framework，RDF）和可缩放向量图形（Scalable Vector Graphics，SVG）。<BR><BR>XHTML 是 XML 形式的 HTML 修订版。XHTML 文档就是遵守 XML 规则的 HTML 文档。同时，从业务和表示两方面定义了其他的 XML 词汇表：RDF 提供了一种向 XML 文档添加信息的方式；SVG 提供了一种使用 XML 指定图形元素的方式（因为 SVG 是基于文本的 XML，不仅可用于动态生成图形，还可用于动画和脚本）；语音可扩展标记语言（Voice Extensible Markup Language，Voice XML）则用于电话菜单和其他语音相关的系统。<BR><BR>大体上了解 XML 之后，使用特定的词汇表只需要理解它所包含的各种元素和属性，以及它所表示的含义。<BR><BR>5. XML 和 Web 服务的关系？&nbsp;&nbsp;<BR>XML 是构建 Web 服务的理想基础，因为它促进了易于标准化和易于理解的消息创建。<BR><BR>6.如何提高 XML 技能？&nbsp;&nbsp;<BR>一旦理解了使用 XML 的基础知识，您会发现有很多需要提高的地方，最好的办法就是慢慢进步。<BR><img src ="http://www.blogjava.net/fortune/aggbug/32832.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-28 13:35 <a href="http://www.blogjava.net/fortune/archive/2006/02/28/32832.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java国际化——资源包的使用</title><link>http://www.blogjava.net/fortune/archive/2006/02/27/32647.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 27 Feb 2006 06:51:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/27/32647.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/32647.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/27/32647.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/32647.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/32647.html</trackback:ping><description><![CDATA[<H4>资源包</H4><BR>在编写应用<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>的时候，需要面对的一个问题是如何来处理与locale相关的一些信息。比如，页面上的一些静态文本就希望能够以用户习惯的语言显示。最原始的做法是将这些信息硬编码到<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>中（可能是一大串判断语句），但是这样就将<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>代码和易变的locale信息捆绑在一起，以后如果需要修改locale信息或者添加其它的locale信息，你就不得不重新修改代码。而资源包可以帮助你解决这个问题，它通过将可变的locale信息放入资源包中来达到两者分离的目的。应用<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>可以自动地通过当前的locale设置到相应的资源包中取得所要的信息。资源包的概念类似于<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>Windows</FONT></A>编程人员使用的资源文件</A>（rc文件</A>）。<BR><BR>一般来说，资源包需要完成两个功能：和具体的locale进行绑定以及读取locale相关信息。<BR><BR>
<H5>ResourceBundle类</H5><BR>你可以把资源包看作为一个由许多成员（子类）组成的大家庭，其中每个成员关联到不同的locale对象，那它是如何完成关联功能的呢？<BR><BR>资源包中的每个成员共享一个被称作基名（base&nbsp;name）的名称，然后在此基础上根据一定的命名规范进行扩展。下面就列出了一些成员的名称：<BR>&nbsp;&nbsp;&nbsp;&nbsp;LabelResources<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LabelResources_de<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LabelResources_de_CH<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LabelResources_de_CH_UNIX<BR>可见这些子类依据这样的命名规范：baseName_language_country_variant，其中language等几个变量就是你在构造Locale类时所使用的。而资源包正是通过这个符合命名规范的名称来和locale进行关联的，比如LabelResource_de_CH就对应于由德语（de）和瑞士（CH）组成的locale对象。<BR><BR>当你的应用<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>需要查找特定locale对象关联的资源包时，它可以调用ResourceBundle的getBundle方法，并将locale对象作为参数传入。<BR>
<DIV class=codeStyle>
<OL>
<LI>
<LI><FONT color=#ff0000>Locale</FONT>&nbsp;currentLocale&nbsp;=&nbsp;<B><FONT color=#0000ff>new</FONT></B>&nbsp;<FONT color=#ff0000>Locale</FONT>(<FONT color=#ff33ff>"de"</FONT>,&nbsp;<FONT color=#ff33ff>"CH"</FONT>,&nbsp;<FONT color=#ff33ff>"UNIX"</FONT>); 
<LI><FONT color=#ff0000>ResourceBundle</FONT>&nbsp;myResources&nbsp;= 
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#ff0000>ResourceBundle</FONT>.getBundle(<FONT color=#ff33ff>"LabelResources"</FONT>,&nbsp;currentLocale);</LI></OL></DIV><BR>如果该locale对象匹配的资源包子类找不到，getBundle将试着查找最匹配的一个子类。具体的查找策略是这样的：getBundle使用基名，locale对象和缺省的locale来生成一个候选资源包名称序列。如果特定locale对象的语言代码、国家代码和可选变量都是空值，则基名是唯一的候选资源包名称。否则的话，具体locale对象（language1，country1和variant1）和缺省locale（language2，country2和variant2）将产生如下的序列：<BR>
<UL><BR>
<LI>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language1&nbsp;+&nbsp;"_"&nbsp;+&nbsp;country1&nbsp;+&nbsp;"_"&nbsp;+&nbsp;variant1<BR>
<LI>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language1&nbsp;+&nbsp;"_"&nbsp;+&nbsp;country1&nbsp;<BR>
<LI>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language1&nbsp;<BR>
<LI>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language2&nbsp;+&nbsp;"_"&nbsp;+&nbsp;country2&nbsp;+&nbsp;"_"&nbsp;+&nbsp;variant2&nbsp;<BR>
<LI>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language2&nbsp;+&nbsp;"_"&nbsp;+&nbsp;country2&nbsp;<BR>
<LI>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language2&nbsp;<BR>
<LI>baseName&nbsp;<BR></LI></UL><BR>然后，getBundle方法按照产生的序列依次查找匹配的资源包子类并对结果子类初始化。首先，它将寻找类名匹配候选资源包名称的类，如果找到将创建该类的一个实例，我们称之为结果资源包。否则，getBundle方法将寻找对应的资源文件</A>，它通过候选资源包名称来获得资源文件</A>的完整路径（将其中的“.”替换为“/”，并加上“.properties”后缀），如果找到匹配文件</A>，getBundle方法将利用该资源文件</A>来创建一个PropertyResourceBundle实例，也就是最终的结果资源包。与此同时，getBundle方法会将这些资源包实例缓存起来供以后使用。<BR><BR>如果没有找到结果资源包，该方法将抛出MissingResourceException异常。所以为了防止异常的抛出，一般来说都需要至少实现一个基名资源包子类。<BR><BR><B>注意：基名参数必须是一个完整的类名称（比如LabelResources，resource.LabelResources等），就相当于你引用一个类时需要指定完整的类路径。但是，为了和以前的版本保持兼容，在使用PropertyResourceBundles时也允许使用“/”来代替“.”表示路径。</B><BR><BR>比如你有以下这些资源类和资源文件</A>：MyResources.class，&nbsp;MyResources_fr_CH.properties，&nbsp;MyResources_fr_CH.class，&nbsp;MyResources_fr.properties，&nbsp;MyResources_en.properties，&nbsp;MyResources_es_ES.class。你利用以下的locale设置来调用getBundle方法，你将会得到不同的结果资源包（假设缺省locale为Locale(“en”,&nbsp;“UK”)），请参考表13.4。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;表13.4&nbsp;locale设置与结果资源包<BR>locale设置&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;结果资源包<BR>Locale("fr",&nbsp;"CH")&nbsp;&nbsp;&nbsp;&nbsp;MyResources_fr_CH.class<BR>Locale("fr",&nbsp;"FR")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResources_fr.properties<BR>Locale("de",&nbsp;"DE")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResources_en.properties<BR>Locale("en",&nbsp;"US")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResources_en.properties<BR>Locale("es",&nbsp;"ES")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResources_es_ES.class<BR><BR>创建了具体的资源包子类实例以后，就需要获得具体的信息。信息在资源包中是以键值对的方式存储的，表13.5列出的是LabelResources.properties文件</A>的内容。<BR><BR>表13.5&nbsp;LabelResources.properties<BR>
<DIV class=codeStyle>
<OL>
<LI>
<LI>#&nbsp;This&nbsp;is&nbsp;LabelResources.properties&nbsp;file 
<LI>greetings&nbsp;=&nbsp;您好！ 
<LI>farewell&nbsp;=&nbsp;再见。 
<LI>inquiry&nbsp;=&nbsp;您好吗？</LI></OL></DIV><BR>其中等号左边的字符</A>串表示主键，它们是唯一的。为了获得主键对应的值，你可以调用ResourceBundle类的getString方法，并将主键作为参数。此外，文件</A>中以“#”号开头的行表示注释行。<BR><BR>
<H5>ListResourceBundle和PropertyResourceBundle子类</H5><BR>抽象类ResourceBundle具有两个子类：ListResourceBundle和PropertyResourceBundle，它们表示资源包子类两种不同的实现方式。<BR><BR>PropertyResourceBundle是和资源文件</A>配对使用的，一个属性文件</A>就是一个普通的文本文件</A>，你只需要为不同的locale设置编写不同名称的资源文件</A>。但是，在资源文件</A>中只能包含字符</A>串，如果需要存储其它类型对象，你可以使用ListResourceBundle。<BR><BR>ListResourceBundle是将键值对信息保存在类中的列表中，而且你必须实现ListResourceBundle的具体子类。<BR><BR>如果ListResourceBundle和PropertyResourceBundle不能够满足你的需要，你可以实现自己的ResourceBundle子类，你的子类必须覆盖两个方法：handleGetObject和getKeys。<BR><BR>
<H5>使用资源文件</A></H5><BR>使用资源包最简单的方法就是利用资源文件</A>，利用资源文件</A>一般需要以下几个步骤：<BR>1、创建一个缺省的资源文件</A><BR>为了防止找不到资源文件</A>，你最好实现一个缺省的资源文件</A>，该文件</A>的名称为资源包的基名加上.properties后缀。<BR>2、创建所需的资源文件</A><BR>为你准备支持的locale设置编写对应的资源文件</A>。<BR>3、设置locale<BR>你必须在<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>中的某个地方提供locale的设置或者切换功能，或者将其放入配置文件</A>中。<BR>4、根据locale设置创建资源包<BR>ResourceBundle&nbsp;resource&nbsp;=<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ResourceBundle.getBundle("LabelBundle",currentLocale);<BR>5、通过资源包获取locale相关信息<BR>String&nbsp;value&nbsp;=&nbsp;resource.getString("welcome");<BR><BR><B>注意：在使用基名的时候，特别要注意给出完整的类名（或者路径名），比如你的应用<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>所在的类包为org.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>research.j2seimproved.i18n，而你的资源文件</A>在你的应用<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>下的resource子目录中，那你的基名就应该是org.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>research.j2seimproved.i18n.resource.LabelBundleBundle而不是resource.LabelBundleBundle。<BR></B><BR><BR>
<H5>使用ListResourceBundle</H5><BR>使用ListResourceBundle和使用资源文件</A>的步骤基本上一样，只不过你需要用ListResourceBundle子类来替换相应的资源文件</A>。比如你的应用<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>的基名是LabelBundle，而且准备支持Locale("en","US")和Locale("zh","CN")，那你需要提供以下几个<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>Java</FONT></A>文件</A>，注意类名和locale的对应关系。<BR>LabelBundle_en_US.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A><BR>LabelBundle_zh_CN.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A><BR>LabelBundle.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>（缺省类）<BR><BR>代码13.3列出的是LabelBundle_zh_CN.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>的源代码，相对于资源文件</A>中“key&nbsp;=&nbsp;value”的写法，在此文件</A>中你首先利用键值对来初始化一个二维数组，并在getContents方法中返回该数组。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>代码13.3：LabelBundle_zh_CN.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A><BR>
<DIV class=codeStyle>
<OL>
<LI><FONT color=#246398></FONT>
<LI><B><FONT color=#0000ff>package</FONT></B>&nbsp;org.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>research.j2seimproved.i18n;<B><FONT color=#0000ff>import</FONT></B>&nbsp; 
<LI>
<LI><A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>.util.<B><A class=wordstyle href="http://blog.cnbie.com/source/jdk142/<a%20target=" _blank?><FONT color=#246398>java</FONT></A></A>/util/ListResourceBundle.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>.html" target="_blank"&gt;<FONT class=classLink><U>ListResourceBundle</U></FONT></A></B>; 
<LI>
<LI><B><FONT color=#0000ff>public</FONT></B>&nbsp;<B><FONT color=#0000ff>class</FONT></B>&nbsp;LabelBundle_zh_CN&nbsp;<B><FONT color=#0000ff>extends</FONT></B>&nbsp;<FONT color=#ff0000>ListResourceBundle</FONT>&nbsp;{&nbsp;&nbsp;&nbsp; 
<LI>&nbsp;&nbsp;<B><FONT color=#0000ff>public</FONT></B>&nbsp;<B><A class=wordstyle href="http://blog.cnbie.com/source/jdk142/<a%20target=" _blank?><FONT color=#246398>java</FONT></A></A>/lang/Object.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>.html" target="_blank"&gt;<FONT class=classLink><U>Object</U></FONT></A></B>[][]&nbsp;getContents()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<LI>&nbsp;&nbsp;&nbsp;&nbsp;<B><FONT color=#0000ff>return</FONT></B>&nbsp;contents;&nbsp;&nbsp;&nbsp; 
<LI>&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; 
<LI>
<LI>&nbsp;&nbsp;<B><FONT color=#0000ff>private</FONT></B>&nbsp;<B><A class=wordstyle href="http://blog.cnbie.com/source/jdk142/<a%20target=" _blank?><FONT color=#246398>java</FONT></A></A>/lang/Object.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>.html" target="_blank"&gt;<FONT class=classLink><U>Object</U></FONT></A></B>[][]&nbsp;contents&nbsp;=&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<LI>&nbsp;&nbsp;&nbsp;&nbsp;{<FONT color=#ff33ff>"title"</FONT>,&nbsp;<FONT color=#ff33ff>"称谓"</FONT>},&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<LI>&nbsp;&nbsp;&nbsp;&nbsp;{<FONT color=#ff33ff>"surname"</FONT>,&nbsp;<FONT color=#ff33ff>"姓"</FONT>},&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<LI>&nbsp;&nbsp;&nbsp;&nbsp;{<FONT color=#ff33ff>"firstname"</FONT>,&nbsp;<FONT color=#ff33ff>"名"</FONT>},&nbsp;&nbsp;&nbsp; 
<LI>&nbsp;&nbsp;}; 
<LI>}</LI></OL></DIV><BR><BR>创建完资源类以后，同样需要设置locale以及根据locale来创建资源包。在通过资源包获取具体值的时候，你不能再使用getString方法，而应该调用getObject方法，而且由于getObject方法返回一个Object对象，你还需要进行正确的类型转换。其实，为了你的<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>通用性，我们建议在使用资源文件</A>的时候你也应该调用getObject方法，而不是getString方法。<BR>
<DIV class=codeStyle>
<OL>
<LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;<B><A class=wordstyle href="http://blog.cnbie.com/source/jdk142/<a%20target=" _blank?><FONT color=#246398>java</FONT></A></A>/lang/String.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>.html" target="_blank"&gt;<FONT class=classLink><U>String</U></FONT></A></B>&nbsp;title&nbsp;=&nbsp;(<B><A class=wordstyle href="http://blog.cnbie.com/source/jdk142/<a%20target=" _blank?><FONT color=#246398>java</FONT></A></A>/lang/String.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>.html" target="_blank"&gt;<FONT class=classLink><U>String</U></FONT></A></B>)resource.getObject(<FONT color=#ff33ff>"title"</FONT>);</LI></OL></DIV><BR>关于ListResourceBundle的详细使用，可以参考本书所附代码中国际化一节的ListResourceBundleSample.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A><A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>。<BR><BR>
<H5>MessageFormat类</H5><BR>上面我们讲到利用资源文件</A>来分离代码和可变的信息。但是在实际过程中，有些信息并不能够完全事先定义好，其中可能会用到运行时的一些结果，最典型例子的就是错误提示代码，比如提示某个输入必须在一定范围内。利用上面所讲的资源文件</A>并不能够很好地解决这个问题，所以<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>Java</FONT></A>中引入了MessageFormat类。<BR><BR>MessageFormat提供一种语言无关的方式来组装消息，它允许你在运行时刻用指定的参数来替换掉消息字符</A>串中的一部分。你可以为MessageFormat定义一个模式，在其中你可以用占位符来表示变化的部分，比如你有这样一句话：<BR><BR>您好，<U>peachpi</U>！欢迎来到<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>Java</FONT></A>研究组织网站！当前时间是：<U>2003-8-1&nbsp;16:43:12。</U><BR><BR>其中斜体带下划线的部分为可变化的，你需要根据当前时间和不同的登录用户来决定最终的显示。我们用占位符来表示这些变化的部分，可以得到下面这个模式：<BR><BR>您好，{0}！欢迎来到<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>Java</FONT></A>研究组织网站！当前时间是：{1,date}&nbsp;{1,time}。<BR><BR>占位符的格式为{&nbsp;ArgumentIndex&nbsp;,&nbsp;FormatType&nbsp;,&nbsp;FormatStyle&nbsp;}，详细说明可以参考MessageFormat的API说明文档。这里我们定义了两个占位符，其中的数字对应于传入的参数数组中的索引，{0}占位符被第一个参数替换，{1}占位符被第二个参数替换，依此类推。<BR>最多可以设置10个占位符，而且每个占位符可以重复出现多次，而且格式可以不同，比如{1,date}和{1,time}。而通过将这些模式定义放到不同的资源文件</A>中，就能够根据不同的locale设置，得到不同的模式定义，并用参数动态替换占位符。<BR><BR>下面我们就以MessageFormatSample.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A><A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>程序</FONT></A></A>（源文件</A>见本书所附代码）为例，来详细说明其中的每个步骤。<BR>1、找出可变的部分，并据此定义模式，将模式放入不同的资源文件</A>中。<BR>比如针对上面的模式，定义了下面两个资源文件</A>：<BR>MessagesBundle_en_US.properties<BR>Welcome&nbsp;=&nbsp;Hi,&nbsp;{0}!&nbsp;Welcome&nbsp;to&nbsp;<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>Java</FONT></A>&nbsp;Research&nbsp;Organization!<BR>MessagesBundle_zh_CN.properties<BR>Welcome&nbsp;=&nbsp;您好，{0}！欢迎来到<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>Java</FONT></A>研究组织网站！<BR><BR>2、创建MessageFormat对象，并设置其locale属性。<BR>
<DIV class=codeStyle>
<OL>
<LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#ff0000>MessageFormat</FONT>&nbsp;formatter&nbsp;=&nbsp;<B><FONT color=#0000ff>new</FONT></B>&nbsp;<FONT color=#ff0000>MessageFormat</FONT>(<FONT color=#ff33ff>""</FONT>); 
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatter.setLocale(currentLocale);</LI></OL></DIV><BR>3、从资源包中得到模式定义，以及设置参数。<BR>
<DIV class=codeStyle>
<OL>
<LI>
<LI>messages&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#ff0000>ResourceBundle</FONT>.getBundle( 
<LI>&nbsp;&nbsp;<FONT color=#ff33ff>"org.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>research.j2seimproved.i18n.resource.MessagesBundle"</FONT>,currentLocale); 
<LI><B><A class=wordstyle href="http://blog.cnbie.com/source/jdk142/<a%20target=" _blank?><FONT color=#246398>java</FONT></A></A>/lang/Object.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>.html" target="_blank"&gt;<FONT class=classLink><U>Object</U></FONT></A></B>[]&nbsp;testArgs&nbsp;=&nbsp;{<FONT color=#ff33ff>"peachpi"</FONT>,<B><FONT color=#0000ff>new</FONT></B>&nbsp;<FONT color=#ff0000>Date</FONT>()};</LI></OL></DIV><BR>4、利用模式定义和参数进行格式化。<BR>
<DIV class=codeStyle>
<OL>
<LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B><A class=wordstyle href="http://blog.cnbie.com/source/jdk142/<a%20target=" _blank?><FONT color=#246398>java</FONT></A></A>/lang/System.<A class=wordstyle href="http://www.itlove.net/" target=_blank><FONT color=#246398>java</FONT></A></A>.html" target="_blank"&gt;<FONT class=classLink><U>System</U></FONT></A></B>.out.println(formatter.format(messages.getString(<FONT color=#ff33ff>"welcome"</FONT>),testArgs));</LI></OL></DIV><BR><BR>
<H5>关于资源包的组织</H5><BR>一般来说，你是按照资源的用途来组织资源包的，比如会把所有的页面按钮的信息放入一个名为ButtonResources的资源包中。在实际的应用过程中，以下几个原则可以帮你决定如何组织资源包：<BR>1、要易于维护。<BR>2、最好不要将所有的信息都放入一个资源包中，因为这样资源包载入内存时将会很耗时。<BR>3、最好将一个大的资源包分为几个小的资源包，这样可以在使用的时候才导入必须的资源，减少内存消耗。<BR><img src ="http://www.blogjava.net/fortune/aggbug/32647.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-27 14:51 <a href="http://www.blogjava.net/fortune/archive/2006/02/27/32647.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java 关于线程的停止问题</title><link>http://www.blogjava.net/fortune/archive/2006/02/27/32641.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Mon, 27 Feb 2006 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/27/32641.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/32641.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/27/32641.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/32641.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/32641.html</trackback:ping><description><![CDATA[多线程是<A class=wordstyle href="http://www.itlove.net/" target=_blank>java</A></A>的一个优势，<A class=wordstyle href="http://www.itlove.net/" target=_blank>java</A></A>使得<A class=wordstyle href="http://www.itlove.net/" target=_blank>程序</A></A>员可以很方便的进行多线程<A class=wordstyle href="http://www.itlove.net/" target=_blank>程序</A></A><A class=wordstyle href="http://www.itlove.net/" target=_blank>开发</A>。获得更好的性能。<BR>关于多线程的概念以及一般的多线程编程，比如如何以及为何实现runnable接口，为何stop()会被Deprecated掉等等，这个请看matrix之前的多线程编程基础或者sun的<A class=wordstyle href="http://www.itlove.net/" target=_blank>java</A></A>文档。<BR>关于多线程编程，有几点这里要提到的：<BR>1。既然stop()是不被推荐的，那么我们如何停止一个线程呢？直接kill吗？在这里，笔者总结一种比较通用也比较稳定的方法：<BR><BR>class threadtest extend Thread{<BR>//skip some code..<BR><BR><BR>boolean runflag=true; <BR><BR>public synchronized void stopthread()<BR>{<BR>runflag=false; <BR>}<BR><BR>public synchronized boolean getrunflag()<BR>{<BR>return runflag; <BR>} <BR><BR>public void run() {<BR>runflag=true;<BR>try {<BR>while (getrunflag()) {<BR>code1；<BR>code2； <BR>//put your code here<BR>}<BR>}<BR>}<BR>catch (IOException e) {<BR>e.printStackTrace();<BR>}<BR>System.out.println(this.getClass().getName()+" stopped");<BR>}<BR><BR>//skip some code..<BR>} <BR><BR><BR>这样，每当需要停止该线程时，只需调用stopthread()即可。<BR><BR>这里有两点需要注意：<BR><BR>1）我们用了一个同步方法getrunflag()来得到当前的状态，为什么用这个方法而不是直接使用while(runflag)呢？<BR>这个是因为在<A class=wordstyle href="http://www.itlove.net/" target=_blank>java</A></A>的多线程模型中，有一个公共的对象存储区，但是每个对象都有自己的私有备份，当一个线程改变了状态，jvm并不能保证这个线程改变过的变量即时更新公共对象存储区的状态，可能(可能性不大)造成问题。<BR>所以建议有好的设计习惯，采用同步方法来获得当前的runflag值。<BR><BR>2）还有一点，特别是涉及<A class=wordstyle href="http://www.itlove.net/" target=_blank>网络</A></A>的多线程，如果发生了<A class=wordstyle href="http://www.itlove.net/" target=_blank>网络</A></A>阻塞(在while循环里面发生)，那么，即使runflag状态比如改变成false，由于<A class=wordstyle href="http://www.itlove.net/" target=_blank>程序</A></A>被阻塞，线程用这种方法是永远都不会被停止的。<BR>举个例子：比如上面的<A class=wordstyle href="http://www.itlove.net/" target=_blank>程序</A></A>，如果code1是一段<A class=wordstyle href="http://www.itlove.net/" target=_blank>网络</A></A>程式，如果在code1发生了阻塞，阻塞的意义就是得不到请求的<BR>资源，在无限期等待，这个时候，runflag状态的变化对while循环是起不了作用的，线程不会被停止。<BR>笔者曾经参与多个涉及到获取<A class=wordstyle href="http://www.itlove.net/" target=_blank>网络</A></A>资源的<A class=wordstyle href="http://www.itlove.net/" target=_blank>java</A></A>程式，经常遇到因为<A class=wordstyle href="http://www.itlove.net/" target=_blank>网络</A></A>的阻塞引起的线程问题。<BR>如果你的程式可能涉及到<A class=wordstyle href="http://www.itlove.net/" target=_blank>网络</A></A>阻塞，或者有可能发生某种消息接受的阻塞。那么，请不要用这种方法来停止线程。具体方法请看笔者另外一片文章：高级多线程编程(二)-多线程中的监控与超时问题。<BR><img src ="http://www.blogjava.net/fortune/aggbug/32641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-27 14:45 <a href="http://www.blogjava.net/fortune/archive/2006/02/27/32641.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>摸吊居士戒烟客</title><link>http://www.blogjava.net/fortune/archive/2006/02/26/32517.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Sun, 26 Feb 2006 12:08:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/26/32517.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/32517.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/26/32517.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/32517.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/32517.html</trackback:ping><description><![CDATA[最近因为要吃药治鼻炎烟抽得少多了，其实常常想着要戒掉，无奈......<BR>哎我做过好几回摸吊居士戒烟客了<img src ="http://www.blogjava.net/fortune/aggbug/32517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-26 20:08 <a href="http://www.blogjava.net/fortune/archive/2006/02/26/32517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java图形用户界面设计（转</title><link>http://www.blogjava.net/fortune/archive/2006/02/24/32312.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Fri, 24 Feb 2006 09:26:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/24/32312.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/32312.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/24/32312.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/32312.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/32312.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width="100%">
<H1>&nbsp;</H1>
<P id=subtitle>深入了解布局管理器</P><IMG class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></TD>
<TD class=no-print width=192><IMG height=18 alt=developerWorks src="http://www-128.ibm.com/developerworks/i/dw.gif" width=192></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width=10><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></TD>
<TD width="100%">
<TABLE class=no-print cellSpacing=0 cellPadding=0 width=160 align=right border=0>
<TBODY>
<TR>
<TD width=10><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></TD>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width=150 border=0>
<TBODY>
<TR>
<TD class=v14-header-1-small></TD></TR></TBODY></TABLE>
<TABLE class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=no-padding width=150>
<TABLE cellSpacing=0 cellPadding=0 width=143 border=0><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8> 
<FORM name=email action=https://www-130.ibm.com/developerworks/secure/email-it.jsp>
<SCRIPT language=JavaScript type=text/javascript>
<!--
document.write('<tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/></td><td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送" /></td><td width="122"><p><a class="smallplainlink" href="javascript:document.email.submit();"><b>将此页作为电子邮件发送</b></a></p></td></tr>');
//-->
</SCRIPT>
&nbsp; 
<TBODY>
<TR vAlign=top>
<TD width=8><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></TD>
<TD width=16></TD>
<TD width=122>
<P><A class=smallplainlink href="javascript:document.email.submit();"><B><FONT color=#5c81a7 size=2>将此页作为电子邮件送</FONT></B></A></P></TD></TR><NOSCRIPT><tr valign="top"><td width="8"><img alt="" height="1" width="8" src="//www.ibm.com/i/c.gif"/></td><td width="16"><img alt="" width="16" height="16" src="//www.ibm.com/i/c.gif"/></td><td class="small" width="122"><p><span class="ast">未显示需要 JavaScript 的文档选项</span></p></td></tr></NOSCRIPT></FORM></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE cellSpacing=0 cellPadding=0 width=150 border=0>
<TBODY>
<TR>
<TD class=v14-header-1-small>对此页的评价</TD></TR></TBODY></TABLE>
<TABLE class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=no-padding width=150>
<TABLE cellSpacing=0 cellPadding=0 width=143 border=0>
<TBODY>
<TR vAlign=top>
<TD width=8><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></TD>
<TD><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/d_bold.gif" width=16 vspace=3 border=0></TD>
<TD width=125>
<P><A class=smallplainlink href="http://www-128.ibm.com/developerworks/cn/java/l-javagui/index.html#rate"><B><FONT color=#996699 size=2>帮助我们改进这些内容</FONT></B></A></P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE>
<P>2002 年 7 月 05 日</P>
<BLOCKQUOTE>本文试图通过作者自己的开发经历介绍一些具体的应用实例，希望能给那些曾经象作者一样苦闷的Java痴迷者一些帮助。</BLOCKQUOTE>
<P><A name=1><SPAN class=atitle><FONT face=Arial size=4>前言</FONT></SPAN></A></P>
<P><FONT face=Arial size=4></FONT>
<P>随着Internet的飞速发展，Java技术也得到了越来越广泛的应用。而无论我们是采用J2SE、J2EE还是J2ME，GUI都是不能回避的问题。现在的应用软件越来越要求界面友好、功能强大而又使用简单。而众所周知，在Java中进行GUI设计相对于其跨平台、多线程等特性的实现要复杂和麻烦许多。这也是很多Java程序员抱怨的事情。但GUI已经成为程序发展的方向，所以我们也必须了解Java的GUI设计方法和特点。其实，采用Java提供的布局管理器接口和相应的布局管理类，我们也可以做出相当漂亮的界面来，当然实现起来肯定要比VB麻烦许多。本文试图通过自己的开发经历介绍一些具体的应用实例，希望能给那些曾经象我一样苦闷的Java痴迷者一些帮助。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/l-javagui/index.html#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=2><SPAN class=atitle><FONT face=Arial size=4>Java中的布局管理器</FONT></SPAN></A></P>
<P><FONT face=Arial size=4></FONT>
<P><A name=N1004E><SPAN class=smalltitle><STRONG><FONT face=Arial>2.1 为什么要使用布局</FONT></STRONG></SPAN></A></P>
<P><STRONG><FONT face=Arial></FONT></STRONG>
<P>在实际编程中，我们每设计一个窗体，都要往其中添加若干组件。为了管理好这些组件的布局，我们就需要使用布局管理器。比如说，设计一个简单的计算器，或一个文本编辑器等等。这些组件是让JVM 自己任意安排呢？还是按照一定的位置关系进行规范的安排呢？当然应该选择后者。将加入到容器的组件按照一定的顺序和规则放置，使之看起来更美观，这就是布局。在Java中，布局由布局管理器 (LayoutManager) 来管理。那么，我们在什么时候应该使用布局管理器？应选择哪种布局管理器？又该怎样使用布局管理器呢？</P>
<P>如果你写的是GUI程序，在使用AWT/Swing组件时就不应硬性设置组件的大小和位置，而应该使用Java的布局管理器（LayoutManager）来设置和管理可视组件的大小和位置，否则就有可能造成布局混乱。不信，你可以新建一个Frame（或JFrame），通过setBounds()方法往其中添加几个Button（或JButton），一旦你将窗体拉大或缩小时，你会发现组件的排列完全不是按你所预想的那样。为了解决这个问题，即当窗体（或容器）缩放时，组件位置也随之合理调整，我们就需要使用布局管理器。</P>
<P>为此，我们首先要知道Java的布局方式，Java提供的API中有些什么布局管理器，它们的布局特点是什么。</P>
<P><A name=N1005F><SPAN class=smalltitle><STRONG><FONT face=Arial>2.2 Java的布局方式</FONT></STRONG></SPAN></A></P>
<P><STRONG><FONT face=Arial></FONT></STRONG>
<P>我们都知道，Java的GUI界面定义是由AWT类包和Swing类包来完成的。它在布局管理上采用了容器和布局管理分离的方案。也就是说，容器只管将其他组件放入其中，而不管这些组件是如何放置的。对于布局的管理交给专门的布局管理器类（LayoutManager）来完成。</P>
<P>现在我们来看Java中布局管理器的具体实现。我们前面说过，Java中的容器类（Container），它们只管加入组件（Component），也就是说，它只使用自己的add()方法向自己内部加入组件。同时他记录这些加入其内部的组件的个数，可以通过container.getComponentCount()方法类获得组件的数目，通过container.getComponent(i)来获得相应组件的句柄。然后LayoutManager类就可以通过这些信息来实际布局其中的组件了。</P>
<P>Java已经为我们提供了几个常用的布局管理器类，例如： FlowLayout、BorderLayout、GridLayout、GridBagLayout等。下面列表说明它们的布局特点：</P>
<TABLE width="60%" border=1>
<TBODY>
<TR>
<TD>包</TD>
<TD>类</TD>
<TD>特点</TD></TR>
<TR>
<TD>java.awt</TD>
<TD>CardLayout</TD>
<TD>将组件象卡片一样放置在容器中，在某一时刻只有一个组件可见</TD></TR>
<TR>
<TD>java.awt</TD>
<TD>FlowLayout</TD>
<TD>将组件按从左到右而后从上到下的顺序依次排列，一行不能放完则折到下一行继续放置</TD></TR>
<TR>
<TD>java.awt</TD>
<TD>GridLayout</TD>
<TD>形似一个无框线的表格，每个单元格中放一个组件</TD></TR>
<TR>
<TD>java.awt</TD>
<TD>BorderLayout</TD>
<TD>将组件按东、南、西、北、中五个区域放置，每个方向最多只能放置一个组件</TD></TR>
<TR>
<TD>java.awt</TD>
<TD>GridBagLayout</TD>
<TD>非常灵活，可指定组件放置的具体位置及占用单元格数目</TD></TR>
<TR>
<TD>Javax.swing</TD>
<TD>BoxLayout</TD>
<TD>就像整齐放置的一行或者一列盒子，每个盒子中一个组件</TD></TR>
<TR>
<TD>Javax.swing</TD>
<TD>SpringLayout</TD>
<TD>根据一组约束条件放置子组件</TD></TR>
<TR>
<TD>Javax.swing</TD>
<TD>ScrollPaneLayout</TD>
<TD>专用于JScrollPane，含一个Viewport，一个行头、一个列头、两个滚动条和四个角组件</TD></TR>
<TR>
<TD>Javax.swing</TD>
<TD>OverlayLayout</TD>
<TD>以彼此覆盖的形式叠置组件</TD></TR>
<TR>
<TD>Javax.swing</TD>
<TD>ViewportLayout</TD>
<TD>JViewport的默认布局管理器</TD></TR></TBODY></TABLE>
<P>事实上，在大多数情况下，综合运用好这些布局管理器已可以满足需要。当然对于特殊的具体应用，我们可以通过实现LayoutManager或LayoutManager2接口来定义自己的布局管理器。下面我们通过几个实例来了解几个常用的布局管理器的使用方法。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/l-javagui/index.html#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=3><SPAN class=atitle><FONT face=Arial size=4>GUI设计应用实例</FONT></SPAN></A></P>
<P><FONT face=Arial size=4></FONT>
<P><A name=N10104><SPAN class=smalltitle><STRONG><FONT face=Arial>3.1 FlowLayout/GridLayout/BorderLayout的应用实例</FONT></STRONG></SPAN></A></P>
<P><STRONG><FONT face=Arial></FONT></STRONG>
<P><STRONG>3.1.1应用背景</STRONG> </P>
<P>假设我们要编写一个简单的计算器JApplet，其基本界面如下：</P><BR><A name=N10117><B></A><BR><IMG height=295 alt="" src="http://www-128.ibm.com/developerworks/cn/java/l-javagui/1.gif" width=420> <BR>
<P><B>3.1.2解决方法</B> </P>
<P>通过其界面要求可知，我们可以通过将"BackSpace"和"Clear"JButton放置在一个JPanel（1）中，采用FlowLayout布局；将显示结果的JTextField和该JPanel一起放置到另外一个JPanel（2），采用GridLayout布局；而将其它的JButton则放置在另外一个JPanel（3）中，采用GridLayout布局；再将JPanel（2）和JPanel（3）加入该JApplet，即可实现界面需求。具体实现方法如下：</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console">/**以FlowLayout布局JPanel（1）*/
JPanel p1 = new JPanel(new FlowLayout()); //默认组件从居中开始
//加入"BackSpace"和"Clear"JButton
p1.add(backButton);    
p1.add(clearButton);
/**以GridLayout布局JPanel（2）*/
JPanel p2 = new JPanel(new GridLayout(2, 1));   //放置2行，每行1个组件
//加入显示结果的JTextField和JPanel（1）
p2.add(displayField);  
p2.add(p1);
/**以GridLayout布局JPanel（3）*/
JPanel p3 = new JPanel(new GridLayout(4, 5));   //放置4行，每行5个组件
String buttonStr = "789/A456*B123-C0.D+=";
for (int i = 0; i &lt; buttonStr.length(); i++)
this.addButton(p3, buttonStr.substring(i, i + 1));
	
//addButton方法
	private void addButton(Container c, String s)
    {
        JButton b = new JButton(s);
        if (s.equals("A"))
            b.setText("sqrt");
        else if (s.equals("B"))
            b.setText("1/x");
        else if (s.equals("C"))
            b.setText("%");
        else if (s.equals("D"))
            b.setText("+/-");
        b.setForeground(Color.blue);
        c.add(b);
        b.addActionListener(this);
    }
/**以BorderLayout布局JApplet*/
	this.setLayout(new BorderLayout());
this.add(p2, "North");
this.add(p3, "Center");
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P>这样，就一切OK啦。具体的实现代码可参见附件中的CalculateApplet.java文件。</P>
<P><A name=N10133><SPAN class=smalltitle><FONT face=Arial>3.2 带工具栏和状态栏的GridLayout/BorderLayout应用实例</FONT></SPAN></A></P>
<P><FONT face=Arial></FONT>
<P><B>3.2.1实际问题</B> </P>
<P>在很多情况下我们需要动态设置工具栏和状态栏，看下面的应用实例：</P><BR><A name=N10146><B></A><BR><IMG height=406 alt="" src="http://www-128.ibm.com/developerworks/cn/java/l-javagui/2.gif" width=470> <BR>
<P>以上是在视图的工具栏和状态栏都被复选的时候，以下分别为某一个没选或都未选的情况。</P><BR><A name=N10157><B></A><BR><IMG height=370 alt="" src="http://www-128.ibm.com/developerworks/cn/java/l-javagui/3.gif" width=470> <BR>
<P><B>3.2.2解决方法</B> </P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console">	/**工具栏JToolBar采用从左开始的FlowLayout布局*/
JToolBar toolBar = new JToolBar();	
toolBar.setBorderPainted(false); //不画边界
    toolBar.setLayout(new FlowLayout(FlowLayout.LEFT));
	
/**窗体采用动态的BorderLayout布局，通过获取工具栏或状态栏的复选标记进行界面的动态调整*/
JSplitPane splitPane = new JSplitPane();
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); //设置统计窗口分隔条的方向
splitPane.setDividerLocation(300); 	//设置分隔条的位置
splitPane.setOneTouchExpandable(true);
JCheckBoxMenuItem toolBarItem = new JCheckBoxMenuItem("工具栏(T)", true);
    JLabel statusLabel = new JLabel("当前统计目标:");
    JCheckBoxMenuItem statusBarItem = new JCheckBoxMenuItem("状态栏(S)", true);

/**设置系统窗体布局并动态设置工具栏和状态栏*/
    private void setLayout()
    {
        if (toolBarItem.getState() &amp;&amp;' statusBarItem.getState())
        {
            this.getContentPane().add(BorderLayout.NORTH, toolBar);
            this.getContentPane().add(BorderLayout.CENTER, splitPane);
            this.getContentPane().add(BorderLayout.SOUTH, statusLabel);
        }
        else if (toolBarItem.getState() &amp;&amp; !statusBarItem.getState())
        {
            this.getContentPane().add(BorderLayout.NORTH, toolBar);
            this.getContentPane().remove(statusLabel);
        }
        else if (statusBarItem.getState() &amp;&amp; !toolBarItem.getState())
        {
            this.getContentPane().add(BorderLayout.SOUTH, statusLabel);
            this.getContentPane().remove(toolBar);
        }
        else if (!toolBarItem.getState() &amp;&amp; !statusBarItem.getState())
        {
            this.getContentPane().remove(toolBar);
            this.getContentPane().remove(statusLabel);
        }
        this.show(); //添加或移去组件后刷新界面
    }
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P>通过该方法即可实现界面的动态刷新与调整。</P>
<P><A name=N10170><SPAN class=smalltitle><FONT face=Arial>3.3 GridBagLayout应用实例</FONT></SPAN></A></P>
<P><FONT face=Arial></FONT>
<P><B>3.3.1实际问题</B> </P>
<P>GridBagLayout是Java API提供的一个较复杂的布局管理器，利用好它可以解决许多实际编程中的令人烦恼的界面设计问题。看下面的界面应用实例：</P><BR><A name=N10183><B></A><BR><IMG height=359 alt="" src="http://www-128.ibm.com/developerworks/cn/java/l-javagui/5.gif" width=602> <BR>
<P><B>3.3.2解决方法</B> </P>
<P>这个界面的设计比较复杂，涉及多个标签域（JLabel）、文本域（JTextField、JTextArea），且标签域的大小还不一样，如附件标签；并当窗体缩放时，标签域的大小应不改变，而文本域则必须自适应缩放。如何来实现呢？请看下面的代码：（工具栏的实现不再赘述）</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console">/**系统的界面布局实现*/
GridBagConstraints gridBag = new GridBagConstraints();
gridBag.fill = GridBagConstraints.HORIZONTAL;  //以水平填充方式布局
    gridBag.weightx = 0;  //行长不变
    gridBag.weighty = 0;  //列高不变
    fromLabel.setForeground(Color.blue);
    fromLabel.setFont(new Font("Alias", Font.BOLD, 16));
    this.add(fromLabel, gridBag, 0, 1, 1, 1);  //指定发信人标签位置
    receiveLabel.setForeground(Color.blue);
    receiveLabel.setFont(new Font("Alias", Font.BOLD, 16));
    this.add(receiveLabel, gridBag, 0, 2, 1, 1); //指定收信人标签位置及大小
    ccLabel.setForeground(Color.blue);
    ccLabel.setFont(new Font("Alias", Font.BOLD, 16));
    this.add(ccLabel, gridBag, 0, 3, 1, 1); //指定抄送人标签位置及大小
    subjectLabel.setForeground(Color.blue);
    subjectLabel.setFont(new Font("Alias", Font.BOLD, 16));
    his.add(subjectLabel, gridBag, 0, 4, 1, 1); //指定主题标签位置及大小
    accessoryLabel.setForeground(Color.blue);
    accessoryLabel.setFont(new Font("Alias", Font.BOLD, 16));
    this.add(accessoryLabel, gridBag, 0, 5, 1, 1); //指定附件标签位置及大小

    gridBag.weightx = 100; //行自适应缩放
    gridBag.weighty = 0;//列高不变
    fromField.setText("admin@watermelon.com");
   	this.add(fromField, gridBag, 1, 1, 2, 1); //指定发信人文本域（JTextField）位置及大小
    this.add(receiveField, gridBag, 1, 2, 2, 1); //指定收信人文本域（JTextField）位置及大小
    this.add(ccField, gridBag, 1, 3, 2, 1); //指定抄送人文本域（JTextField）位置及大小
    this.add(subjectField, gridBag, 1, 4, 2, 1); //指定主题文本域（JTextField）位置及大小
    accessoryArea.setEditable(false); 
//设置不显示水平滚动条（该JTextArea置于JScrollPane中）
accessoryScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    this.add(accessoryScroll, gridBag, 1, 5, 2, 1); //指定附件文本区（JTextArea）位置及大小

    gridBag.fill = GridBagConstraints.BOTH;//采用全填充方式布局
    gridBag.weightx = 100;//行自适应缩放
    gridBag.weighty = 100;//列自适应缩放
    mailArea.setBackground(Color.blue);
    mailArea.setForeground(Color.yellow);
    mailArea.setTabSize(4);
    //指定信件主体区（JTextArea）的位置及大小。（该JTextArea也置于JScrollPane中）
	this.add(scroll, gridBag, 0, 6, 3, 1);

	在上面用到一个方法add()，这个方法是自己定义的：
private void add(Component c, GridBagConstraints gbc, int x, int y, int w, int h)
    {
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridheight = h;
        gbc.gridwidth = w;
        this.getContentPane().add(c, gbc);
    }
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P>在用到GridBagLayout布局管理器的组件添加方法中，都可以重用它。事实上，你还可以在方法最前面加一个参数Container cn，而将方法中的this相应的改为cn，就可以通用于所有需要使用GridBagLayout进行布局管理的容器中。在下面的复杂例程中我们就会用到。</P>
<P><A name=N1019F><SPAN class=smalltitle><FONT face=Arial>3.4 综合多个布局的复杂应用实例</FONT></SPAN></A></P>
<P><FONT face=Arial></FONT>
<P><B>3.4.1实际问题</B> </P>
<P>请看下面的实际应用界面要求：</P><BR><A name=N101B2><B>（图3.4-1）</B></A><BR><IMG height=310 alt=图3.4-1 src="http://www-128.ibm.com/developerworks/cn/java/l-javagui/6.gif" width=495> <BR><BR><A name=N101C1><B>（图3.4-2）</B></A><BR><IMG height=310 alt=图3.4-2 src="http://www-128.ibm.com/developerworks/cn/java/l-javagui/7.gif" width=495> <BR><BR><A name=N101D0><B>（图3.4-3）</B></A><BR><IMG height=310 alt=图3.4-3 src="http://www-128.ibm.com/developerworks/cn/java/l-javagui/8.gif" width=496> <BR>
<P>在这个具体应用中，底部的JButton组是确定的，但JTabbedPane的每一个选项都不同，如何实现呢？</P>
<P><B>3.4.2解决方案</B> </P>
<P>首先我们可以采用BorderLayout确定主题对话框的布局方式，实现方法如下：</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console">JTabbedPane dbTabPane = new JTabbedPane();
…… //下面需要用到的JButton等组件变量定义（或声明）
private void initLayout()
{
initDBTabPane();//初始化JTabbedPane:DBTabPane组件
    this.getContentPane().add(BorderLayout.CENTER, dbTabPane);
	//将JTabbedPane组件：dbTabPane布局于JDialog对话框的中间
        initButtonPanel();//初始化JPanel:ButtonPanel组件
        this.getContentPane().add(BorderLayout.SOUTH, buttonPanel);
	//将JPanel组件：buttonPanel布局于JDialog对话框的底部（南面）
    }

private void initDBTabPane()
{
        JPanel loginPanel = new JPanel(new GridLayout(10, 1));
//为保证两个JCheckBox组件位于顶端，设置为共10行，每行一个组件的布局，但只
//放置界面要求的两个组件，这样就保持了界面的美观，否则如定义为
//Gridlayout(2,1)则会使两个组件居中，而且中间会隔开较长的距离。
pwdBox.setMnemonic('P');
        loginPanel.add(pwdBox);
        dspBox.setMnemonic('D');
        loginPanel.add(dspBox);
        dbTabPane.add("Login", loginPanel); //设置"Login"JPanel（图3.4-1）的布局
        needRadio.setMnemonic('N');
        allRadio.setMnemonic('A');
        cacheRadio.setMnemonic('U');
        radioPanel.setBorder(new TitledBorder("Load Option"));//加上边界标题
        radioPanel.add(needRadio);
        radioPanel.add(allRadio);
        radioPanel.add(cacheRadio);
//以上为加入需要的JRadioButton组件到指定的JPanel: radioPanel
        queryPanel.add(radioPanel);//加入含JRadioButton组的JPanel到queryPanel
        reqBox.setMnemonic('R');
        boxPanel.add(reqBox);
        saveBox.setMnemonic('S');
        boxPanel.add(saveBox);
        autoBox.setMnemonic('t');
        boxPanel.add(autoBox);
//以上为加入需要的JCheckBox组到指定的JPanel：boxPanel
        queryPanel.add(boxPanel); //加入含JCheckBox组的JPanel到queryPanel
        dbTabPane.add("Query", queryPanel);//设置"Query"JPanel（图3.4-2）的布局
        initDrvPanel();
    }

/**设置"Drivers"JPanel（图3.4-3）的布局*/
private void initDrvPanel()
{
        gridBag.fill = GridBagConstraints.HORIZONTAL;
        gridBag.weightx = 100;
        gridBag.weighty = 0;
        tipLabel.setForeground(Color.black);
        this.add(drvPanel, tipLabel, gridBag, 0, 0, 4, 1);
        urlLabel.setForeground(Color.black);
        this.add(drvPanel, urlLabel, gridBag, 0, 5, 4, 1);
        urlField.setEditable(false);
        this.add(drvPanel, urlField, gridBag, 0, 6, 4, 1);
        gridBag.weightx = 0;
        gridBag.weighty = 0;
        addButton.setMnemonic('A');
        this.add(drvPanel, addButton, gridBag, 3, 1, 1, 1);
        editButton.setMnemonic('E');
        this.add(drvPanel, editButton, gridBag, 3, 2, 1, 1);
        removeButton.setMnemonic('R');
        this.add(drvPanel, removeButton, gridBag, 3, 3, 1, 1);
        gridBag.fill = GridBagConstraints.BOTH;
        gridBag.weightx = 100;
        gridBag.weighty = 100;
       	//设置JTable组件：drvTable的从0到7行第0列的值
for (int i = 0; i &lt; 8; i++)
       		drvTable.setValueAt(drvStrs[i],i,0); 
//设置JTable的列头
drvTable.getColumn(drvTable.getColumnName(0)).setHeaderValue("All Drivers");
        drvTable.setShowGrid(false);//设置不显示网格线
        this.add(drvPanel, drvScroll, gridBag, 0, 1, 3, 4);
        dbTabPane.add("Drivers", drvPanel);
   }

/**初始化底部JButton组的布局*/
private void initButtonPanel()
    {
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
//从右边开始进行FlowLayout布局
okButton.setMnemonic('O');
        buttonPanel.add(okButton);
        cancelButton.setMnemonic('C');
        buttonPanel.add(cancelButton);
        helpButton.setMnemonic('H');
        buttonPanel.add(helpButton);
    }

/**给指定的容器cn在指定的（x,y）位置放置指定大小（宽度=w,高度=h）的组件c*/
private void add(Container cn, Component c, GridBagConstraints gbc, int x, int y, int w, int h)
{
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = w;
        gbc.gridheight = h;
        cn.add(c, gbc);
    }
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><FONT face="Lucida Console"><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></FONT></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><FONT face="Lucida Console"><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></FONT></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/l-javagui/index.html#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=4><SPAN class=atitle><FONT face=Arial size=4>结束语</FONT></SPAN></A></P>
<P><FONT face=Arial size=4></FONT>
<P>以上是本人在两年多J2EE应用开发中，总结的关于用Java进行GUI设计的一些经验，希望能给曾经象我一样迷惘，但依旧对Java一往情深，至今仍在摸索探求Java GUI设计捷径的朋友一些启示。更希望借此机会抛砖引玉，与更多的朋友进行交流与探讨。其实，在Java中所有的布局管理器都要实现一个接口，即LayoutManager Inerface或者是它的一个子接口LayoutManager2 Interface，后者用于更复杂的布局管理。如果在实际应用中，觉得Java API提供的这些布局管理器仍不够用，你完全可以自己来实现其中某一个接口的方法，从而为你自己的具体GUI应用设计提供更好的布局管理。</P></B></B></B></B></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/fortune/aggbug/32312.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-24 17:26 <a href="http://www.blogjava.net/fortune/archive/2006/02/24/32312.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Resource的Disposal </title><link>http://www.blogjava.net/fortune/archive/2006/02/23/32108.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Thu, 23 Feb 2006 07:40:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/23/32108.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/32108.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/23/32108.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/32108.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/32108.html</trackback:ping><description><![CDATA[<FONT size=2><BR>1、如果你用构造函数创建了widget或者graphic对象，当你不需要时你必须手动地dispose掉它;<BR>2、如果你不是使用构造函数得到这个widget或者graphic对象，由于不是你allocate的，你不需要手动来dispose掉它;<BR>3、如果你传递一个widget或者graphic对象的reference给另一个对象，那么你必须小心，不要在它仍在被使用中就dispose掉它;<BR>4、当你close掉一个shell，那么这个shell及其子widget会被递归dispose掉的，虽然你不需再dispose掉那些widget，但是你必须free掉与这些widget相关的图像资源;<BR>5、如果在一个widget的生命期中创建了graphic对象，可以通过注册一个dispose listener来free这个graphic对象，不过数据对象如Rectangle和Point没有使用操作系统资源，不用手动dispose(它们也没有dispose方法). </FONT><BR><img src ="http://www.blogjava.net/fortune/aggbug/32108.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-23 15:40 <a href="http://www.blogjava.net/fortune/archive/2006/02/23/32108.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA开发者应该去的20几个英文网站 （转）</title><link>http://www.blogjava.net/fortune/archive/2006/02/23/32062.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Thu, 23 Feb 2006 01:51:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/23/32062.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/32062.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/23/32062.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/32062.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/32062.html</trackback:ping><description><![CDATA[<P>[http://www.javaalmanac.com] - Java开发者年鉴一书的在线版本. 要想快速查到某种Java技巧的用法及示例代码, 这是一个不错的去处. <BR>[http://www.onjava.com] - O'Reilly的Java网站. 每周都有新文章. <BR>[http://java.sun.com] - 官方的Java开发者网站 - 每周都有新文章发表. <BR>[http://www.developer.com/java] - 由Gamelan.com 维护的Java技术文章网站. <BR>[http://www.java.net] - Sun公司维护的一个Java社区网站. <BR>[http://www.builder.com] - Cnet的Builder.com网站 - 所有的技术文章, 以Java为主. <BR>[http://www.ibm.com/developerworks/java] - IBM的Developerworks技术网站; 这是其中的Java技术主页. <BR>[http://www.javaworld.com] - 最早的一个Java站点. 每周更新Java技术文章. <BR>[http://www.devx.com/java] - DevX维护的一个Java技术文章网站. <BR>[http://www.fawcette.com/javapro] - JavaPro在线杂志网站. <BR>[http://www.sys-con.com/java] - Java Developers Journal的在线杂志网站. <BR>[http://www.javadesktop.org] - 位于Java.net的一个Java桌面技术社区网站. <BR>[http://www.theserverside.com] - 这是一个讨论所有Java服务器端技术的网站. <BR>[http://www.jars.com] - 提供Java评论服务. 包括各种framework和应用程序. <BR>[http://www.jguru.com] - 一个非常棒的采用Q&amp;A形式的Java技术资源社区. <BR>[http://www.javaranch.com] - 一个论坛，得到Java问题答案的地方，初学者的好去处。 <BR>[http://www.ibiblio.org/javafaq/javafaq.html] - comp.lang.java的FAQ站点 - 收集了来自comp.lang.java新闻组的问题和答案的分类目录. <BR>http://java.sun.com/docs/books/tutorial/] - 来自SUN公司的官方Java指南 - 对于了解几乎所有的java技术特性非常有帮助. <BR>http://www.javablogs.com] - 互联网上最活跃的一个Java Blog网站. <BR>http://java.about.com/] - 来自About.com的Java新闻和技术文章网站.<BR><BR>另外：<A href="http://www.theserverside.com/">www.theserverside.com</A></P>
<P><A href="http://www.apache.org/">www.apache.org</A></P>
<P>http://sourceforge.net/ </P><img src ="http://www.blogjava.net/fortune/aggbug/32062.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-23 09:51 <a href="http://www.blogjava.net/fortune/archive/2006/02/23/32062.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我忍！</title><link>http://www.blogjava.net/fortune/archive/2006/02/22/31956.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Wed, 22 Feb 2006 05:47:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/22/31956.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/31956.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/22/31956.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/31956.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/31956.html</trackback:ping><description><![CDATA[<P>近一个月没玩魔兽世界了，时不时地还会想起美丽的艾泽拉斯和我可爱的部落兄弟们.........又开了2个FB.........<BR>我忍我忍，不能在玩了太花时间啊！！<BR><BR>哎，魔兽世界真的是一个非常好的游戏！！！！是非常非常非常好！！！！！！！</P><img src ="http://www.blogjava.net/fortune/aggbug/31956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-22 13:47 <a href="http://www.blogjava.net/fortune/archive/2006/02/22/31956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个小SWT程序</title><link>http://www.blogjava.net/fortune/archive/2006/02/22/31952.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Wed, 22 Feb 2006 05:13:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/22/31952.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/31952.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/22/31952.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/31952.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/31952.html</trackback:ping><description><![CDATA[<P>以下程序运行后产生一个红色的小球在窗口来回弹，如在小球结束运动之前关闭窗口（shell）则产生：<BR><BR>Exception in thread "main" org.eclipse.swt.SWTException: Widget is disposed<BR>&nbsp;at org.eclipse.swt.SWT.error(SWT.java:2942)<BR>&nbsp;at org.eclipse.swt.SWT.error(SWT.java:2865)<BR>&nbsp;at org.eclipse.swt.SWT.error(SWT.java:2836)<BR>&nbsp;at org.eclipse.swt.widgets.Widget.error(Widget.java:395)<BR>&nbsp;at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:297)<BR>&nbsp;at org.eclipse.swt.widgets.Control.internal_new_GC(Control.java:1104)<BR>&nbsp;at org.eclipse.swt.graphics.GC.&lt;init&gt;(GC.java:132)<BR>&nbsp;at org.eclipse.swt.graphics.GC.&lt;init&gt;(GC.java:99)<BR>&nbsp;at ballThread.clean(BounceBall.java:115)<BR>&nbsp;at ballThread$2.run(BounceBall.java:135)<BR>&nbsp;at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)<BR>&nbsp;at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:123)<BR>&nbsp;at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3057)<BR>&nbsp;at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2716)<BR>&nbsp;at org.eclipse.swt.widgets.Display.release(Display.java:2765)<BR>&nbsp;at org.eclipse.swt.graphics.Device.dispose(Device.java:261)<BR>&nbsp;at BounceBall.main(BounceBall.java:58)<BR><BR>原因应该是仍然在使用对象时将该对象清除了导致异常的产生，应该怎样改动程序呢？？思考中.........<BR><BR><BR>import org.eclipse.swt.graphics.GC;<BR>import org.eclipse.swt.graphics.Point;<BR>import org.eclipse.swt.graphics.Rectangle;<BR>import org.eclipse.swt.widgets.Shell;<BR>import org.eclipse.swt.widgets.Display;<BR>import org.eclipse.swt.widgets.Canvas;<BR>import org.eclipse.swt.SWT;<BR>import org.eclipse.swt.widgets.Button;<BR>import org.eclipse.swt.graphics.Color;</P>
<P>public class BounceBall {</P>
<P>&nbsp;private Shell sShell = null;&nbsp; //&nbsp; @jve:decl-index=0:visual-constraint="10,10"<BR>&nbsp;private Canvas canvas = null;<BR>&nbsp;private Button startButton = null;<BR>&nbsp;ballThread bt = null;<BR>&nbsp;Display display = null;</P>
<P>&nbsp;public BounceBall() {<BR>&nbsp;&nbsp;super();<BR>&nbsp;&nbsp;// TODO Auto-generated constructor stub<BR>//&nbsp;&nbsp;bt = new ballThread(canvas);<BR>&nbsp;&nbsp;display = Display.getDefault();<BR>&nbsp;}</P>
<P>&nbsp;/**<BR>&nbsp; * This method initializes canvas&nbsp;<BR>&nbsp; *<BR>&nbsp; */<BR>&nbsp;private void createCanvas() {<BR>&nbsp;&nbsp;canvas = new Canvas(sShell, SWT.NONE);<BR>&nbsp;&nbsp;canvas.setBackground(new Color(Display.getCurrent(), 0, 0, 255));<BR>&nbsp;&nbsp;canvas.setBounds(new org.eclipse.swt.graphics.Rectangle(26,14,527,242));<BR>&nbsp;}</P>
<P>&nbsp;/**<BR>&nbsp; * @param args<BR>&nbsp; */<BR>&nbsp;public static void main(String[] args) {<BR>&nbsp;&nbsp;// TODO Auto-generated method stub<BR>&nbsp;&nbsp;/* Before this is run, be sure to set up the launch configuration (Arguments-&gt;VM Arguments)<BR>&nbsp;&nbsp; * for the correct SWT library path in order to run with the SWT dlls. <BR>&nbsp;&nbsp; * The dlls are located in the SWT plugin jar.&nbsp; <BR>&nbsp;&nbsp; * For example, on Windows the Eclipse SWT 3.1 plugin jar is:<BR>&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; installation_directory\plugins\org.eclipse.swt.win32_3.1.0.jar<BR>&nbsp;&nbsp; */<BR>//&nbsp;&nbsp;Display display = Display.getDefault();<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;BounceBall thisClass = new BounceBall();<BR>&nbsp;&nbsp;thisClass.createSShell();<BR>&nbsp;&nbsp;thisClass.sShell.open();</P>
<P>&nbsp;&nbsp;while (!thisClass.sShell.isDisposed()) {<BR>&nbsp;&nbsp;&nbsp;if (!thisClass.display.readAndDispatch())<BR>&nbsp;&nbsp;&nbsp;&nbsp;thisClass.display.sleep();<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;thisClass.display.dispose();<BR>&nbsp;}</P>
<P>&nbsp;/**<BR>&nbsp; * This method initializes sShell<BR>&nbsp; */<BR>&nbsp;private void createSShell() {<BR>&nbsp;&nbsp;sShell = new Shell();<BR>&nbsp;&nbsp;sShell.setText("Shell");<BR>&nbsp;&nbsp;createCanvas();<BR>&nbsp;&nbsp;sShell.setSize(new org.eclipse.swt.graphics.Point(588,367));<BR>&nbsp;&nbsp;startButton = new Button(sShell, SWT.NONE);<BR>&nbsp;&nbsp;startButton.setBounds(new org.eclipse.swt.graphics.Rectangle(87,284,76,33));<BR>&nbsp;&nbsp;startButton.setText("Start");<BR>&nbsp;&nbsp;startButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {<BR>&nbsp;&nbsp;&nbsp;public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;//System.out.println("widgetSelected()"); // TODO Auto-generated Event stub widgetSelected()<BR>&nbsp;&nbsp;&nbsp;&nbsp;new ballThread(40,40,canvas).start();<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;});<BR>&nbsp;}</P>
<P>}</P>
<P><BR>&nbsp;class ballThread extends Thread {</P>
<P>&nbsp;&nbsp;int x, y, xsize, ysize, addx, addy;<BR>&nbsp;&nbsp;Rectangle rc = null;<BR>&nbsp;&nbsp;GC gc = null;<BR>&nbsp;&nbsp;Canvas c = null;<BR>&nbsp;&nbsp;Color red = Display.getCurrent().getSystemColor(SWT.COLOR_RED);</P>
<P>&nbsp;&nbsp;public ballThread(int x,int y,Canvas ca) {<BR>&nbsp;&nbsp;&nbsp;c = ca;<BR>&nbsp;&nbsp;&nbsp;this.x = x;<BR>&nbsp;&nbsp;&nbsp;this.y = y;<BR>&nbsp;&nbsp;&nbsp;xsize = 10;<BR>&nbsp;&nbsp;&nbsp;ysize = 10;<BR>&nbsp;&nbsp;&nbsp;addx = 1;<BR>&nbsp;&nbsp;&nbsp;addy = 2;<BR>&nbsp;&nbsp;&nbsp;rc = c.getBounds();<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;public void draw(int x, int y, int xsize, int ysize) {<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;gc = new GC(c);<BR>&nbsp;&nbsp;&nbsp;gc.drawOval(x, y, xsize, ysize);<BR>&nbsp;&nbsp;&nbsp;gc.setBackground(red);<BR>&nbsp;&nbsp;&nbsp;gc.fillOval(x, y, xsize, ysize);<BR>&nbsp;&nbsp;&nbsp;gc.dispose();<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;public void clean() {<BR>&nbsp;&nbsp;&nbsp;gc = new GC(c);<BR>&nbsp;&nbsp;&nbsp;// Rectangle rt = canvas.getBounds();<BR>&nbsp;&nbsp;&nbsp;gc.drawRectangle(rc.x - 100, rc.y - 100, rc.width + 100,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rc.height + 100);<BR>&nbsp;&nbsp;&nbsp;gc.fillRectangle(rc.x - 100, rc.y - 100, rc.width + 100,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rc.height + 100);<BR>&nbsp;&nbsp;&nbsp;gc.dispose();<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;public void run() {<BR>&nbsp;&nbsp;&nbsp;for (int i = 1; i &lt; 1500; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;try{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Display.getDefault().asyncExec(new Thread () {<BR>&nbsp;&nbsp;&nbsp;&nbsp;public void run(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;draw(x, y, xsize, ysize);}});<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(10);<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Display.getDefault().asyncExec(new Thread () {<BR>&nbsp;&nbsp;&nbsp;&nbsp;public void run(){&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;clean();}});<BR>&nbsp;&nbsp;&nbsp;&nbsp;} catch (InterruptedException e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// TODO Auto-generated catch block<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;if (rc.contains(x, y)) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x += addx;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y += addy;<BR>&nbsp;&nbsp;&nbsp;&nbsp;} else {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (x &gt;= rc.width || x &lt;= 26) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addx = -addx;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x += addx;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y += addy;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else if (y &gt;= rc.height || y &lt;= 14) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addy = -addy;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x += addx;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y += addy;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;}<BR><BR>想到一个办法能够去除那些exceptions，就是在display.dispose()前加一句Thread.currentThread().stop();强制终止线程，不过这个办法肯定是最垃圾的办法.......<BR></P><img src ="http://www.blogjava.net/fortune/aggbug/31952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-22 13:13 <a href="http://www.blogjava.net/fortune/archive/2006/02/22/31952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT</title><link>http://www.blogjava.net/fortune/archive/2006/02/22/31925.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Wed, 22 Feb 2006 02:59:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/22/31925.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/31925.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/22/31925.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/31925.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/31925.html</trackback:ping><description><![CDATA[SWT应用程序结构：<BR>1.创建显示，它表示SWT会话<BR>2.创建一个或多个Shell，它表示应用程序的主窗口<BR>3.创建Shell内部所需的任何其它小部件<BR>4.初始化小部件的大小和必需的状态，为需要监听的小部件注册监听器<BR>5.打开Shell窗口<BR>6.运行事件调度循环直到发生退出情况为止<BR>7.清除显示<BR><BR>SWT提供的组件：<BR>1.显示（Display）<BR>&nbsp;管理平台事件循环，控制用户界面线程和其它线程之间的通信，除非是多线程否则不需要太多考虑display<BR>2.shell<BR>OS平台窗口管理器管理的一个“窗口”，辅助shell是作为另一个shell的子代创建的通常用作对话框或其它的瞬时窗口<BR>3.输入组件<BR>主要用来管理平台事件循环和控制用户界面线程和其它线程之间的通信，处理字符串的输入与输出，以及对应事件的发生。<BR>Button&nbsp;&nbsp; 有普通按钮push，check按钮，radio按钮，toggle按钮<BR>Text&nbsp; 可以输入文字 可指定单行，多行，和滚动行<BR>Combo <BR>Slider<BR>4.显示组件（用于显示文字，图片等）<BR>Label&nbsp;&nbsp;&nbsp;&nbsp;显示文字或图片<BR>Canvas<BR>List&nbsp;&nbsp;&nbsp;能够进行一览显示，可以从一览中选定一行或几行<BR>Table&nbsp;&nbsp;&nbsp;显示二维表格，可以在列头指定列名<BR>Tree<BR>ProgressBar&nbsp;&nbsp;&nbsp;显示进度条<BR>5.Menu/工具栏组件<BR>在窗口上配置Menu和工具栏<BR>Menu<BR>ToolBar&nbsp;&nbsp;&nbsp;显示工具栏<BR>CoolBar&nbsp;&nbsp;&nbsp;显示可以使用鼠标拖动的工具栏<BR>6.容器组件<BR>可以包含其它的Widget<BR>Composite<BR>Group<BR>TabFolder&nbsp;&nbsp;&nbsp;可以通过Tab换页<BR>SashForm<BR>7.对话框组件<BR>MessageBox&nbsp;&nbsp;&nbsp;显示message<BR>FileDialog&nbsp;&nbsp;&nbsp;指定文件<BR>DirectoryDialog&nbsp;&nbsp;&nbsp;&nbsp;指定路径<BR>ColorDialog&nbsp;&nbsp;&nbsp;指定颜色<BR>FontDialog&nbsp;&nbsp;&nbsp;指定字体<BR>PrintDialog&nbsp;&nbsp;&nbsp;指定打印机<BR>8.布局管理组件<BR>FillLayout&nbsp;&nbsp;&nbsp;填补空隙，水平或垂直配置<BR>FormLayout&nbsp;&nbsp;&nbsp;参照其它窗口进行布局<BR>RowLayout&nbsp;&nbsp;&nbsp;&nbsp;水平或垂直配置，可指定margin或widget之间的距离<BR>GridLayout<BR>StackLayout<BR><BR>布局<BR>1.FillLayout 填充布局<BR>是最简单的布局，将小部件布局在单行或单列中，强制他们全部使用相同的大小<BR>可以使用它对任务栏或工具栏中的按钮进行布局<BR>2.RowLayout 行布局<BR>（写不动了，休息先）<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><img src ="http://www.blogjava.net/fortune/aggbug/31925.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-22 10:59 <a href="http://www.blogjava.net/fortune/archive/2006/02/22/31925.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT多线程（1）</title><link>http://www.blogjava.net/fortune/archive/2006/02/22/31899.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Wed, 22 Feb 2006 01:10:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/22/31899.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/31899.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/22/31899.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/31899.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/31899.html</trackback:ping><description><![CDATA[<BR>在SWT中，通常存在一个被称为"用户线程"的唯一线程，只有在这个线程中才能调用对构件或某些图形API的访问操作。如果在非用户线程中程序直接调用这些访问操作，那么SWTExcepiton异常会被抛出（if (display.thread != Thread.currentThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);）每一个在非用户线程中出现的widget都要通过检验看display.thread 是否等于Thread.currentThread()如果不相等就要抛出非法访问线程异常。但是SWT也在*.widget.Display类中提供了两个方法可以间接的在非用户线程的进行图形构件的访问操作，这是通过的syncExec(Runnable)和asyncExec(Runnable)这两个方法去实现的。<BR><BR><FONT size=1>&nbsp; </FONT><SPAN style="FONT-FAMILY: 宋体">对于</SPAN><SPAN lang=EN-US>Display</SPAN><SPAN style="FONT-FAMILY: 宋体">，在同一个线程里，不能申明</SPAN><SPAN lang=EN-US>2</SPAN><SPAN style="FONT-FAMILY: 宋体">个</SPAN><SPAN lang=EN-US>Display</SPAN><SPAN style="FONT-FAMILY: 宋体">实例。同样的，一个</SPAN><SPAN lang=EN-US>Display</SPAN><SPAN style="FONT-FAMILY: 宋体">实例也不能跨线程使用。也就是说，如果你要在另外一个线程中显示一个窗体，（比如你要在任务完成后弹出一个对话框），你必须另外创建一个</SPAN><SPAN lang=EN-US>Display</SPAN><SPAN style="FONT-FAMILY: 宋体">实例。不然会导致异常。)</SPAN> <img src ="http://www.blogjava.net/fortune/aggbug/31899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-22 09:10 <a href="http://www.blogjava.net/fortune/archive/2006/02/22/31899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>努力努力</title><link>http://www.blogjava.net/fortune/archive/2006/02/21/31854.html</link><dc:creator>fortune</dc:creator><author>fortune</author><pubDate>Tue, 21 Feb 2006 11:47:00 GMT</pubDate><guid>http://www.blogjava.net/fortune/archive/2006/02/21/31854.html</guid><wfw:comment>http://www.blogjava.net/fortune/comments/31854.html</wfw:comment><comments>http://www.blogjava.net/fortune/archive/2006/02/21/31854.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fortune/comments/commentRss/31854.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fortune/services/trackbacks/31854.html</trackback:ping><description><![CDATA[今天老板找谈话了，终于加工资了......不过老板没说+多少我也没敢问（汗啊。。。还没做项目没为公司做什么贡献实在是不好意思啊.....）<BR>要努力努力努力学习阿！！！！！<BR>周末要去办护照了，大概过段时间要去迪拜了，第一次出国不知道外国的月亮是长啥样的~~~<BR>努力努力努力<img src ="http://www.blogjava.net/fortune/aggbug/31854.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fortune/" target="_blank">fortune</a> 2006-02-21 19:47 <a href="http://www.blogjava.net/fortune/archive/2006/02/21/31854.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>