﻿<?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-eroself</title><link>http://www.blogjava.net/eroself/</link><description>关于人生的程式，在这里谱写......</description><language>zh-cn</language><lastBuildDate>Sun, 03 May 2026 04:33:49 GMT</lastBuildDate><pubDate>Sun, 03 May 2026 04:33:49 GMT</pubDate><ttl>60</ttl><item><title>构建基于通用导航器架构（CNF）的视图 第三部分：配置菜单</title><link>http://www.blogjava.net/eroself/archive/2008/07/15/214909.html</link><dc:creator>鬼谷子</dc:creator><author>鬼谷子</author><pubDate>Tue, 15 Jul 2008 03:04:00 GMT</pubDate><guid>http://www.blogjava.net/eroself/archive/2008/07/15/214909.html</guid><wfw:comment>http://www.blogjava.net/eroself/comments/214909.html</wfw:comment><comments>http://www.blogjava.net/eroself/archive/2008/07/15/214909.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/eroself/comments/commentRss/214909.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/eroself/services/trackbacks/214909.html</trackback:ping><description><![CDATA[<br />
转自：http://blog.csdn.net/windy444/archive/2007/12/31/2006309.aspx<br />
<br />
&nbsp;由windy444翻译，转载请注明
<p>原文名：Building a Common Navigator Framework (CNF) Viewer Part III: Configuring
Menus，作者：MICHAEL ELDER，出处：<a href="http://scribbledideas.blogspot.com/">http://scribbledideas.blogspot.com/</a>（本人从未能打开过，呵呵）。</p>
<p>先上Copyright</p>
<p>The opinions and ideas expressed herin are my own and do not represent the
intent, opinion, or official statement of any company or organization.<br />
All
postings by me to this site are copyrighted (C) by Michael D. Elder, 2006 and
made available under the terms of the Eclipse Public License 1.0 with the
constraint that any reuse of the content must contain this copyright
statement.</p>
<p>&nbsp;&nbsp;&nbsp;
在前面的文章中，我们通览了如何构件一个通用导航器架构视图，以及提供了一个基础扩展来展示属性文件。现在，我们将要学习如何为CNF配置菜单，以及如何为我们的视图添加操作来操作我们的内容。</p>
<p><font size="3">概览</font></p>
<p>&nbsp;&nbsp;&nbsp; 这边有两个基本选择来为CNF视图增加操作：</p>
<p>&nbsp;&nbsp;&nbsp; &#8226;
使用org.eclipse.ui.popupMenus作为objectContributions或viewerContributions来提供操作。...popupMenus扩展点能让你在整个Eclipse工作台上提供操作代理。CNF视图能被配置成接受这些操作代理（缺省情况下），或者忽略他们。在平台提供的Project
Explorer视图中，对象或视图操作是被接受的（在第四部分中会详细介绍）。</p>
<p>&nbsp;&nbsp; &nbsp;&#8226;
使用org.eclipse.ui.navigator.navigatorContent作为actionProviders来提供操作。有时候，客户需要更加有计划的控制下面这些内容：对于特定上下文环境中给定的菜单，要提供怎样的操作；基于当前的选择项，需要提供什么可重定向操作。</p>
<p>&nbsp;&nbsp;&nbsp; CNF的操作提供者，只被CNF视图所接受。（将在第五部分给出详细信息）</p>
<p><font size="3">配置菜单结构</font></p>
<p>&nbsp;&nbsp;&nbsp; 在第一部分，我们定义了示例&lt;viewer /&gt;元素，弹出菜单被简要的提到了。</p>
<p>&nbsp;&nbsp;&nbsp; 回忆一下，这里有两种方法来配置弹出菜单。第一种可能就是简单的为org.eclipse.ui.navigator.viewer中&lt;viewer
/&gt;元素下的popupMenuId指定一个值，第二种可能就是采取一种更主动的方法来配置菜单支持的插入点。</p>
<p>&nbsp;&nbsp;&nbsp; 提示：popupMenuId和popupMenu元素同时被指定将导致错误。</p>
<p>&nbsp;&nbsp;&nbsp; 如果我们想要设置popupMenuId，将如同下面看到的一样：</p>
<p>&nbsp;<img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F17.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp;
该标识符能被org.eclipse.ui.popupMenus的扩展者所使用，来为视图增加一个特定的viewerContributions；然而objectContributions不需要任何的标识符。</p>
<p>&nbsp;&nbsp;&nbsp; 当只有popupMenuId属性被指定，缺省的插入点（insertion
points）集合会自动的配置到弹出菜单中。在org.eclipse.ui.navigator.viewer的schema参考中，列出了缺省配置。为方便起见，这里也列出了：</p>
<p>"group.new" separator="true"<br />
"group.goto"<br />
"group.open"
separator="true"<br />
"group.openWith"<br />
"group.edit"
separator="true"<br />
"group.show"
separator="true"<br />
"group.reorganize"<br />
"group.port"<br />
"group.generate"
separator="true"<br />
"group.search" separator="true"<br />
"group.build"
separator="true"<br />
"additions" separator="true"<br />
"group.properties"
separator="true"</p>
<p>&nbsp;&nbsp;&nbsp; 这些值能被org.eclipse.ui.popupMenus中的menubarPath属性元素所使用。</p>
<p>&nbsp;&nbsp;&nbsp;
当有计划的使用和搜索菜单项时，这些值也能被使用（参考org.eclipse.jface.action.IContributionManager，特别是insertAfter(),insertBefore(),
和appendToGroup()）。</p>
<p>&nbsp;&nbsp;&nbsp;
所有字符常量("group.*")都没定义在org.eclipse.ui.navigator.ICommonMenuConstants中，以便有计划的使用。</p>
<p>&nbsp;&nbsp;&nbsp; 作为替换，我们可以选择定义&lt;viewer/&gt;的子元素&lt;popupMenu
/&gt;，这里我们可以定义自己的插入点（insertion points）。（译者注：略过一个基本操作）。</p>
<p>&nbsp;&nbsp;&nbsp; 在我们的例子中，我们可以使用同Project Explorer一样的菜单配置。</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F18.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 每个&lt;insertionPoint /&gt;元素暗示这一个GroupMarker能通过IContributionMenu
API被访问到。当separator属性被设置成true时，菜单将会展现一条水平线。Eclipse中的菜单有足够的智能，只显示必要的线，两条背靠背的线将只被显示成一条。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 让我们注意一下&lt;popupMenu
/&gt;下的allowsPlatformContributions="true"属性。缺省情况下，CNF接受..popupMenus提供的操作。若把该属性设置成false，将会限制菜单只接受操作提供者（Action
Providers）。</p>
<p>&nbsp;&nbsp;&nbsp;
上面的例子并没有做什么神奇的事，在你自己的CNF视图中，你可以根据需要定义自己的插入点("group.example")。推荐的命名规约为"group.*"，除了additions
group之外，上面的那些group都遵循了。</p>
<p>&nbsp;&nbsp;&nbsp; 对于扩展或操作CNF菜单插入点集合的一些评论。对于一个已经配置好的视图，是没有可能来声明性操作或扩展他的插入点集合的。有可能的是，通过Action
Providers，来增加新的GroupMarkers
或Separators，但这里需要当心。在第五部分，我们将详细介绍这个是如何完成的，现在只是提醒一下，需要当心，并且当只有需要用到&lt;actionProvider
/&gt;中dependsOn属性时。该dependsOn的值指明为菜单提供额外插入点集合的Action
Provider的标识符。永远不要programmatically（译者注：不知道该怎么翻）删除插入点，因为其它扩展可能会依赖与他们。如果你自己定义的视图不需要使用某个插入点，则在定义你自己的&lt;popupMenu
/&gt;元素时，不要定义他就好了。</p>
<p><font size="3">总结</font></p>
<p>&nbsp;&nbsp;&nbsp; 在这篇文章中，我们讨论了如何为CNF视图配置菜单，下面的文章将讨论如何使用org.eclipse.ui.popupMenus
和org.eclipse.ui.navigator.navigatorContent/actionProvider来增加菜单。</p>
<br />
<br />
<img src ="http://www.blogjava.net/eroself/aggbug/214909.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/eroself/" target="_blank">鬼谷子</a> 2008-07-15 11:04 <a href="http://www.blogjava.net/eroself/archive/2008/07/15/214909.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>构建基于通用导航器架构（CNF）的视图 第二部分：增加内容</title><link>http://www.blogjava.net/eroself/archive/2008/07/15/214908.html</link><dc:creator>鬼谷子</dc:creator><author>鬼谷子</author><pubDate>Tue, 15 Jul 2008 03:02:00 GMT</pubDate><guid>http://www.blogjava.net/eroself/archive/2008/07/15/214908.html</guid><wfw:comment>http://www.blogjava.net/eroself/comments/214908.html</wfw:comment><comments>http://www.blogjava.net/eroself/archive/2008/07/15/214908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/eroself/comments/commentRss/214908.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/eroself/services/trackbacks/214908.html</trackback:ping><description><![CDATA[<br />
转自：http://blog.csdn.net/windy444/archive/2007/12/31/2006304.aspx<br />
<br />
<p>由windy444翻译，转载请注明</p>
<p>原文名：Building a Common Navigator Framework (CNF) Viewer Part II: Adding
Content，作者：MICHAEL ELDER，出处：<a href="http://scribbledideas.blogspot.com/">http://scribbledideas.blogspot.com/</a>（本人从未能打开过，呵呵）。</p>
<p>先上Copyright</p>
<p>The opinions and ideas expressed herin are my own and do not represent the
intent, opinion, or official statement of any company or organization.<br />
All
postings by me to this site are copyrighted (C) by Michael D. Elder, 2006 and
made available under the terms of the Eclipse Public License 1.0 with the
constraint that any reuse of the content must contain this copyright
statement.</p>
<p>&nbsp;&nbsp;&nbsp;
在这篇文章中，我们将学习如何为我们上篇文章定义的例子增加一个简单的内容扩展。为避免陷于过度复杂的内容和标签提供者，我们将关注于一个简单的文件结构模型，简单文本文件*.properties。当完成时，我们的内容扩展将允许在Example
viewer展开任意*.properties文件，并在下面正确排列出数据。</p>
<p>&nbsp;&nbsp;&nbsp; 首先，让我们看一下，内容扩展在plugin.xml中看起来是怎样的。（译者注：略过一些基本操作，plugin.xml如下：）</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F6.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp; 该扩展用id
"org.eclipse.ui.examples.navigator.propertiesContent"定义了一个内容扩展，显示的名称是"Properties
File Contents"。该名称会出现在过滤器对话框的"Available
Extensions"标签中。我们马上会去看一下内容和标签提供者的Java代码，但现在只是注意一下，两者都被指定了。只指定其中的一个是不行的。</p>
<p>&nbsp;&nbsp;&nbsp; 最后，我们设置一些属性，告诉框架，我们需要怎样的扩展：</p>
<p>&nbsp;&nbsp; &#8226; <strong>activeByDefault</strong>&nbsp; 决定扩展是否在缺省配置中被激活（如：新工作空间）</p>
<p>&nbsp;&nbsp; &#8226; <strong>icon</strong>&nbsp; 决定在用户界面引用该扩展时，显示什么图标</p>
<p>&nbsp;&nbsp; &#8226; <strong>priority</strong>&nbsp;
有几种不同的用法。最主要的作用是指定视图中项的相对位置（视图中从上到下排列的分别是最高优先级（highest priority）项到最低优先级（lowest
priority）项）。一般的说，&#8220;一般级&#8221;（"normal"）或&#8220;高级&#8221;（"high"）对于大多数的扩展来说，足够了，两者分别预示着与资源扩展混合在一起（优先级一样的话，则按字母顺序）或恰好放在工程下的资源之上。</p>
<p>&nbsp;&nbsp; 在每个&lt;navigatorContent
/&gt;元素内，我们能指定不同类别的扩展。但在扩展我们的例子之前，我们必须向架构定义，我们的扩展何时被调用。我们必须定义，什么时候视图中树的节点能够提供children，parents，或者标签和图标。我们用Eclipse
核心表达式来做这个工作。</p>
<p>&nbsp;&nbsp; 对于内容扩展，这里有两个重要的表达式：&lt;<strong>triggerPoints</strong> /&gt;
和&lt;<strong>possibleChildren</strong> /&gt;。</p>
<p>&nbsp;&nbsp; &lt;triggerPoints /&gt;表达式指定树中哪种类型的节点对我们的扩展感兴趣。当架构找到了匹配&lt;triggerPoints
/&gt;的节点，我们的扩展会被调用，为该节点提供子元素。我们的扩展并不一定是唯一能有机会为该节点提供子元素的扩展，架构会聚集该节点下所有的子元素（译者注：可以是不同扩展提供的）。</p>
<p>&nbsp;&nbsp;&nbsp; <img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F7.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;possibleChildren
/&gt;表达式指定我们的扩展能为树中哪种类型的节点提供标签或父节点（译者注：注意与triggerPoints 的不同）。若你的场景中必须在视图中支持link
with editor,&nbsp;或者 setSelection()，&lt;possibleChildren /&gt;表达式必须是完整且正确的。</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F8.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp; 一旦我们定义了一个扩展，我们必须把它绑定到想要关联的视图上。设定一个&lt;viewerContentBinding
/&gt;，来指定任何匹配include中模式的扩展，这些扩展对于在&lt;viewerContentBinding
/&gt;元素中指定的任何viewerId的视图是可见的。可以参考上一篇文章。</p>
<p>&nbsp;&nbsp;&nbsp; <img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F9.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp; 既然我们已经设置好了扩展，现在可以来看一下真正处理事务的代码了。</p>
<p>&nbsp;&nbsp;&nbsp;
首先，我们需要一个模型。一个属性文件的结构是相当简单的，我们只要用一个模型对象PropertiesTreeData,就能够建模了。这个对象有三个域：name（属性的名称），value（属性的值），container（拥有属性模型的文件）。每一个模型元素，指示属性文件中的一条属性。</p>
<p>&nbsp;&nbsp;&nbsp;
在我们的例子中，模型只有当被内容提供者请求时，才被载入。内容提供者被框架用来决定树中每个元素的子元素，或者被用来指定给定元素的父元素（可能有多个）。</p>
<p>&nbsp;&nbsp;&nbsp;
我们的示例内容提供者实现了接口org.eclipse.jface.viewers.ITreeContentProvider，用来提供树形结构的信息。通用导航器架构也支持实现org.eclipse.jface.viewers.ITreePathContentProvider接口的内容提供者，但这个超出了本例的范围。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;
PropertiesContentProvider也提供了我们的扩展需要的其它一些功能，比如监听资源变化和更新模型（以及视图）。在本文中不会涉及，读者可以到本文的源码中了解这个是如何工作的。</p>
<p>&nbsp;&nbsp;&nbsp; 现在，我们将关注ITreeContentProvider提供的视图集成方法。</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F10.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp; ITreeContentProvider必须实现<strong>getElements(Object
input),getChildren(Object parent), hasChildren(Object element)</strong>&nbsp;和
<strong>getParent(Object element)</strong>方法。</p>
<p>&nbsp;&nbsp;&nbsp; getElements()方法被用来查询在视图根目录下有哪些元素。许多实现会直接调用getChildren()来处理，我们在这边也如此。</p>
<p>&nbsp;&nbsp;&nbsp; <img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F11.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; getChildren()方法接受一个对象（我们这里是*.properties结尾的IFile，或者是由于在&lt;triggerPoints
/&gt;中描述而必须引入的PropertiesTreeData模型实例）。</p>
<p>&nbsp;&nbsp;&nbsp;
在接下来的实现中，我们检查接受的对象是否为org.eclipse.core.resources.IFile，并且是否以*.properties结尾。如果接受的对象满足这些要求，我们检查载入模型的缓存，当未缓存时，尝试载入模型。updateModel()方法将为每个属性创建一个PropertiesTreeData对象，并且在cachedModelMap中缓存所找到的模型。请读者在源码中查看updateModel()方法是如何实现的。</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F12.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp;
hasChildren()方法被优化了，知道当传入的对象是以*.properties结尾的IFile，就返回true。另一种替换的方法，是在这边载入文件，作一些计算，但这样性能会受损。</p>
<p>&nbsp;&nbsp;&nbsp;
如果传入的对象是PropertiesTreeData模型元素，则返回false。因为我们的模型元素没有子元素。（属性没有子元素，但其它模型可能就会有了）。</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F13.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp;
getParent()方法返回包含PropertiesTreeData项的IFile，若传入其它参数，返回null。通用导航器架构会继续询问其它扩展，直到一个非null的的父元素被找到或者已经遍历了所有扩展。回忆一下，如果元素匹配&lt;possibleChildren
/&gt;表达式，扩展会被要求为该元素提供父节点。</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F14.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;
最后，我们内容扩展的标签提供者，会告诉视图如何为我们的模型元素（PropertiesTreeData）来展现标签和图标。既然我们只关注这些元素，我们不必担心如何为其它元素来提供标签和图标。这些元素将由其它的扩展来展现标签和图标。</p>
<p>&nbsp;&nbsp;&nbsp; PropertiesLabelProvider实现了org.eclipse.jface.viewers.ILabelProvider
和<br />
org.eclipse.ui.navigator.IDescriptionProvider接口。</p>
<p>&nbsp;&nbsp;&nbsp; ILabelProvider是JFace中提供标签和图标的缺省接口要求。</p>
<p>&nbsp;&nbsp;&nbsp; IDescriptionProvider是特定用于通用导航器架构的，用于在Eclipse窗口左下角的状态栏显示文本。</p>
<p>&nbsp;&nbsp;&nbsp; ILabelProvider要求的方法是getText()&nbsp;和 getImage()。我们将让模型标签显示"name=
value"的字符串。对于图标，我们使用平台提供的一个共享图标。</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F15.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp; 标签提供者在下面两种情况下会被访问到：1.自己的扩展定义的元素。2.所有匹配&lt;possibleChildren
/&gt;的元素。如果图标或标签返回了null，框架会基于&lt;possibleChildren
/&gt;和视图bindings，继续查找其它扩展（来显示标签和图标）。如果你的扩展希望由其它人来定义标签和图标，则要返回null。</p>
<p>&nbsp;&nbsp;&nbsp; 就这些了，最终的视图Example View在属性文件下列出了属性。</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F16.JPG" /></p>
<br />
<br />
<img src ="http://www.blogjava.net/eroself/aggbug/214908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/eroself/" target="_blank">鬼谷子</a> 2008-07-15 11:02 <a href="http://www.blogjava.net/eroself/archive/2008/07/15/214908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>构建基于通用导航器架构（CNF）的视图 第一部分：定义ViewPart</title><link>http://www.blogjava.net/eroself/archive/2008/07/15/214907.html</link><dc:creator>鬼谷子</dc:creator><author>鬼谷子</author><pubDate>Tue, 15 Jul 2008 03:01:00 GMT</pubDate><guid>http://www.blogjava.net/eroself/archive/2008/07/15/214907.html</guid><wfw:comment>http://www.blogjava.net/eroself/comments/214907.html</wfw:comment><comments>http://www.blogjava.net/eroself/archive/2008/07/15/214907.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/eroself/comments/commentRss/214907.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/eroself/services/trackbacks/214907.html</trackback:ping><description><![CDATA[<br />
转自：http://blog.csdn.net/windy444/archive/2007/12/30/2005315.aspx<br />
<br />
<p>由windy444翻译，转载请注明</p>
<p>原文名：Building a Common Navigator Framework (CNF) Viewer Part I: Defining the
View Part&nbsp;，作者：MICHAEL ELDER，出处：<a href="http://scribbledideas.blogspot.com/">http://scribbledideas.blogspot.com/</a>（本人从未能打开过，呵呵）。</p>
<p>先上Copyright</p>
<p>The opinions and ideas expressed herin are my own and do not represent the
intent, opinion, or official statement of any company or organization.<br />
All
postings by me to this site are copyrighted (C) by Michael D. Elder, 2006 and
made available under the terms of the Eclipse Public License 1.0 with the
constraint that any reuse of the content must contain this copyright
statement.</p>
<p>&nbsp;&nbsp;&nbsp; 关于扩展点和API的特定文档，可以在Eclipse的平台帮助（(Help &gt; Help Content）中找到，Platform
Plug-in Developer's Guide &gt;Reference &gt; API Reference | Extension Points
Reference，涉及的扩展点有org.eclipse.ui.navigator.viewer，org.eclipse.ui.navigator.navigatorContent。相关的API包为org.eclipse.ui.navigator。若你想知道这篇文章中提到的东西的更多细节，这些东西可以作为参考。</p>
<p>&nbsp;&nbsp;&nbsp;
好了，哪里开始呢？首先，我们将对包含该视图的插件作一些配置，把org.eclipse.ui.navigator添加到依赖（dependencies）中。然后，我们用org.eclipse.ui.views扩展点来定义一个view
part，并把org.eclipse.ui.navigator.CommonNavigator类作为view
part的实现类。这个类将为我们的视图提供一些基础功能。然后，我们定义org.eclipse.ui.navigator.viewer扩展点，把视图配置成通用导航器（Common
Navigator）。最后，能够通过定义org.eclipse.ui.navigator.navigatorContent扩展点以及绑定(org.eclipse.ui.navigator.viewer/viewerContentBinding)来关联扩展点和视图。</p>
<p>&nbsp;&nbsp;
你不仅可以通过org.eclipse.ui.navigator.CommonNavigator，把该架构用于导航器，你可以通过org.eclipse.ui.navigator.INavigatorContentService把该架构用于从对话框到编辑器的任何地方，或者定义你自己的视图和view
part。但在这里，我们将只关注于基本功能。</p>
<p><font size="3">基本设置</font></p>
<p>&nbsp;&nbsp; 通用导航器架构是Eclipse 3.2的一个新特性，因此，你至少需要安装Eclipse
3.2。（译者注：下面一些是开发过插件的人都知道的事情，此处略过）</p>
<p><font size="3">定义View Part</font></p>
<p>&nbsp;&nbsp; 当要定义一个具有通用导航器功能的视图，你必须定义一个实际的view part，这个是你视图的容器。</p>
<p>&nbsp;&nbsp; （译者注：略去一段无关紧要的，插件开发初学者可以去参考基本view的开发，定义完成后的plugin文件如下：）</p>
<p>&nbsp;&nbsp; <img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/clip_image002.JPG" /></p>
<p><font size="3">&nbsp;定义视图配置</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一旦定义好了view
part，我们将通过org.eclipse.ui.navigator.viewer对我们的视图作一些配置扩展，这些扩展将告诉架构一些基础的东西，例如，通用导航器的view
part是哪个，弹出菜单的结构是怎样的，是否要定义object contributions，以及一些会影响视图缺省行为的属性。</p>
<p>&nbsp;&nbsp;&nbsp; （译者注：略过定义plugin.xml文件过程，后面会附上该文件）</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;
<strong>对于弹出菜单的一些评论</strong>。通用导航器架构提供两种方式让视图来定制菜单。第一种方式是通过指定org.eclipse.ui.navigator.viewer扩展点下viewer的popupMenuId，来接受缺省的分隔符，以及菜单的group
mark id。缺省值被记录在org.eclipse.ui.navigator.viewer扩展点下，为了方便，被列在了下面。</p>
<p>"group.new" separator="true"<br />
"group.goto"<br />
"group.open"
separator="true"<br />
"group.openWith"<br />
"group.edit"
separator="true"<br />
"group.show"
separator="true"<br />
"group.reorganize"<br />
"group.port"<br />
"group.generate"
separator="true"<br />
"group.search" separator="true"<br />
"group.build"
separator="true"<br />
"additions" separator="true"<br />
"group.properties"
separator="true"</p>
<p>&nbsp;&nbsp;&nbsp; 另一种方式，你可以选择不去指定popupMenuId，作为替换，你可以指定&lt;popupmenu /&gt;作为&lt;viewer
/&gt;元素的子元素。在这里，你可以定义自己的分隔符以及group mark id（能够由后面的用户来增加菜单）。如果你期望绑定平台(Resource,
Java<sup>tm</sup>)提供内容扩展的内容（content）或者操作（Action），推荐您使用缺省分组（上面列出的）。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>对于选项（option）的一些评论</strong>。&lt;viewer /&gt;元素下的&lt; options
/&gt;元素能够允许指定基于字符串的name=value对。这里有一些选项被基础架构所使用（在org.eclipse.ui.navigator.viewer扩展点文档的例子部分有记录），但你自己的视图或扩展点也可以使用这种机制来提供额外的扩展。请参考org.eclipse.ui.navigator.INavigatorViewerDescriptor中读取&lt;viewer
/&gt;元素中属性的API。你能通过通用导航器视图的org.eclipse.ui.navigator.INavigatorContentService得到视图描述符。</p>
<p>&nbsp;&nbsp; 定义viewerId后的plugin文件：</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;
定义好视图后，我们需要添加内容扩展，并绑定到视图上。我将在下一篇文章中给出一些更具体的信息。作为示例，我们简单的把缺省的资源内容（由org.eclipse.ui.navigator.resources插件定义）绑定到视图上。</p>
<p>&nbsp;&nbsp;&nbsp; （译者注：略过一些基本操作，定义完后的plugin文件如下：）</p>
<p>&nbsp;<img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp; 你现在可以启动工作台了（Run... &gt; New Eclipse
Application），这时能看到我们的视图。但我们还未给视图绑定操作，所以，你仍然要通过在资源导航器或包浏览器中创建工程，才能在我们的视图中出现工程。后面，我们会增加资源操作和过滤器，但现在，让我们看看该视图拥有的缺省行为。目前有折叠所有按钮（Collapse
All），Link with Editor按钮，过滤器（Filters）按钮（以及一个"Available
Filters"标签），和一个扩展标签（"Available Content"）。</p>
<p>&nbsp;&nbsp;&nbsp;
要绑定资源过滤器，我们需要在&lt;/includes&gt;元素下增加另一个contentExtension元素，指定"org.eclipse.ui.navigator.resources.filters.*"为标识符。这将会选取org.eclipse.ui.navigator.resources定义的所有的过滤器。当然，你可以参考org.eclipse.ui.navigator.resources的plugin文件，选取你自己想要的过滤器的标示符。</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F1.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp; 再一次选择Run...，确认在过滤器对话框中出现了一些资源过滤器。</p>
<p>&nbsp;&nbsp;&nbsp;
接下来，我们将绑定默认的资源操作。要绑定操作，需要在我们扩展点的根下面，增加一个viewerActionBinding元素。（译者注：略过一些操作，定义完后的plugin文件如下：）</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F2.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp; &nbsp;现在，启动工作台后，在默认的空视图中（在视图中右键空的地方），你将看到New, Import, Export,&nbsp;和
Refresh操作。当你选中视图中的一个元素时，出现的菜单类似与资源导航器中的。</p>
<p>（译者注：再次略过一段操作，不影响对文章的理解）</p>
<p><font size="3">定义过滤器</font></p>
<p>&nbsp;&nbsp;&nbsp; 今天我们将做的最后一件事，是用Eclipse核心表达式（Core
Expressions）为我们的视图定义一个过滤器。核心表达式架构的文档在org.eclipse.core.expressions插件中。我们将用org.eclipse.core.resources定义的属性测试者（property
testers）来测试特定的工程性质（Nature），然后隐藏所有没有该性质的工程。</p>
<p>（译者注：略过一些操作，定义完后的plugin文件如下：）</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F3.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp; 你也可以在扩展点中设置activeByDefault属性，来决定该过滤器是否在缺省配置中被激活。</p>
<p>&nbsp;&nbsp;&nbsp;
最后，我们需要为我们的视图定义contentExtension，来作为viewerContentBinding的一部分。确保使用了我们新建的过滤器的id，或者一个通用的样式（如："org.eclipse.ui.examples.navigator.filters.*"）来绑定所有我们未来定义的匹配样式的过滤器。最后的plug.xml如下：</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F4.JPG" /></p>
<p>&nbsp;&nbsp;&nbsp; 现在，最后一次启动工作台。创建一个新的简单工程和Java工程，当&#8220;Hide non-Java
Projects&#8221;被激活时，简单工程会被隐藏。</p>
<p><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/windy444/%E6%96%B0%E5%BB%BA%20BMP%20%E5%9B%BE%E5%83%8F5.JPG" /></p>
<p>（译者注：第一部分终于翻译完了）</p>
<br />
<br />
<img src ="http://www.blogjava.net/eroself/aggbug/214907.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/eroself/" target="_blank">鬼谷子</a> 2008-07-15 11:01 <a href="http://www.blogjava.net/eroself/archive/2008/07/15/214907.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>养生堂</title><link>http://www.blogjava.net/eroself/archive/2008/07/01/211927.html</link><dc:creator>鬼谷子</dc:creator><author>鬼谷子</author><pubDate>Tue, 01 Jul 2008 07:44:00 GMT</pubDate><guid>http://www.blogjava.net/eroself/archive/2008/07/01/211927.html</guid><wfw:comment>http://www.blogjava.net/eroself/comments/211927.html</wfw:comment><comments>http://www.blogjava.net/eroself/archive/2008/07/01/211927.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/eroself/comments/commentRss/211927.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/eroself/services/trackbacks/211927.html</trackback:ping><description><![CDATA[<br />
转自：<a href="http://hi.baidu.com/siyu123/blog/item/7f0643c28587d534e4dd3b59.html">http://hi.baidu.com/siyu123/blog/item/7f0643c28587d534e4dd3b59.html</a><br />
<br />
1、酸性体液致病的原因: <br />
<br />
导致酶促反应效率下降。 <br />
导致血液粘度上升，流动性下降。 <br />
导致细菌和真菌在体内过度活跃。 <br />
导致免疫系统的反应速度和敏感度下降。 <br />
会改变血红细胞的物理特性，影响血液微循环的效率。 <br />
会引发各种体细胞为适应酸性体液环境而产生的不利突变。 <br />
<br />
2、酸性体质的主要病症表现： <br />
<br />
酸性体质者极易疲劳。 <br />
酸性体液严重影响儿童智力。 <br />
酸性体液易导致多种体内结石。 <br />
酸性体液易引发多种肿瘤和癌症。 <br />
酸性体液易导致动脉硬化、高血压。 <br />
酸性体液易导致多种过敏症、易感冒。 <br />
酸性体液易导致糖代谢疾病、痴肥、口臭。 <br />
酸性体液易导致各种关节痛症并会加重通风病情。 <br />
酸性体液加重钙流失，妨碍钙吸收，导致骨质疏松症。 <br />
酸性体液导致出生儿童性别比例失调，酸性体质易生女孩。 <br />
酸性体液导致肌肉皮肤松弛、易出现皱纹、易出现皮肤感染、导致治愈速度慢、易留疤<br />
痕。 <br />
<br />
3 、人体体液酸碱平衡理论 <br />
人体体液酸碱平衡是人体的三大基础平衡之一。 <br />
占人体体重 70 ％的体液有一定的酸碱度，并在较窄的范围内保持稳定，这种酸碱平衡<br />
是维持人体生命活动的重要基础。如果这一平衡被破坏，就会影响生命的正常活动效<br />
率，并导致各种疾病。人从一诞生就开始了她一生顽强的抗酸斗争，这就是人体体液酸<br />
碱平衡理论的核心内容。 <br />
<br />
随着人类社会文明的发展，人们发现越来越多新的严重疾病在不断出现，包括各种过<br />
敏、肿瘤、癌症、心血管疾病、糖尿病等等，这些疾病的共同特征是它们与人体外部的<br />
细菌、病毒无关，而是因为人体内部自身生理机能的失调或功能的下降所致。这些疾病<br />
无法*杀菌、消炎（除因机能问题导致体内共生微生物的大量繁殖外）来进行治疗，因为<br />
这些疾病的根源来自人体体液变酸。用世界著名医学博士、日本专家莜原秀隆的一句话<br />
讲：人体体液的酸化是百病之源。 <br />
<br />
不论人体的吸收和代谢多么复杂，但有一点是很清楚的，那就是人体的代谢过程是产生<br />
酸性物质的过程，人体所有活动都依赖生命的基本单位&#8220;细胞&#8221;将体内营养物，经氧化<br />
分解获得能量，同时释放出各种酸性代谢废物，无一例外。最基本的化学常识告诉我<br />
们，一个碱性的体液环境有利于中和、清除体内的酸性代谢物，是氧化分解过程得以顺<br />
利继续，生命可以连续不断的获得所需能量；事实十分清楚的告诉我们：就减少酸性代<br />
谢物在被排出人体之前对细胞活动的影响而言，一个碱性的体液环境绝对比酸性体液环<br />
境有优势得多；所以弱碱性得体液环境具有十分重要得生理意义。各种人体体液的趋向<br />
酸化是人体衰老过程（ Aging Process ）的重要指标。通过测定体液的酸碱度可以判断<br />
一个人细胞的生理年龄。而大量的正常细胞为适应不断酸化的体液环境，在其死亡之前<br />
就有机会获得为适应酸性环境的有效突变从而使细胞癌变。这一机理解释了 100 ％的癌<br />
症患者是酸性体质的事实。因此，调整和恢复体液应有的酸碱水平会减少细胞癌变的机<br />
会，它被誉为除外科切除和放射、药物疗法外的第三种防治癌肿的途径。 <br />
<br />
所以，弱碱性的体液环境是细胞活动的最佳也是最基本的机体环境，它使得生命整体可<br />
以合理地延续。 <br />
<br />
人体体液中，所有的基础体液都处于弱碱性， PH 值都大于 7.0 。血液的 PH 值为 <br />
7.35-7.45 ，而大多数分泌液也处于弱碱性水平，如果将人体所有的体液混合在一起，<br />
其平均 PH 值为 7.30-7.35 。人类赖以繁衍后代的精液和宫颈液的 PH 值更高达 7.5-<br />
9.0 。 <br />
<br />
我们无法改变体液酸化的大趋势－－即人体一定会死亡的规律，但是，我们完全可以延<br />
缓人体体液酸化的进程，从而达到延年益寿的目的。 <br />
<br />
此理论能够科学、有效和合理地解释了近 20 年全球泛滥的内源性疾病（非体外病菌入<br />
侵所产生的疾病：如心脑血管疾病、结石、关节炎、 痛风、过敏、癌肿等）的产生机<br />
理，并依据此理论找到了防治内源性疾病的有效方法。 <br />
<br />
<br />
<br />
<br />
4 、 为何酸性体质是导致各种癌肿和早衰的主要原因？ <br />
<br />
酸性体质使得正常细胞为适应酸性环境而导致细胞过早衰退或产生变异。事实表明，如<br />
有糖尿病、心血管疾病、各类癌症等中老年才有的疾病越来越年轻化，正是因为酸性体<br />
质人群越来越年轻化。而调整体液酸碱平衡被誉为预防和治疗癌肿的第三种有效方法。 <br />
<br />
<br />
六大原因造成现代人身体酸性化 <br />
<br />
1.饮食结构不合理　专家指出，科学的饮食习惯是酸碱食物比例为20%：80%，但是现代<br />
人饮食中的主食往往是精米白面、鸡鸭鱼肉蛋，而这些都是酸性食物，据分析这样的饮<br />
食习惯其酸碱比例却正好相反，为80%:20%。因此，长期摄入过多的酸性食物是导致人体<br />
酸性化的原因之一。 <br />
<br />
2.运动不足　在阳光下多做运动多出汗，可帮助排除体内多余的酸性物质。但现代人以<br />
车代步现象愈来愈多，运动量大大减少，长久便会导致酸性代谢物长期滞留在体内，导<br />
致体质的酸性化。 <br />
<br />
<br />
3.过重的心理负担　由于现代生活节奏的加快，人们在日常生活、工作和感情上承担着<br />
不同的压力。当这种压力得不到释放的时候，便会对身体造成影响，从而导致体质的酸<br />
性化。 <br />
<br />
<br />
4.不良嗜好　烟、酒等都是典型的酸性食品，毫无节制的抽烟饮酒等，极易导致人体的<br />
酸性化。 <br />
<br />
<br />
5.生活不规律　如彻夜唱卡拉OK、打麻将、夜不归宿等无规律生活，都会加重体质酸<br />
化。 <br />
<br />
<br />
6.环境的严重污染　由于饮用水、农作物、家禽鱼蛋等造成严重污染，人们摄入这些含<br />
有有害元素的饮水、食物和吸入有害空气后，其中的酸性物质会滞留在体内造成体质酸<br />
性化。 <br />
<br />
哪些人的身体容易&#8220;发酸&#8221; <br />
<br />
<br />
1.熬夜一族 晚上1：00以后不睡觉，人体的代谢作用由内分泌燃烧，用内分泌燃烧产生<br />
的毒素会很多，会使体质变酸，通常熬夜的人得慢性疾病的机率比抽烟或喝酒的人都来<br />
得高。所以每天尽量在晚上12：00以前睡觉，不要常熬夜，若非要熬夜，一星期以一次<br />
为限！熬夜时不要吃肉，尽量吃碳水化合物，这样隔天才不至于很累，可把伤害减至最<br />
低。 <br />
<br />
2.宵夜一族 <br />
<br />
凡是晚上8：00再进食就称做宵夜。吃宵夜隔天会疲倦，爬不起床，肝也会受损，因为睡<br />
觉时，人体各器官活动力低，处于休息状态，因此食物留在肠子里会变酸、发酵、产生<br />
毒素伤害身体。 <br />
<br />
3.早餐的&#8220;逃兵&#8221; <br />
<br />
一天三餐中，早餐最重要，但许多人普遍不吃早餐，一早空着肚子，体内没有动力，会<br />
自动使用甲状腺、副甲状腺、下脑垂体等腺体，去燃烧组织，造成腺体亢进、体质变<br />
酸，长期导致慢性病。 <br />
<br />
4.&#8220;精食&#8221;一族 <br />
<br />
少运动且整天坐在办公室的上班族最容易犯这种错误，因为吃的少，刻意选择很精致的<br />
食物而少吃粗粮，这种人的肠子老化的特别快，肝功能差，大便是黑色的而且会常便<br />
秘。因为精致食物缺乏纤维素，会导致肠子功能变差，甚至萎缩，你所吃的食物变成了<br />
毒素，使你体质变酸，慢性病也开始了。 <br />
<br />
测测你的体质是否&#8220;发酸&#8221;了 <br />
<br />
1.早起精神不佳； <br />
<br />
2.夜里睡不香(失眠)； <br />
<br />
3.整天都感到很累； <br />
<br />
4.工作想速战速决，没有持久力； <br />
<br />
5.情绪不稳定，容易发怒； <br />
<br />
6.易被虫咬； <br />
<br />
7.容易得皮肤病； <br />
<br />
8.容易发烧或感冒； <br />
<br />
9.有高血压、低血压、肝脏病； <br />
<br />
10.有糖尿病、肾脏病、痛风； <br />
<br />
11.经常头疼、腿痛、肩酸、腰酸； <br />
<br />
12.身体肥胖； <br />
<br />
13.有胃病、胃溃疡； <br />
<br />
14.有过敏症、便秘； <br />
<br />
15.有哮喘病、失眠症、神经衰弱； <br />
<br />
16.食欲不振； <br />
<br />
17.牙龈易出血； <br />
<br />
18.伤口易化浓； <br />
<br />
19.喜欢喝(碳酸)饮料； <br />
<br />
20.喜欢吃肉食、油腻食物； <br />
<br />
21.喜欢喝酒； <br />
<br />
22.喜欢吃甜食； <br />
<br />
23.喜欢吸烟。 <br />
<br />
有人说，当你25岁时，身体血液就已开始酸化，如果你到了30岁，已出现了上述的6～8<br />
种情况，那 <br />
<br />
你的酸性体质已到了相当的程度，怎么办？尽快采取措施减酸。 <br />
<br />
<br />
<br />
<br />
常见食物的酸碱性 <br />
<br />
<br />
强酸性 <br />
蛋黄、乳酪、白糖、西点、乌鱼子、柴鱼、牛奶、可乐类饮料等。 <br />
<br />
中酸性 <br />
火腿、鸡肉、鸭肉、鲔鱼、虾、猪肉、鳗鱼、牛肉、白面包、奶油、羊肉等。 <br />
<br />
弱酸性 <br />
白米、白面、花生、啤酒、酒、油炸豆腐、海苔、文蛤、章鱼、泥鳅。 <br />
<br />
中性 糙米、玉米、小米、大麦等粗粮 <br />
<br />
弱碱性 <br />
红豆、萝卜、苹果、甘蓝菜、洋葱、豆腐等。 <br />
<br />
中碱性 <br />
萝卜干、大豆、红萝卜、蕃茄、香蕉、橘子、番瓜、草莓、蛋白、梅干、柠檬、菠<br />
菜等。 <br />
<br />
强碱性 <br />
葡萄、茶叶、葡萄酒、海带芽、海带等。尤其是天然绿藻富含叶绿素，是不错的碱<br />
性健康食品。 <br />
<img src ="http://www.blogjava.net/eroself/aggbug/211927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/eroself/" target="_blank">鬼谷子</a> 2008-07-01 15:44 <a href="http://www.blogjava.net/eroself/archive/2008/07/01/211927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>喜事到</title><link>http://www.blogjava.net/eroself/archive/2008/07/01/211881.html</link><dc:creator>鬼谷子</dc:creator><author>鬼谷子</author><pubDate>Tue, 01 Jul 2008 06:07:00 GMT</pubDate><guid>http://www.blogjava.net/eroself/archive/2008/07/01/211881.html</guid><wfw:comment>http://www.blogjava.net/eroself/comments/211881.html</wfw:comment><comments>http://www.blogjava.net/eroself/archive/2008/07/01/211881.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/eroself/comments/commentRss/211881.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/eroself/services/trackbacks/211881.html</trackback:ping><description><![CDATA[<p><br />
&nbsp; 终于不加班了，做歌纪念。<br />
<br />
&nbsp; 七一喜鹊到，<br />
&nbsp; 朝鸣杨柳梢；<br />
&nbsp; 有歌和婉调，<br />
&nbsp; 平眉也弯腰。</p>
<img src ="http://www.blogjava.net/eroself/aggbug/211881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/eroself/" target="_blank">鬼谷子</a> 2008-07-01 14:07 <a href="http://www.blogjava.net/eroself/archive/2008/07/01/211881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>宝马忆</title><link>http://www.blogjava.net/eroself/archive/2008/06/27/211089.html</link><dc:creator>鬼谷子</dc:creator><author>鬼谷子</author><pubDate>Fri, 27 Jun 2008 04:01:00 GMT</pubDate><guid>http://www.blogjava.net/eroself/archive/2008/06/27/211089.html</guid><wfw:comment>http://www.blogjava.net/eroself/comments/211089.html</wfw:comment><comments>http://www.blogjava.net/eroself/archive/2008/06/27/211089.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/eroself/comments/commentRss/211089.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/eroself/services/trackbacks/211089.html</trackback:ping><description><![CDATA[<br />
&nbsp;&nbsp;&nbsp; 是夜飞贼游走，伺机而动，状若渴，馋吾之宝马亦久矣，忽而环顾四下无人，欲牵而走，马不从，以刀扼颈逼之，马从而无奈何也。晓而生计，吾寻视之，不得，凄凄焉。宝马乎，夫复何日可相见邪？唯扪心而感伤也。<br />
<br />
<br />
&nbsp;&nbsp;&nbsp; 小偷把我的爱车偷走了，那可是跟了我两年的宝马啊～
<img src ="http://www.blogjava.net/eroself/aggbug/211089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/eroself/" target="_blank">鬼谷子</a> 2008-06-27 12:01 <a href="http://www.blogjava.net/eroself/archive/2008/06/27/211089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>静</title><link>http://www.blogjava.net/eroself/archive/2008/06/24/210267.html</link><dc:creator>鬼谷子</dc:creator><author>鬼谷子</author><pubDate>Tue, 24 Jun 2008 03:32:00 GMT</pubDate><guid>http://www.blogjava.net/eroself/archive/2008/06/24/210267.html</guid><wfw:comment>http://www.blogjava.net/eroself/comments/210267.html</wfw:comment><comments>http://www.blogjava.net/eroself/archive/2008/06/24/210267.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/eroself/comments/commentRss/210267.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/eroself/services/trackbacks/210267.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p>雨过陌上独踱，不见虹之颜色。<br />
归来床前数点，零落月光之宴。</p>
<p>——雨后坝上寻虹不见而归有感。</p>
<img src ="http://www.blogjava.net/eroself/aggbug/210267.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/eroself/" target="_blank">鬼谷子</a> 2008-06-24 11:32 <a href="http://www.blogjava.net/eroself/archive/2008/06/24/210267.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>蔓草歌</title><link>http://www.blogjava.net/eroself/archive/2008/06/21/209696.html</link><dc:creator>鬼谷子</dc:creator><author>鬼谷子</author><pubDate>Sat, 21 Jun 2008 08:13:00 GMT</pubDate><guid>http://www.blogjava.net/eroself/archive/2008/06/21/209696.html</guid><wfw:comment>http://www.blogjava.net/eroself/comments/209696.html</wfw:comment><comments>http://www.blogjava.net/eroself/archive/2008/06/21/209696.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/eroself/comments/commentRss/209696.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/eroself/services/trackbacks/209696.html</trackback:ping><description><![CDATA[<br />
&nbsp; 窗含香蔓兮，绿荫拂面；晚风轻送兮，其臭如兰。<br />
<br />
<br />
&nbsp; 窗棱藤蔓缠绕，透过阳光，洒在脸上的是片片绿荫。<br />
&nbsp; 到了晚上，一阵风吹过，香味扑鼻，料是有花开了。<br />
&nbsp;
 <img src ="http://www.blogjava.net/eroself/aggbug/209696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/eroself/" target="_blank">鬼谷子</a> 2008-06-21 16:13 <a href="http://www.blogjava.net/eroself/archive/2008/06/21/209696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>无题</title><link>http://www.blogjava.net/eroself/archive/2008/06/17/208711.html</link><dc:creator>鬼谷子</dc:creator><author>鬼谷子</author><pubDate>Tue, 17 Jun 2008 13:28:00 GMT</pubDate><guid>http://www.blogjava.net/eroself/archive/2008/06/17/208711.html</guid><wfw:comment>http://www.blogjava.net/eroself/comments/208711.html</wfw:comment><comments>http://www.blogjava.net/eroself/archive/2008/06/17/208711.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/eroself/comments/commentRss/208711.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/eroself/services/trackbacks/208711.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;无题<br />
回望仲夏已晚秋，<br />
跣足南下少年游；<br />
道不逢缘何聚首，<br />
片片清幽点点眸。<br />
<br />
那年夏天,空气中透着晚秋的寒意,<br />
我只身来到成都实现自己的梦想,<br />
奈何天意弄人,得到了本不想要的.<br />
罢了罢了,只为了些许宁静和目光.<br />
<img src ="http://www.blogjava.net/eroself/aggbug/208711.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/eroself/" target="_blank">鬼谷子</a> 2008-06-17 21:28 <a href="http://www.blogjava.net/eroself/archive/2008/06/17/208711.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Extension Object/Interface模式</title><link>http://www.blogjava.net/eroself/archive/2008/06/17/208527.html</link><dc:creator>鬼谷子</dc:creator><author>鬼谷子</author><pubDate>Tue, 17 Jun 2008 02:01:00 GMT</pubDate><guid>http://www.blogjava.net/eroself/archive/2008/06/17/208527.html</guid><wfw:comment>http://www.blogjava.net/eroself/comments/208527.html</wfw:comment><comments>http://www.blogjava.net/eroself/archive/2008/06/17/208527.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/eroself/comments/commentRss/208527.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/eroself/services/trackbacks/208527.html</trackback:ping><description><![CDATA[转自：http://xerdoc.com/blog/archives/228.html<br />
<br />
<p>Extension Object同Visitor、Decorator等模式差不多，都是在不改变类层次机构的前提下向系统添加功能，被称为扩展对象模式。</p>
<p>在了解扩展对象模式之前需要了解一下相关的一条OOD原则，就是单一职责原则（Single Responsibility Principle，SRP）。</p>
<blockquote>
<p>就一个类而言，应该仅有一个引起他变化的原因。</p>
</blockquote>
<p>大致的意思就是要把职责分配到不同的对象当中去。如果我们把每一个职责的变化看成是变化的一个轴线，当需求变化时，该变化会反映为类的职责的变化。
如果一个类承担了多余一个的职责，那么引起他变化的原因就多余一个轴线，也就是把这些职责耦合到了一起。在某种程度上，这种耦合会导致Fragile
Design，当变化发生时，设计会遭受到意向不到的破坏。</p>
<p>在具体讨论之前，先来看一个设计问题。<br />
<br />
我们要开始设计一个RSS Reader，一般使用一棵树来呈现对于Feed的管理和组织结构，类似于Bloglines、GreatNews那样的。构建这棵树的过程中，我们可以使用Composite模式来设计相应的类层次结构，例如，基本接口我们可以采用
</p>
<pre><code>public interface IChannelNode {<br />
public String getTitle();<br />
public String getId();<br />
... ...<br />
}</code></pre>
<p>然后构建Composite的子类（用来容纳目录等组织结构）和具体类，例如</p>
<pre><code>public class CompositeChannelNode implements IChannelNode {<br />
public void addChild(IChannelNode node);<br />
... ...<br />
}<br />
public class FeedChannelNode implements IChannelNode {<br />
... ...<br />
}</code></pre>
<p>上述这些类结构完全可以用来描述这棵树的层次结构了，而且我们可以使用Eclipse中的TreeViewer来显示。Eclipse中的
TreeViewer是基于Structured
Model的，所以，几乎使用很少的代码，就可以完成显示这个树的功能，这也是Eclipse对于这种基于Structured
Model封装的比较好的结果。不过简单的使用UI会比较单调，所以，就需要对于UI部分进行润色，那么在这个类层次中不可避免的要加入UI部分的代码，
这就不符合SRP的要求了。另外，假如我们还要完成对于这棵树的persistent，那么序列化的代码又会污染这个单纯的模型了。这里我们就可以使用扩
展对象模式了，把这些变化另外wrap起来。</p>
<h3>对Extension的抽象封装</h3>
<p>这个是Uncle
Bob提过的一种优雅的实现机制，是基于对于Extension的抽象封装，然后在本身模型（上面的Channel组织模型）注册这些
Extension，在运行时可以方便的得到合适的扩展来执行相应功能。例如我们来定义一个Extension的注册和使用机制，然后在
IChannelNode中将请求delegate给这套机制，当然也可以把这个直接集成到IChannelNode的代码中，下面用Part和
PartExtension来完成这部分功能（代码不是完整的）。</p>
<pre><code>public abstract class Part  {<br />
public void addExtension(String extensionType, PartExtension extension) { ... ... }<br />
public PartExtension getExtension(String extensionType) { ... ... }<br />
}<br />
public interface PartExtension {<br />
}</code></pre>
<p>可以简单的使用一个HashMap来完成extension的注册和获取。其实这部分的代码就把扩展这部分不变的内容封装起来，而对于可能存在的变
化完全可以利用增加新的类来完成，也就满足了开放封闭原则（OCP）。比如我们说到的persistent部分，建立相应的persistent扩展就可
以了。</p>
<pre><code>public class PersistentPart extends Part {<br />
public PersistentPart() {<br />
addExtension("CSVFormat", new CSVPersistentPartExtension());<br />
// 注册其他format的存储方式<br />
}<br />
}<br />
public interface PersistentExtension extends PartExtension {<br />
public void doPersistent(IChannelNode node);<br />
}<br />
public class CSVPersistentPartExtension implements PersistentExtension {<br />
public void doPersistent(IChannelNode node) {<br />
// save node.getTitle();<br />
// save node.getId();<br />
......<br />
}<br />
}</code></pre>
<p>变化的部分就是用什么方式来存储信息了，比如我们不使用CVS来存储而改用XML存储，那么只需要生成相应的XMLPersistentPartExtension，并把他注册到PersistentPart就可以了。<br />
看了这个，当时我觉得搞得真是很麻烦，很复杂，而且可读性很差啊，呵呵。不过本身Extension Object的实现就是特别复杂的，慢慢实践，我想会越来越掌握这种方法的。</p>
<p>我投入精力更大的是下面要说的一种同Adapter结合起来的扩展方法，并使用这种方法实现了UI部分的分离，感觉确实方便很多，不过开始理解起来也是比较头疼。</p>
<h3>使用Adapter模式来扩展</h3>
<p>这里要说的是Eclipse平台底层最为核心的IAdaptable，Erich
Gamma一手打造，我先后看了好久才体会到这种设计的魅力。这次扩展我们拿UI来说事。Eclipse中显示一个Tree很容易，有了
Structured
Model之后，打造好相应的TreeContentProvider和LabelContentProvider就基本完成了。但是对于一个效果复杂的
显示在Provider中的代码就会显的很臃肿，主要也是在LabelContentProvider中，而原有模型的逻辑也会增加很多基于UI部分的代
码，比如Channel不同状态下要显示什么样的图片，使用什么样的字体，什么样的前景背景色等等。所以，比较好的办法就是分离出一套并行的类层次，
IChannelNodeUI，而且如果在扩展过程中我们能够把IChannelNode适配到IChannelNodeUI，并交给
LabelContentProvider就好办了，所有的UI代码就搞到IChannelNodeUI这套东西里面去了。<br />
现在介绍的扩展方式就是依据Adapter为基础的，所以，现在先把Adapter这部分搞定</p>
<pre><code>public interface IChannelNodeUI {<br />
public Image getImage();<br />
public Font getFont();<br />
... ...<br />
}<br />
public class ChannelNodeUIAdapter implements IChannelNodeUI {<br />
private IChannelNode node_;<br />
public ChannelNodeUIAdapter(IChannelNode node) { ... ... }<br />
<br />
public Image getImage() {<br />
if (node_.isLoading())<br />
// return loading image;<br />
... ...<br />
}<br />
......<br />
}</code></pre>
<p>接下来也就是对这些扩展的管理，比如我们还有对于IPersistent的适配，那么如何更好的来管理这些扩展呢。比较容易想到的还是注册然后获取这样的方法，可是这些适配器和适配关系如何管理呢？<br />
看一下，Erich大牛的IAdaptable</p>
<pre><code>org.eclipse.core.runtime/IAdaptable<br />
public interface IAdaptable {<br />
public Object getAdapter(Class adapter);<br />
}</code></pre>
<p>如果IChannelNode从IAdaptable继承过来，那么我们就可以在LabelContentProvider中这样写到（都没有进行check啊）：</p>
<pre><code>    public Image getImage(Object element) {<br />
IChannelNode node = (IChannelNode)element;<br />
IChannelNodeUI uiNode = (IChannelNodeUI)node.getAdapter(IChannelNodeUI.class);<br />
return uiNode.getImage();<br />
}<br />
</code></pre>
<p>那么就需要我们对于IChannelNode中的getAdapter来实现，比如我们在ChannelNode中：</p>
<pre><code>    public Object getAdapter(Class adapter) {<br />
if(adapter == IChannelNodeUI.class)<br />
return new ChannelNodeUIAdapter(this);<br />
return null;<br />
}</code></pre>
<p>这样的问题就是不好维护，所以，Erich大牛还提供了对应的IAdapterFactory和IAdapterManager，当然AdapterManager是Platform中提供的对于框架部分的封装，不需要我们干什么了。<br />
我们也就需要生成一个AdapterFactory，然后把他注册给Platform的AdapterManager就可以了：</p>
<pre><code>    IAdapterManager manager = Platform.getAdapterManager();<br />
IAdapterFactory uiFactory = new ChannelNodeUIFactory();<br />
manager.registerAdapters(uiFactory, IChannelNode.class);</code></pre>
<p>那么如何使用呢，Eclipse的Platform里提供了一个PlatformObject的类，继承他直接就具有了Adaptable的能力，
并自动把getAdapter的请求转交给Platform了，缺陷就是会影响你的继承体系，毕竟Java无法多元继承，所以，如果你不是继承自
PlatformObject的话，自己转交一下，</p>
<pre><code>    Platform.getAdapterManager().getAdapter(this, IChannelNodeUI.class);</code></pre>
<p>这种扩展对象模式就是基于这样的Adapter模式，由IAdaptable、IAdapterFactory和IAdapterManager完成了对框架的封装，从而给Eclipse带来了巨大的灵活性。</p>
<p>参考数目：《敏捷软件开发》、《Contributing to Eclipse》</p>
<br />
<br />
<img src ="http://www.blogjava.net/eroself/aggbug/208527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/eroself/" target="_blank">鬼谷子</a> 2008-06-17 10:01 <a href="http://www.blogjava.net/eroself/archive/2008/06/17/208527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>