﻿<?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-sean2fly</title><link>http://www.blogjava.net/sean2fly/</link><description /><language>zh-cn</language><lastBuildDate>Mon, 15 Jun 2026 22:26:03 GMT</lastBuildDate><pubDate>Mon, 15 Jun 2026 22:26:03 GMT</pubDate><ttl>60</ttl><item><title>为Text editor中添加Content Assistant</title><link>http://www.blogjava.net/sean2fly/articles/100942.html</link><dc:creator>巴山鹰</dc:creator><author>巴山鹰</author><pubDate>Tue, 27 Feb 2007 08:11:00 GMT</pubDate><guid>http://www.blogjava.net/sean2fly/articles/100942.html</guid><wfw:comment>http://www.blogjava.net/sean2fly/comments/100942.html</wfw:comment><comments>http://www.blogjava.net/sean2fly/articles/100942.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean2fly/comments/commentRss/100942.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean2fly/services/trackbacks/100942.html</trackback:ping><description><![CDATA[<p>转贴:<br />  <a href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html">http://www.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html</a><br /></p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr valign="top">
								<td width="100%">
										<h1>为 SWT 应用程序配备内容助理</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.ibm.com/developerworks/cn/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.ibm.com/developerworks/secure/email-it.jsp">
																														<input type="hidden" value="对于 Eclipse Java 编辑器的用户，内容助理是一个众所周知的特性。按一下 Ctrl + 空格键，带有一组完成建议的窗口就会弹出来。选择某个特定的建议将会打开另一个窗口，其中显示了插入选定建议之后的预览效果。可以使用回车键来接受某个建议，或双击该建议以将它插入当前文档。本文将展示如何容易地向基于 SWT 的应用程序（不管是独立应用程序还是 Eclipse 工作台的插件）添加这个特性。" name="body" />
																														<input type="hidden" value="为 SWT 应用程序配备内容助理" name="subject" />
																														<input type="hidden" value="cn" name="lang" />
																														<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>
																														<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">
																																				<img height="16" alt="将此页作为电子邮件发送" src="http://www.ibm.com/i/v14/icons/em.gif" width="16" vspace="3" />
																																		</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>
																														</tbody>
																												</form>
																										</table>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																</td>
														</tr>
												</tbody>
										</table>
										<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
										<!-- 03/20/06 updated by gretchen -->
										<br />
										<table cellspacing="0" cellpadding="0" width="150" border="0">
												<tbody>
														<tr>
																<td class="v14-header-2-small">拓展 Tomcat 应用</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/fw_bold.gif" width="16" vspace="3" border="0" />
																								</td>
																								<td width="125">
																										<p>
																												<a class="smallplainlink" href="http://www.ibm.com/developerworks/cn/kickstart/webserver.html?S_TACT=105AGX52&amp;S_CMP=simpleart">
																														<font color="#5c81a7" size="2">下载 IBM 开源 J2EE 应用服务器 WAS CE 新版本 V1.1</font>
																												</a>
																										</p>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																</td>
														</tr>
												</tbody>
										</table>
										<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<p>级别: 初级</p>
		<p>
				<a href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html#author">
						<font color="#996699">Berthold Daum</font>
				</a> (<a href="mailto:berthold.daum@bdaum.de?subject=为 SWT 应用程序配备内容助理&amp;cc="><font color="#5c81a7">berthold.daum@bdaum.de</font></a>), 顾问, bdaum industrial communications<br /></p>
		<p>2004 年 1 月 10 日</p>
		<blockquote>对于 Eclipse Java 编辑器的用户，内容助理是一个众所周知的特性。按一下 Ctrl + 空格键，带有一组完成建议的窗口就会弹出来。选择某个特定的建议将会打开另一个窗口，其中显示了插入选定建议之后的预览效果。可以使用回车键来接受某个建议，或双击该建议以将它插入当前文档。本文将展示如何容易地向基于 SWT 的应用程序（不管是独立应用程序还是 Eclipse 工作台的插件）添加这个特性。</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>
				<a name="IDAPDQ1E">创建 HTML 编辑器 <br />内容助理的概念与 JFace 文本查看器（即 <code>org.eclipse.jface.text.source.SourceViewer</code> 类）的特定实现有关。整个 Eclipse 工作台中都使用了这个类的实例来实现各种编辑器。然而， <code>SourceViewers</code> 并不仅限用于 Eclipse 工作台，而是还使用在基于 SWT 和 JFace JAR 建立的任何应用程序中。本文将在 Eclipse 编辑器插件的环境中展示内容助理的实现，并给出关于如何通过“裸” <code>SourceViewers</code> 使用内容助理的技巧。 </a>
		</p>
		<p>下面让我们实现一个简单的 HTML 编辑器。内容助理对 HTML 编辑可能非常有用。例如，内容助理能够生成诸如表或链接等典型的 HTML 结构，或者能够将选中的文本区域包装到样式标签中。</p>
		<p>为节省时间，我们将使用 <b>New Plug-in Project</b>向导之一来实现这个编辑器，以生成适当的编辑器插件。由于所生成的这个编辑器是 XML 编辑器，而 HTML 是基于 XML 的标记语言，我们只需进行一些次要的修改，将所生成的编辑器转换为一个 HTML 编辑器。下面就让我们开始吧。 </p>
		<p>在调用 <b>New</b>向导之后，选择 Plug-in Development 和 Plug-in Project。在随后的屏幕上，输入项目名称“Sample HTML Editor”。在接下来的屏幕上，定义适当的插件 ID，比如“com.bdaum.SampleHTMLEditor”。下面的屏幕允许您选择适当的代码生成向导。请选择 <b>Plug-in with an editor</b>，如图 1 所示。 </p>
		<p>
				<a name="IDAQEQ1E">
						<b>图 1. 带编辑器的插件</b>
				</a>
				<br />
				<img height="500" alt="带编辑器的插件" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecca/figure1.jpg" width="500" />
		</p>
		<p>在下一个屏幕上，修改建议的插件名称（如果想这样做的话）和插件类名称，并指定一个提供者名称。其他内容保留不变。</p>
		<p>继续到下一个屏幕，把建议的名称 <b>Editor Class Name</b>修改为“HTMLEditor”，把 <b>Editor Name</b>修改为“Sample HTML Editor”，把 <b>File Extension</b>修改为“html, htm”，如图 2 所示。后一个条目将把新的编辑器与具有 .html 或 .htm 文件扩展名的所有文件关联起来。 </p>
		<p>
				<a name="IDAGFQ1E">
						<b>图 2. 编辑器选项</b>
				</a>
				<br />
				<img height="299" alt="编辑器选项" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecca/figure2a.jpg" width="500" />
		</p>
		<p>单击 <b>Finish</b>按钮来生成新的编辑器。现在通过 <b>Run &gt; Run as ... &gt; Run-time workbench</b>启动一个新的工作台。在创建具有 .html 或 .htm 文件扩展名的新文件（或导入这样的文件）之后，再使用新的编辑器来打开它。 </p>
		<p>
				<a name="N100AE">
						<span class="atitle">添加内容助理</span>
				</a>
		</p>
		<p>正如您很快将会发现的，这个编辑器没有具备内容助理特性；按 Ctrl + 空格键没有任何作用。 <code>SourceViewers</code> 默认情况下没有配备内容助理。我们需要相应地配置这个 HTML 编辑器中使用的 <code>SourceViewer</code> 。 </p>
		<p>HTML 编辑器的 <code>SourceViewer</code> 的配置是通过所生成的类 <code>XMLConfiguration</code> 来表示的，这个类是 <code>SourceViewerConfiguration</code> 的子类（如果您愿意，可以将这个类重命名为 <code>HTMLConfiguration</code> ，不过这并不是必需的）。为了向源代码查看器添加一个内容助理，我们需要重写 <code>SourceViewerConfiguration</code> 方法 <code>getContentAssistant()</code> 。这最适合通过 Java 编辑器的上下文功能 <b>Source &gt; Override/Implement Methods...</b>来完成，这个功能会为该方法创建一个存根（stub）。现在我们需要实现这个方法，并返回一个 <code>IContentAssistant</code> 类型的适当实例。 </p>
		<p>内容助理由一个或多个内容处理器组成，我们想要支持的每种内容类型分别有一个内容处理器。源代码查看器处理过的文档可以划分为具有不同内容类型的多个分区。这样的分区将由分区扫描程序确定，事实上，我们在包 <code>com.bdaum.HTMLEditor.editors </code>中发现了一个类 <code>XMLPartitionScanner</code> 。这个类为我们的文档类型 <code>XML_DEFAULT</code> 、 <code>XML_COMMENT</code> 和 <code>XML_TAG</code> 定义了三种不同的内容类型。此外，文档也可能包含 <code>IDocument.DEFAULT_CONTENT_TYPE</code> 类型的分区。 </p>
		<p>在新方法 <code>getContentAssistant()</code> 中，我们首先创建了 <code>IContentAssistant</code> 的默认实现的一个新实例，并给它配备了针对 <code>XML_DEFAULT</code> 、 <code>XML_TAG</code> 和 <code>IDocument.DEFAULT_CONTENT_TYPE</code> 内容类型的完全一样的内容助理处理器。由于不打算在 HTML 注释内提供辅助，因此我们没有为内容类型 <code>XML_COMMENT</code> 创建内容助理处理器。清单 1 显示了该代码。 </p>
		<br />
		<br />
		<a name="N10117">
				<b>清单 1. getContentAssistant</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">public IContentAssistant getContentAssistant(SourceViewer sourceViewer) {
   // Create content assistant
   ContentAssistant assistant = new ContentAssistant();
   
   // Create content assistant processor
   IContentAssistProcessor processor = new HtmlContentAssistProcessor();
   
   // Set this processor for each supported content type
   assistant.setContentAssistProcessor(processor, XMLPartitionScanner.XML_TAG);
   assistant.setContentAssistProcessor(processor, XMLPartitionScanner.XML_DEFAULT);
   assistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
         
   // Return the content assistant   
   return assistant;
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a name="IDAKRU2E">实现内容助理处理器 <br />类 <code>HtmlContentAssistProcessor</code> 还不存在。现在通过单击 <b>QuickFix</b>灯泡状图标来创建它。在这个新类中，我们只需完成从接口 <code>IContentAssistProcessor</code> 继承来的预先生成的方法。我们最感兴趣的方法是 <code>computeCompletionProposals()</code> 。这个方法返回一个 <code>CompletionProposal</code> 实例数组，我们提供的每个建议分别有一个实例。例如，我们可以提供所有 HTML 标签的集合以供选择。然而，我们希望它更高级一点。当在编辑器中选中一个文本范围时，我们希望提供一个可用于包装这段文本的样式标签集合。否则，我们就提供用于创建新 HTML 结构的标签。图 3 和图 4 显示了我们想要达到的效果。 </a>
		</p>
		<p>
				<a name="IDAGSU2E">
						<b>图 3. structProposal</b>
				</a>
				<br />
				<img height="220" alt="structProposal" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecca/figure3b.jpg" width="404" />
		</p>
		<p>
				<a name="IDATSU2E">
						<b>图 4. styleProposal</b>
				</a>
				<br />
				<img height="174" alt="styleProposal" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecca/figure4.jpg" width="600" />
		</p>
		<p>因此，首先要从编辑器的 <code>SourceViewer</code> 实例中检索当前选中的内容（参见清单 2）。 </p>
		<br />
		<br />
		<a name="N10167">
				<b>清单 2. computeCompletionProposals</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, 
   int documentOffset) {
   // Retrieve current document
   IDocument doc = viewer.getDocument();
   // Retrieve current selection range
   Point selectedRange = viewer.getSelectedRange();
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>然后创建一个 <code>ArrayList 实例</code> ，用于收集所生成的 <code>ICompletionProposal</code> 实例，如清单 3 所示。 </p>
		<br />
		<br />
		<a name="N1017C">
				<b>清单 3. computeCompletionProposals (续)</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">   List propList = new ArrayList();
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>如果选中了文本范围，则检索选中的文本，并计算出样式标签建议，如清单 4 所示。</p>
		<br />
		<br />
		<a name="N10189">
				<b>清单 4. computeCompletionProposals (续)</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">   if (selectedRange.y &gt; 0) {
     try {
       // Retrieve selected text
       String text = doc.get(selectedRange.x, selectedRange.y);
       // Compute completion proposals
       computeStyleProposals(text, selectedRange, propList);
     } catch (BadLocationException e) {
     }
   } else {
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>否则，设法从文档中检索一个限定符，如清单 5 所示。这样的限定符包含部分地进入 HTML 标签的所有字符，用来限制可能的建议集。</p>
		<br />
		<br />
		<a name="N10196">
				<b>清单 5. computeCompletionProposals (续)</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">     // Retrieve qualifier
     String qualifier = getQualifier(doc, documentOffset);
     // Compute completion proposals
     computeStructureProposals(qualifier, documentOffset, propList);
   }
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>最后，将自动完成建议列表转换为一个数组，并将这个数组作为结果返回，如清单 6 所示。</p>
		<br />
		<br />
		<a name="N101A3">
				<b>清单 6. computeCompletionProposals (续)</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">   // Create completion proposal array
   ICompletionProposal[] proposals = new ICompletionProposal[propList.size()];
   // and fill with list elements
   propList.toArray(proposals);
   // Return the proposals
   return proposals; 
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<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.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101AD">
						<span class="atitle">构造限定符</span>
				</a>
		</p>
		<p>现在，让我们看看如何从当前文档检索限定符。我们需要实现方法 <code>getQualifier()</code> ，如清单 7 所示。 </p>
		<br />
		<br />
		<a name="N101BA">
				<b>清单 7. getQualifier</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">private String getQualifier(IDocument doc, int documentOffset) {
   // Use string buffer to collect characters
   StringBuffer buf = new StringBuffer();
   while (true) {
     try {
       // Read character backwards
       char c = doc.getChar(--documentOffset);
       // This was not the start of a tag
       if (c == '&gt;' || Character.isWhitespace(c))
          return "";
       // Collect character
       buf.append(c);
       // Start of tag. Return qualifier
       if (c == '&lt;')
           return buf.reverse().toString();
     } catch (BadLocationException e) {
       // Document start reached, no tag found
       return "";
     }
   }
}
</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.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101C7">
						<span class="atitle">编译自动完成建议</span>
				</a>
		</p>
		<p>现在让我们编译一个建议集合。清单 8 显示了构成这些建议的相关标签集。如果您愿意，还可以添加更多的标签。</p>
		<br />
		<br />
		<a name="N101D0">
				<b>清单 8. 建议集合</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">// Proposal part before cursor
private final static String[] STRUCTTAGS1 =
   new String[] { "&lt;P&gt;", "&lt;A SRC=\"", "&lt;TABLE&gt;",  "&lt;TR&gt;",  "&lt;TD&gt;" };
// Proposal part after cursor
private final static String[] STRUCTTAGS2 =
   new String[] { "",    "\"&gt;&lt;/A&gt;",   "&lt;/TABLE&gt;", "&lt;/TR&gt;", "&lt;/TD&gt;" }
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>可以看到，我们将每个标签建议划分为两个部分：一部分在预计的光标位置之前，一部分在预计的光标位置之后。清单 9 显示了编译这些建议的 <code>computeStructureProposals()</code> 方法。 </p>
		<br />
		<br />
		<a name="N101E1">
				<b>清单 9. computeStructureProposals</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">private void computeStructureProposals(String qualifier, int documentOffset, List propList) { 
   int qlen = qualifier.length();
   // Loop through all proposals
   for (int i = 0; i &lt; STRUCTTAGS1.length; i++) {
      String startTag = STRUCTTAGS1[i];
      // Check if proposal matches qualifier
      if (startTag.startsWith(qualifier)) {
         // Yes -- compute whole proposal text
         String text = startTag + STRUCTTAGS2[i];
         // Derive cursor position
         int cursor = startTag.length();
         // Construct proposal
         CompletionProposal proposal =
            new CompletionProposal(text, documentOffset - qlen, qlen, cursor);
         // and add to result list
         propList.add(proposal);
      }
   }
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>我们遍历标签数组，选择以指定限定符开头的所有标签。对于每个选定的标签，我们创建一个新的 <code>CompletionProposal</code> 实例。对于参数，我们传递完整的标签文本、这段文本应该插入的位置、文档中应该被替换的文本的长度（也就是限定符的长度），以及相对于插入文本开头的预计光标位置。 </p>
		<p>这个方法将为我们提供 WYSIWYG（“所见即所得”）的建议。内容助理的弹出窗口将列出建议，其形式与它们被选定时插入文档的形式精确一致。</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.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101F5">
						<span class="atitle">处理复杂建议</span>
				</a>
		</p>
		<p>前述方法并不适合于我们还必须实现的方法 <code>computeStyleProposals()</code> 。这里我们需要将选中的文本包装到选定的样式标签中，并使用这个新的字符串替换文档里选中的文本。由于这样的替换可能具有任何长度，在内容助理选择窗口中显示它是没有意义的。相反，显示一段简短而有意义的说明性文字，一旦选定明确的样式建议，就显示一个包含完整替换文本的预览窗口，这样会更有意义。我们可以通过使用 <code>CompletionProposal()</code> 构造函数的一种扩展形式来实现这点。 </p>
		<p>清单 10 显示了我们想要支持的样式标签以及关联的说明文字。同样，您可能希望添加更多的标签。</p>
		<br />
		<br />
		<a name="N10209">
				<b>清单 10. 样式标签集合</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">private final static String[] STYLETAGS = new String[] { 
      "b", "i", "code", "strong" 
};
private final static String[] STYLELABELS = new String[] { 
      "bold", "italic", "code", "strong" 
};
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>清单 11 显示了方法 <code>computeStyleProposals()</code> 。 </p>
		<br />
		<br />
		<a name="N1021A">
				<b>清单 11. computeStyleProposals</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">private void computeStyleProposals(String selectedText, Point selectedRange, List propList) {
   // Loop through all styles
   for (int i = 0; i &lt; STYLETAGS.length; i++) {
      String tag = STYLETAGS[i];
      // Compute replacement text
      String replacement = "&lt;" + tag + "&gt;" + selectedText + "&lt;/" + tag + "&gt;";
      // Derive cursor position
      int cursor = tag.length()+2;
      // Compute a suitable context information
      IContextInformation contextInfo = 
         new ContextInformation(null, STYLELABELS[i]+" Style");
      // Construct proposal
      CompletionProposal proposal = new CompletionProposal(replacement, 
         selectedRange.x, selectedRange.y, cursor, null, STYLELABELS[i], 
         contextInfo, replacement);
      // and add to result list
      propList.add(proposal);
   }
}
</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.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10227">
						<span class="atitle">显示额外信息</span>
				</a>
		</p>
		<p>
				<code>CompletionProposal()</code> 构造函数的前四个参数与它们在 <code>computeStructureProposals()</code> 方法中一样具有相同的含义（替换字符串、插入点、被替换的文本的长度，以及相对于插入点的光标位置）。第五个参数（在本例中我们将 <code>null</code> 传递给它）接受一个图像实例。这个图像将显示在弹出窗口中相应条目的左侧。第六个参数接受出现在建议选择窗口中的画面说明文字。第七个参数用于 <code>IContextInformation</code> 实例，我们很快就会讨论它。最后，第八个参数接受附加信息窗口中的文本，当某条建议被选定时，这段文本就应该显示出来。然而，仅只是为这个参数提供一个值，并不足以实际获得这样的信息窗口。我们必须相应地配置内容助理。同样地，这是在类 <code>XMLConfiguration</code> 中完成的。我们只需向方法 <code>getContentAssistant()</code> 添加如清单 12 所示的行。 </p>
		<br />
		<br />
		<a name="N10248">
				<b>清单 12. 向 getContentAssistant 添加行</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这里发生了什么呢？首先，我们从当前源代码查看器配置中获得了一个 <code>IInformationControlCreator</code> 类型的实例。这个实例是一个负责创建类 <code>DefaultInformationControl</code> 的实例的工厂，所创建的实例将负责管理信息窗口。然后我们告诉内容助理关于这个工厂的信息。内容助理最终将在某个自动完成建议被选定时，使用这个工厂来创建一个新的信息控制实例。 </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.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1025D">
						<span class="atitle">格式化信息文本</span>
				</a>
		</p>
		<p>默认情况下，这个信息控制实例将以纯文本的形式提供附加的信息文本。然而，添加一些美妙的文本表示形式是可以做到的。例如，我们可能希望以粗体打印所有标签。为此，我们需要相应地配置 <code>IInformationControlCreator</code> 创建的 <code>DefaultInformationControl</code> 实例。实现这点的惟一办法是使用一个不同的 <code>IInformationControlCreator</code> ，而这可以通过重写 <code>XMLConfiguration </code>方法 <code>getInformationControlCreator()</code> 来完成。 </p>
		<p>这个方法在 <code>SourceViewerConfiguration</code> 类中的标准实现如清单 13 所示。 </p>
		<br />
		<br />
		<a name="N10281">
				<b>清单 13. getInformationControlCreator</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">public IInformationControlCreator getInformationControlCreator
      (ISourceViewer sourceViewer) {
   return new IInformationControlCreator() {
      public IInformationControl createInformationControl(Shell parent) {
         return new DefaultInformationControl(parent);
      }
   };
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>我们通过向 <code>DefaultInformationControl()</code> 构造函数添加一个 <code>DefaultInformationControl.IInformationPresenter</code> 类型的文本展示器（presenter），从而修改 <code>DefaultInformationControl</code> 实例的创建，如清单 14 所示。 </p>
		<br />
		<br />
		<a name="N1029A">
				<b>清单 14. 添加文本展示器</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">   return new DefaultInformationControl(parent, presenter);
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>最后剩下的事情就是实现这个文本展示器，如清单 15 所示。</p>
		<br />
		<br />
		<a name="N102A7">
				<b>清单 15. 文本展示器</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">private static final DefaultInformationControl.IInformationPresenter
   presenter = new DefaultInformationControl.IInformationPresenter() {
      public String updatePresentation(Display display, String infoText,
         TextPresentation presentation, int maxWidth, int maxHeight) {
         int start = -1;
         // Loop over all characters of information text
         for (int i = 0; i &lt; infoText.length(); i++) {
            switch (infoText.charAt(i)) {
               case '&lt;' :
                  // Remember start of tag
                  start = i;
                  break;
               case '&gt;' :
                  if (start &gt;= 0) {
                    // We have found a tag and create a new style range
                    StyleRange range = 
                       new StyleRange(start, i - start + 1, null, null, SWT.BOLD)
                    // Add this style range to the presentation
                    presentation.addStyleRange(range);
                    // Reset tag start indicator
                    start = -1;
                  }
                  break;
         }
      }
      // Return the information text
      return infoText;
   }
};
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>处理过程是在 <code>updatePresentation()</code> 方法中完成的。这个方法接受要显示的文本和一个默认的 <code>TextPresentation</code> 实例。我们只需循环遍历该文本的字符，针对从该文本中找到的每个 XML 标签，我们向它的这个文本展示实例添加一个新的样式范围。在这个新的样式范围中，我们保留前景色和背景色不变，但是把字体样式设为粗体。 </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.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N102BC">
						<span class="atitle">上下文信息</span>
				</a>
		</p>
		<p>现在研究一下我们已在 <code>computeStyleProposals()</code> 方法中创建的 <code>ContextInformation</code> 实例。这个上下文信息将在某个建议已被插入文档之后显示出来。它可用于通知用户关于某个自动完成建议已被成功应用的信息。然而，仅只是向 <code>CompletionProposal()</code> 构造函数传递一个 <code>ContextInformation</code> 实例是不足够的。我们还必须完成方法 <code>getContextInformationValidator()</code> 来为这个上下文信息提供验证器。清单 16 显示了这是如何进行的。 </p>
		<br />
		<br />
		<a name="N102D9">
				<b>清单 16. getContextInformationValidator</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">public IContextInformationValidator getContextInformationValidator() {
   return new ContextInformationValidator(this);
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这里使用了 <code>ContextInformationValidator</code> 的默认实现。这个验证器将检查要显示的上下文信息是否包含在方法 <code>computeContextInformation()</code> 返回的上下文信息项数组中。如果没有，该信息将不会显示。因此我们还必须完成方法 <code>computeContextInformation()</code> ，如清单 17 所示。 </p>
		<br />
		<br />
		<a name="N102F2">
				<b>清单 17. computeContextInformation</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">public IContextInformation[] computeContextInformation(ITextViewer viewer, 
      int documentOffset) {
   // Retrieve selected range
   Point selectedRange = viewer.getSelectedRange();
   if (selectedRange.y &gt; 0) {
      // Text is selected. Create a context information array.
      ContextInformation[] contextInfos = new ContextInformation[STYLELABELS.length];
      // Create one context information item for each style
      for (int i = 0; i &lt; STYLELABELS.length; i++)
         contextInfos[i] = new ContextInformation(null, STYLELABELS[i]+" Style");
      return contextInfos;
   }
   return new ContextInformation[0];
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这里我们仅为每个样式标签创建一个 <code>IContextInformation</code> 项。当然，这种解决办法相当简单。更高级的实现应该检查选中文本的周围，并确定哪些具体的样式标签适用于选中的文本。 </p>
		<p>如果我们不想实现这个方法，还可以选择实现我们自己的 <code>IContextInformationValidator</code> ，它总是返回 true。 </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.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1030A">
						<span class="atitle">激活助理</span>
				</a>
		</p>
		<p>到目前为止，我们已经完成了新内容助理的主要逻辑。但是在测试该插件时，按下 Ctrl + 空格键的时候仍然什么事情也没有发生。当然，它为什么要发生呢？当这个组合键按下时，源代码查看器仍然不知道我们想要一个自动完成建议列表。</p>
		<p>在独立的 SWT/JFace 应用程序中，我们会向源代码查看器添加一个验证侦听器（参见清单 18），并检查这个组合键。按下 Ctrl + 空格键将触发内容助理操作，并且会禁止这个组合键的事件，以便源代码查看器不会进一步处理它 <b>。</b></p>
		<br />
		<br />
		<a name="N10319">
				<b>清单 18. VerifyKeyListener</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">sourceViewer.appendVerifyKeyListener(
   new VerifyKeyListener() {
      public void verifyKey(VerifyEvent event) {
      // Check for Ctrl+Spacebar
      if (event.stateMask == SWT.CTRL &amp;&amp; event.character == ' ') {
        // Check if source viewer is able to perform operation
        if (sourceViewer.canDoOperation(SourceViewer.CONTENTASSIST_PROPOSALS))
          // Perform operation
          sourceViewer.doOperation(SourceViewer.CONTENTASSIST_PROPOSALS);
        // Veto this key press to avoid further processing
        event.doit = false;
      }
   }
});
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>然而在工作台编辑器环境中（我们的 HTML 编辑器插件就是这种情况），我们不需要深入事件处理的细节。相反，我们会创建一个适当的 <code>TextOperationAction</code> 来调用内容助理操作。这是通过扩展类 <code>HTMLEditor</code> 中的方法 <code>createActions()</code> 来完成的。只需确保在包 <code>SampleHTMLEditor</code> 中创建一个文件 <code>SampleHTMLEditorPluginResources.properties</code> 来满足该插件资源包的请求即可！ </p>
		<br />
		<br />
		<a name="N1033A">
				<b>清单 19. TextOperationAction</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">private static final String CONTENTASSIST_PROPOSAL_ID = 
   "com.bdaum.HTMLeditor.ContentAssistProposal"; 
protected void createActions() {
   super.createActions();
   // This action will fire a CONTENTASSIST_PROPOSALS operation
   // when executed
   IAction action = 
      new TextOperationAction(SampleHTMLEditorPlugin.getDefault().getResourceBundle(),
      "ContentAssistProposal", this, SourceViewer.CONTENTASSIST_PROPOSALS);
   action.setActionDefinitionId(CONTENTASSIST_PROPOSAL_ID);
   // Tell the editor about this new action
   setAction(CONTENTASSIST_PROPOSAL_ID, action);
   // Tell the editor to execute this action 
   // when Ctrl+Spacebar is pressed
   setActionActivationCode(CONTENTASSIST_PROPOSAL_ID,' ', -1, SWT.CTRL);
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>现在可以再次测试这个插件。这时应该能够按 Ctrl + 空格键来调用内容助理了。您也许想要根据文本是否被选中来尝试内容助理的不同行为。</p>
		<p>而且，我们还可以添加更多的代码。例如，当键入 '&lt;'字符时，内容助理可以自动激活它自己。这可以通过向内容助理处理器指定这个自动激活字符来实现（就像每种文档类型能够具有特定的处理器一样，同样可以针对每种文档类型使用不同的自动激活字符）。为此，我们完成了类 <code>HtmlContentAssistProcessor</code> 中的方法 <code>getCompletionProposalAutoActivationCharacters</code> 的定义，如清单 20 所示。 </p>
		<br />
		<br />
		<a name="N10352">
				<b>清单 20. getCompletionProposalAutoActivationCharacters</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">public char[] getCompletionProposalAutoActivationCharacters() {
   return new char[] { '&lt;' };
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>此外，我们必须启用自动激活并设置自动激活延迟。这是在类 <code>XMLConfiguration</code> 中完成的。我们向方法 <code>getContentAssistant()</code> 添加如清单 21 所示的行。 </p>
		<br />
		<br />
		<a name="N10367">
				<b>清单 21. 向 getContentAssistant 添加行</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">   assistant.enableAutoActivation(true);
   assistant.setAutoActivationDelay(500);
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>最后，我们也许希望改变内容助理弹出窗口的背景色，以把它和附加信息窗口区别开来。因此，我们向方法 <code>getContentAssistant()</code> 添加了额外两行，如清单 22 所示。 </p>
		<br />
		<br />
		<a name="N10378">
				<b>清单 22. 向 getContentAssistant 添加行</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">   Color bgColor = colorManager.getColor(new RGB(230,255,230));
   assistant.setProposalSelectorBackground(bgColor);
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>注意，我们使用了 <code>XMLConfiguration</code> 实例的颜色管理器来创建新的颜色。当颜色不再需要时，这样为我们省去了清除它的麻烦，因为颜色管理器会负责颜色的清除。 </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.ibm.com/developerworks/cn/linux/opensource/os-ecca/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10389">
						<span class="atitle">高级概念</span>
				</a>
		</p>
		<p>现在，在成功地为我们的 HTML 管理器实现内容助理之后，您或许想知道基于模板的内容助理是如何工作的，以及它是如何实现的。我们从 Java 源代码编辑器中知道，这些内容助理具有一个特别的特性：它们的自动完成建议是可以参数化的。这类建议中的特定名称可由用户修改，结果使得该名称在整个建议中的所有实例被同时更新。</p>
		<p>遗憾的是，这个功能是 Eclipse Java 开发工具包（JDT）插件的一部分，因而不管是基于 SWT/JFace 的独立应用程序，还是最简单的 Eclipse 平台，凡是没有这个插件的应用程序，都无法使用这个功能。幸运的是，这个功能的源代码可供使用，并且调整它以适应其他环境并不困难。特别是， <code>org.eclipse.jdt.internal.ui.text.java</code> 包中的类 <code>ExperimentalProposal</code> 以及 <code>org.eclipse.jdt.internal.ui.text.link</code> 包中的类型 <code>ILinkedPositionListener</code> 、 <code>LinkedPositionUI</code> 和 <code>LinkedPositionManager</code> 实现了这个功能。 </p>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/library/os-ecca/index.html?S_TACT=105AGX52&amp;S_CMP=cn-a-l"><font color="#5c81a7">英文原文</font></a>. <br /><br /></li>
				<li>下载本文中描述的 <a href="ftp://www6.software.ibm.com/software/developer/library/os-ecca/samplehtmleditor.jar"><font color="#5c81a7">示例 HTML 编辑器的 jar 文件</font></a>。 <br /><br /><br /><br /></li>
				<li>在 <a href="http://www.eclipse.org/"><font color="#996699">Eclipse.org</font></a>查找关于 Eclipse 的更多信息。 <br /><br /><br /><br /></li>
				<li>要获得使用 Java 进行 Eclipse 开发的全面指南，请参阅 Berthold Daum 所著的 <a href="http://www.wileyeurope.com/WileyCDA/WileyTitle/productCd-0470869054.html"><font color="#5c81a7"><i>Eclipse 2 for Java Developers</i></font></a>一书(John Wiley &amp; Sons，2003)。该书部分内容可从 <a href="http://www.bdaum.de/eclipse/book/"><font color="#5c81a7">支持的 Web 站点</font></a>下载。 <br /><br /><br /><br /></li>
				<li>“ <a href="http://www.ibm.com/developerworks/cn/java/os-ecplug/index.html"><font color="#5c81a7">开发 Eclipse 插件</font></a>” ( <i>developerWorks</i>，2002 年 12 月) 指导您完成创建一个简单“Hello, World” 插件的过程。 <br /><br /><br /><br /></li>
				<li>“ <a href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecjdt/index.html"><font color="#5c81a7">扩展 Eclipse 的 Java 开发工具</font></a>” ( <i>developerWorks</i>，2003 年 7 月) 指导您完成使用 PDE 创建 Eclipse 插件的过程。 <br /><br /><br /><br /></li>
				<li>在 developerWorks 的 <a href="http://www.ibm.com/developerworks/oss/?S_TACT=105AGX52&amp;S_CMP=cn-a-l"><font color="#5c81a7">开放源代码项目专区</font></a>中，可以找到更多 <a href="http://www.ibm.com/developerworks/views/opensource/articles.jsp?S_TACT=105AGX52&amp;expand&amp;sort_order=desc&amp;search_by&amp;S_CMP=cn-a-l&amp;show_abstract=false&amp;sort_by=Date&amp;view_by=Eclipse"><font color="#5c81a7">为 Eclipse 用户准备的文章</font></a>。还可以参考 alphaWorks 上的最新 <a href="http://www.alphaworks.ibm.com/eclipse"><font color="#5c81a7">Eclipse 技术下载</font></a>。 <br /><br /><br /></li>
		</ul>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td colspan="3">
										<img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
								</td>
						</tr>
						<tr valign="top" align="left">
								<td>
										<p>
										</p>
								</td>
								<td>
										<img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="4" />
								</td>
								<td width="100%">
										<p>Berthold Daum 是一位居住在德国 Luetzelbach 的顾问和作家。他的畅销书 <a href="http://www.wileyeurope.com/WileyCDA/WileyTitle/productCd-0470869054.html"><font color="#5c81a7"><i>Eclipse 2 for Java Developers</i></font></a>的英语版最近由 John Wiley &amp; Sons 出版。这本书的更多信息可在 <a href="http://www.bdaum.de/"><font color="#5c81a7">Berthold 的 Web 站点</font></a>上找到。可以通过 <a href="mailto:berthold.daum at bdaum.de?cc="><font color="#5c81a7">berthold.daum at bdaum.de</font></a>联系他。</p>
								</td>
						</tr>
				</tbody>
		</table><img src ="http://www.blogjava.net/sean2fly/aggbug/100942.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean2fly/" target="_blank">巴山鹰</a> 2007-02-27 16:11 <a href="http://www.blogjava.net/sean2fly/articles/100942.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Connection Network Intelligence</title><link>http://www.blogjava.net/sean2fly/articles/Connection_Network_Intelligence.html</link><dc:creator>巴山鹰</dc:creator><author>巴山鹰</author><pubDate>Wed, 19 Jul 2006 03:56:00 GMT</pubDate><guid>http://www.blogjava.net/sean2fly/articles/Connection_Network_Intelligence.html</guid><wfw:comment>http://www.blogjava.net/sean2fly/comments/58956.html</wfw:comment><comments>http://www.blogjava.net/sean2fly/articles/Connection_Network_Intelligence.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean2fly/comments/commentRss/58956.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean2fly/services/trackbacks/58956.html</trackback:ping><description><![CDATA[<p align="left">To better understand a company, people may not only need to know its revenue, industry and products, but want to know its investors, business partners, and transactions with others. How a company relates to other companies or stakeholders, is often key intelligence to business analysts in decision making. However, due to the large data volume and scattering of relative information, the manual analysis of the relationships are often ineffective and inefficient. <br /><br />IBM Connection Network Intelligence (CNI) is an innovative Relationship Analysis technology developed by IBM China Research Lab, which is designed to help business analysts and decision makers to get insights from the inter-relationships of companies and stakeholders based on built-in domain knowledge. By integrating relationship, transaction and financial information into a holistic relationship network for analysis, it can help the analysts and decision makers to analyze the complex relationships between companies and stakeholders for a variety of business applications: <br />- Securities Fraud Investigation<br />- Securities Investment Analysis<br />- Banking Credit Risk Management<br />- Corporate Internal Reporting</p><img src ="http://www.blogjava.net/sean2fly/aggbug/58956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean2fly/" target="_blank">巴山鹰</a> 2006-07-19 11:56 <a href="http://www.blogjava.net/sean2fly/articles/Connection_Network_Intelligence.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>导出一个RCP程序(Exporting an RCP Application)</title><link>http://www.blogjava.net/sean2fly/articles/37077.html</link><dc:creator>巴山鹰</dc:creator><author>巴山鹰</author><pubDate>Thu, 23 Mar 2006 11:04:00 GMT</pubDate><guid>http://www.blogjava.net/sean2fly/articles/37077.html</guid><wfw:comment>http://www.blogjava.net/sean2fly/comments/37077.html</wfw:comment><comments>http://www.blogjava.net/sean2fly/articles/37077.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean2fly/comments/commentRss/37077.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean2fly/services/trackbacks/37077.html</trackback:ping><description><![CDATA[<p>      在Eclispe 3.1以后的版本, Eclipse platform提供了RCP Application 发布的向导,使RCP的发布过程变的相当简单, 但是也有很多需要注意的问题.<br />      以下是基于3.1以后平台发布的步骤:<br />      1. 确定你的Plugin 有一个*.product文件, 如果没有,可以用Product Configuration的创建向导创建一个.在"Initialize the file content"一项中, 有3种方式, 建议用第三种, 即用Lanuch Configration 的方式创建,因为你可以用当前workplace的环境配置, 换句话说可以排除一些环境上的问题,导致发布的程序出问题.我刚开始选的是第2项,结果就报了一个很奇怪的错误.<br />      2. 向导完后, 就会进入*.Product的editor中, 可以用Testing section中的"Lanchu the product"测试下你的配置的准确性.<br />      3. 如果你的Plugin中用到了第3方的lib, 需要处理一下. 如果你的lib是以java project的lib引用进来的, 需要把它变成发布后的plugin能够识别的方式.<br />      a, 如果还没有导入第三方的lib, 用import-&gt; File System 的Wizard导入第三方的 Jar文件.<br />      b, 进入在Plugin.xml editor的Runtime tab中,　在Classpath section 中，加入第三方Jar文件.<br />      c, 用new button 加入".", 包含你当前路径下的lib.<br />      d, 检查你加在此的lib也在build tab 的export section中被选中，如果不选，你导出的plugin run的时候会找不到lib 中包含的class.<br />      e, 保存你的修改．<br />      f, 选中你的Project, 用Context Menu -&gt;PDE Tools -&gt; Update Classpath, 改变plugin 中classpth 的引用方式．<br />　　除此方法以外你也可以在建Porject的时候直接把Third party的lib加进来，在Eclispe-&gt;new menu中有此wizard．<br />      4. 选择你的Porduct configration 的base方式，我没有为我的Plugin建feature，所以我选择的是"Plugin-ins"方式．<br />      5. 进入*.product的编辑器，点击"Export product export  wizard" link, 指定导出文件的路径, Jre配置, 然后点击"Finish", 导出文件．<br />      6. 进入你的导出目录, 检查你导出的Plugin是不是以目录结构导出的．如果不是，请重新导出 (RCP Plugin 也可以单独导出再放在其对应的目录下)，因为Eclipse platfrom 不能从一个压缩文件中去取你的第三方压缩包．      <br />      7. 运行exe文件．即可进入你的rcp程序．<br /><br /> </p><img src ="http://www.blogjava.net/sean2fly/aggbug/37077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean2fly/" target="_blank">巴山鹰</a> 2006-03-23 19:04 <a href="http://www.blogjava.net/sean2fly/articles/37077.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>