<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>alartin</title>
    <description></description>
    <link>http://alartin.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>请大家，参加一下Java JBoss开源中间件的培训调查，谢谢！</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/110799" style="color:red;">http://alartin.javaeye.com/blog/110799</a>&nbsp;
          发表时间: 2007年08月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          尊敬的JavaEyers们：<br />
&nbsp;&nbsp; 我们计划为国内推动Java开源中间件的使用和普及做一些事情，如果您是Java的粉丝，请您在百忙之中参加我们的一个小调查，半分钟就可以完成，谢谢大家啊?<br />
调查网址：<a href="http://www.surveymonkey.com/s.aspx?sm=hDWamiaiR4I1p4Zejiflww_3d_3d">Java JBoss开源中间件培训的调查</a>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/110799#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 10 Aug 2007 10:47:06 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/110799</link>
        <guid>http://alartin.javaeye.com/blog/110799</guid>
      </item>
      <item>
        <title>Swing中的并发和多线程</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/107784" style="color:red;">http://alartin.javaeye.com/blog/107784</a>&nbsp;
          发表时间: 2007年08月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          看到很多地方讲述Swing中的并发和多线程问题，感觉讲的都不如Sun的教程，这里复述一下关键。Swing之所以和多线程紧密联系在一起是因为图形界面编程中如果只采取顺序编程（也就是你的代码或任务依次执行），会出现很大的问题，比如你要编写一个FTP客户端，你不能让文件下载的时候，用户界面死在那里，你既不能取消任务也不能和界面交互吧。所以有必要将耗时的任务，比如文件下载放到一个独立的线程中处理，而让用户同时能够干其他事情。简单来说，Swing中有三种线程：<br />
<ol>
    <li>启动线程或者初始线程： 这个线程负责调用main方法，很多顺序编程一开始就用的是这种线程。在Swing中启动线程负责很少的事务，主要干两件事情，第一件就是创建一个可运行的对象(Runnable Object),这个可运行对象的任务比较重要，它负责初始化图形界面，第二件就是将这个可运行对象安排到另外一个非常重要的线程，事件分派线程中执行。第二件事情是通过SwingUtilies的invokeLater和invokeAndWait方法来实现的。几乎所有的创建Swing组件和与Swing组件交互的代码都要在事件分派线程中执行。</li>
    <li>事件分派线程：在Swing中负责事件处理的代码需要在一个特定的线程中运行，这个线程就是事件分派线程。大部分调用Swing方法的代码也在这个线程中运行。原因是大部分Swing对象中的方法并不是线程安全的，所以需要这个特定的事件分派线程来保证线程安全。当然也有部分swing对象中的方法指明是线程安全的，这些方法可以在任何线程中调用。你可以将事件分派线程中运行的代码想象成一系列短小的任务，大部分任务都是调用事件处理方法，例如ActionListener.actionPerformed()方法，其他任务可被程序代码通过SwingUtilities的invokeLater/invokeAndWait方法来安排。需要注意的是，在事件分派线程中的任务必须短小精悍，这意味着这些任务能够很快执行完毕，如果你发现有一个耗时的任务，那么你肯定出错了，你会发现你的图形界面经常被卡住，或者死掉了。对于耗时任务你需要另外一个线程，例如工作线程(Worker Thread)来处理。判断你的代码时候运行在事件分派线程上的方法很简单，使用<span class="APILink"><code>javax.swing.SwingUtilities.isEventDispatchThread()方法即可。</code></span></li>
    <li><span class="APILink">工作线程(Worker Thread)或者后台线程(Background Thread)：你可以在这个线程中处理耗时任务。<br />
    </span></li>
</ol>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/107784#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 01 Aug 2007 14:51:21 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/107784</link>
        <guid>http://alartin.javaeye.com/blog/107784</guid>
      </item>
      <item>
        <title>Netbeans平台: 顶层组件</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93979" style="color:red;">http://alartin.javaeye.com/blog/93979</a>&nbsp;
          发表时间: 2007年06月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>Netbeans平台的顶层组件:org.openide.windows.TopComponent是JComponent的子类. 顶层组件知道如何在Netbeans的窗口系统中工作. 如果你想想主窗口中添加组件, 通常的办法是你自己写一个类,继承顶层组件, 就像你开发普通的Swing程序, 继承一个JPanel一样.<br />
</p>
<p>顶层组件需要在模式Mode中生存, Mode是一种docking容器.</p>
<p>顶层组件有各种状态:<br />
</p>
<ul>
    <li> <strong>开/关 open/closed</strong> -&nbsp; 当一个顶层组件被打开时,一个Tab面板将会出现在主窗口代表这个顶层组件<br />
    </li>
    <li> <strong>可见的/不可见的 visible/invisible</strong> - When a TopComponent is <em>visible</em>, it is the selected tab in its <span class="wikipage">Mode 当一个顶层组件可见时, 它在它的模式Mode中是被选择的Tab面板</span> </li>
    <li> <strong>激活的/失活的 active/inactive</strong> - <span class="wikipage">当一个顶层组件被激活时, 它或者一个子组件将获得键盘焦点, 它也是<strong>当前的全局选择的上下文.</strong></span> </li>
</ul>
<p>每个顶层组件都有一个Lookup和一个或者多个激活的节点. 这些定义了窗口系统的选择上下文, 这将决定哪些动作(菜单条目, 工具栏按钮等)是激活的, 和在何种情况下,当这些动作调用时,系统如何处理.</p>
<p>顶层组件是Netbeans平台的窗口API的一部分. 已经打开了的顶层组件能够被序列化,以便在重新启动的情况下复原. Netbeans5.0提供了这个功能的模版. 实际上它使用了外部化接口进行保存. 至于是否保存取决于getPersistenceType()方法的返回值.<br />
</p>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93979#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Jun 2007 15:09:43 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93979</link>
        <guid>http://alartin.javaeye.com/blog/93979</guid>
      </item>
      <item>
        <title>Netbeans平台: 数据对象</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93974" style="color:red;">http://alartin.javaeye.com/blog/93974</a>&nbsp;
          发表时间: 2007年06月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <strong>数据对象</strong>是<strong>文件对象</strong>的包装器. 一个文件对象仅仅是一个<strong>数据容器</strong>,也许这个文件有一个MIME类型, 不过像java.io.File一样, 他一点也不知道也不关心它到底代表了何种文件或者是这个文件究竟是什么. 数据对象是Netbeans平台中<strong>装载器API</strong>的一部分.
<p>一个数据对象代表一个或多个(通常都是只代表一个)文件对象. 一个数据对象知道它代表的文件是何种类型. 它能够代表一个例如java源文件的经过解析的内容.或者在一个InstanceDataObject的情况下, 文件名就可以提供所有的信息.<br />
</p>
<p><strong>数据对象</strong>由数据装载器产生. 模块为特定的文件类型注册相应的数据装载器. 所有对于每个<strong>文件类型</strong>,通常都有一个对应的数据装载器. 同时每个术语这个文件类型的文件通常都对应<strong>一个数据对象</strong><br />
</p>
<p><strong>数据对象很少提及类型. 如果你将一个数据对象转换为一个实现类,那么十有八九你做错了</strong>. 通常的使用方法是你询问一个数据对象,要求得到你感兴趣的(程序需要交互的)接口的实例. 这个方法是DataObject.getCookie(Class class).<br />
</p>
<p>举个最简单的例子, Netbeans API定义了一个接口org.openide.cookies.OpenCookie, 这个接口只有一个方法: open(). 这个方法将在编辑器中打开一个文件. 当open()方法被调用时到底发生了什么完全取决于实现这个数据对象的模块. 系统的其他部分不需也不必知道任何实现的细节: 它仅仅需要知道数据对象是否有一个OpenCookie.如果有,那么在它的上下文菜单中打开动作将被激活, 打开动作将会调用DataObject.getCookie((OpenCookie.class)).open()方法, 同时返回一个OpenCookie.<br />
</p>
<p><strong>Cookie</strong>这个名字容易让人费解, 很不幸,这是个历史遗留问题. getCookie方法其实时服务发现方法Lookup的老版本变种. 这两个其实是一样的.只不过getCookie方法需要所有返回的对象要实现Node.Cookie这个标记接口,而Lookup能返回任何对象. <strong>估计在未来的版本中getCookie()方法会被一个新的getLookup()方法取代.</strong><br />
</p>
<p>就像上面说得一样, 一个数据对象也许代表不止一个文件.所以当你在用户界面展开一个目录时,也许实际的数据对象少于目录中的文件. 这就是为什么使用Netbeans开发可视化图形界面时,每个Swing表单都有一个Java源文件和一个表单文件(.form)相对应,但是在用户界面中你看不到这个表单文件的原因. 在过去, .properties属性文件也使用这种机制从而使用一个节点来代表不同语言的资源文件.<br />
</p>
<p>然而, 这种一个数据对象能够代表多个文件的方式是<strong>强烈不鼓励</strong>的, 新的程序和代码不要使用这种方式, <strong>由于</strong><strong>它在弹性方面带来了严重的副作用,</strong><strong>这种方式将逐渐被取消.</strong><br />
</p>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93974#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Jun 2007 14:52:18 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93974</link>
        <guid>http://alartin.javaeye.com/blog/93974</guid>
      </item>
      <item>
        <title>Netbeans平台: 如何创建一个对用户选择敏感的动作?</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93896" style="color:red;">http://alartin.javaeye.com/blog/93896</a>&nbsp;
          发表时间: 2007年06月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          使用Netbeans IDE开发Java程序时, 你会发现如果你选择的是Java源文件,那么编译这个动作就是可以运行的, 如果你选择的是具有Main方法的Java类文件, 那么执行这个动作就是可以运行的. 这就是说Netbeans IDE根据用户的选择来确定那些动作可以运行,那些动作不可以运行. 那么使用Netbeans平台如何达到上述的效果呢. 基本上, 有三种方式:<br />
<br />
使用CookieAction<br />
<br />
使用NodeAction<br />
<br />
自己开发
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93896#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Jun 2007 11:31:35 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93896</link>
        <guid>http://alartin.javaeye.com/blog/93896</guid>
      </item>
      <item>
        <title>Netbeans平台: .shadow文件</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93852" style="color:red;">http://alartin.javaeye.com/blog/93852</a>&nbsp;
          发表时间: 2007年06月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <br />
Netbeans平台中, .shadow文件主要用于系统文件系统的配置数据上. .shadow文件在功能上和Unix的软连接很像. 实际上就是一个文件的指针. .shadow文件通常在只需要一个对象实例,但是必须在多个目录下存在的情况下使用. 例如, 一个动作通常在系统文件系统中Action目录下声明,但是这个动作也必须在菜单和工具栏中出现. 我们不能创建这个动作的多个实例来解决上面的问题. 一个.instance文件在模块的层文件layer.xml中的Actions目录中创建. 然后在其他需要这个对象的地方创建对应的.shadow文件指向这个.instance文件. 在系统文件系统中声明一个.shadow文件:<br />
<pre><div class="dp-highlighter"><div class="bar"> </div><ol class="dp-xml" start="1"><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">folder</span><span> </span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;A&quot;</span><span class="tag">&gt;</span><span>  </span></span></li><li class=""><span>      <span class="tag">&lt;</span><span class="tag-name">file</span><span> </span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;com-foo-mymodule-MyClass.instance&quot;</span><span class="tag">/&gt;</span><span>  </span></span></li><li class="alt"><span>   <span class="tag"><!--</span--><span class="tag-name">folder</span><span class="tag">&gt;</span><span>  </span></span></span></li><li class=""><span>  </span></li><li class="alt"><span>   <span class="tag">&lt;</span><span class="tag-name">folder</span><span> </span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;B&quot;</span><span class="tag">&gt;</span><span>  </span></span></li><li class=""><span>      <span class="tag">&lt;</span><span class="tag-name">file</span><span> </span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;Shadow1.shadow&quot;</span><span class="tag">&gt;</span><span>  </span></span></li><li class="alt"><span>          <span class="tag">&lt;</span><span class="tag-name">attr</span><span> </span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;originalFile&quot;</span><span> </span><span class="attribute">stringvalue</span><span>=</span><span class="attribute-value">&quot;A/com-foo-mymodule-MyClass.instance&quot;</span><span class="tag">/&gt;</span><span>  </span></span></li><li class=""><span>      <span class="tag"><!--</span--><span class="tag-name">file</span><span class="tag">&gt;</span><span>  </span></span></span></li><li class="alt"><span>   <span class="tag"><!--</span--><span class="tag-name">folder</span><span class="tag">&gt;</span><span>  </span></span></span></li><li class=""><span>  </span></li><li class="alt"><span>   <span class="tag">&lt;</span><span class="tag-name">folder</span><span> </span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;C&quot;</span><span class="tag">&gt;</span><span>  </span></span></li><li class=""><span>      <span class="tag">&lt;</span><span class="tag-name">file</span><span> </span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;anotherShadow.shadow&quot;</span><span class="tag">&gt;</span><span>  </span></span></li><li class="alt"><span>          <span class="tag">&lt;</span><span class="tag-name">attr</span><span> </span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;originalFile&quot;</span><span> </span><span class="attribute">stringvalue</span><span>=</span><span class="attribute-value">&quot;A/com-foo-mymodule-MyClass.instance&quot;</span><span class="tag">/&gt;</span><span>  </span></span></li><li class=""><span>      <span class="tag"><!--</span--><span class="tag-name">file</span><span class="tag">&gt;</span><span>  </span></span></span></li><li class="alt"><span>   <span class="tag"><!--</span--><span class="tag-name">folder</span><span class="tag">&gt;</span><span>  </span></span></span></li></ol></div><folder name="A"><folder name="B"><folder name="C"><file name="anotherShadow.shadow"><br /></file></folder></folder></folder></pre>
<p>.shadow文件可以指向系统文件的任何文件, 也可以指向磁盘上的真实文件. 例如在Netbeans IDE中Favorite Tab面板上,使用.shadow文件指向磁盘上的真实目录.<br />
</p>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93852#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Jun 2007 10:59:04 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93852</link>
        <guid>http://alartin.javaeye.com/blog/93852</guid>
      </item>
      <item>
        <title>Netbeans平台: 我该使用何种注册方式呢?</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93820" style="color:red;">http://alartin.javaeye.com/blog/93820</a>&nbsp;
          发表时间: 2007年06月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我们知道在Netbeans平台中有四种注册/安装方式:<br />
<ul>
    <li>在模块的JAR文件的META-INF/services目录下增加文件条目<br />
    </li>
    <li><span class="wikipage">在系统文件系统下的某目录下增加文件</span> </li>
    <li>在模块的manifest文件中增加manifest条目<br />
    </li>
    <li>实现org.openide.modules.ModuleInstall类并且在manifest文件中配置, 这种方式是在系统启动时执行Java代码</li>
</ul>
我们知道模块的注册和安装其实在Netbeans平台中是同一个概念. 那么我们究竟应该使用何种方式进行注册呢?<br />
<br />
具体情况具体分析:<br />
<br />
如果我们正在实现其他模块提供的API, 那么这个模块应该告诉我们如何做. 如果它告诉你应该使用<strong>默认的lookup查询</strong>, 那么这就意味着使用META-INF/services机制.<br />
<br />
如果我们正在定义自己开发的模块的API, 其他模块将实现这个API并且提供自己的类(想一下IDE的Navigator组件,不同的模块注册句柄能够按照不同的文件类型显示Navigator工具), 那么,很明显,基于manifest的注册机制首先就不在考虑范围之内, 因为在manifest条目中无法增加新类型. 程式化的注册机制也是能不用就不用, 因为弹性太差. 所以只剩下 META-INF/services机制或者系统文件系统机制. 我们可以考虑几个问题:<br />
<br />
Is this just a simple interface or abstract class people should implement, and I just have to find them all and use them?
<p><em>A:</em> If so, use <tt>META-INF/services</tt> </p>
<p><em>Q:</em> Will all of the objects other modules will register be used at the same time, or are there subsets for specific contexts? </p>
<p><em>A:</em> This pertains to performance and scalability - wherever possible, you want to avoid actually instantiating the objects other modules install, and delay instantiating them until they really need to be used. Opening module jars and classloading are both expensive operations that slow things down. </p>
<p>If there will potentially be a large number of subclasses of your interface, try to find a way to divide them into context-appropriate categories and use folders in the system filesystem to partition contexts. For example, if you define the interface <tt>Eater</tt>, and modules will implement eaters of various foods, you probably should create folders for different general kinds of food. That way, you don't have to load a bunch of classes and create the <tt>OliveEater</tt>, <tt>BreadEater</tt>, <tt>EggEater</tt> and <tt>SausageEater</tt> just to ask them if they can eat the <tt>Pizza</tt> you came across. </p>
<p><em>Q:</em> Is there information needed about how each object is to be used which could be provided declaratively, without instantiating the object? </p>
<p><em>A:</em> If so, use the system filesystem, and either let modules declare <a href="http://wiki.netbeans.org/wiki/Edit.jsp?page=DevFaqFilesystemAttributes" class="editpage" title="Create 'DevFaqFilesystemAttributes'">file attributes</a> thatprovide additional information, or let modules put their objects in subfolders that have contextual meaning (the same way the folder <tt>Loaders/text/x-java</tt> uses the folder path to indicate the data type objects pertain to). </p>
<p><em>Q:</em> How many modules will actually implement my interface? How many objects from other modules will I typically be dealing with? Do I need to instantiate all of them just to display a list in the UI? </p>
<p><em>A:</em> Displaying things in the UI is a particularly important case:  <em>You do not want to have to load a bunch of classes from a module just to show an icon and a display name for something</em> - this pertains to anything you're going to display in the Options dialog, on Menus, or various other views. </p>
<p>You can solve this by using <a href="http://wiki.netbeans.org/wiki/view/DevFaqInstanceDataObject" class="wikipage">.instance files</a> and asking that modules implementing your API use the <a href="http://wiki.netbeans.org/wiki/view/DevFaqFileAttributes" class="wikipage">file attributes</a> defined for .instance files to declare the icon and display name.  Then your code can just get a <a href="http://wiki.netbeans.org/wiki/view/DevFaqFileObject" class="wikipage">FileObject</a> for each registered instance, call <tt>DataObject.find(theFileObject).getNodeDelegate().getIcon()</tt> or <tt>getDisplayName()</tt> to get the icon or display name of the object <em>without ever having to create the object until it needs to do real work</em>. </p>
<p>If you run the risk of having to instantiate all the objects in a folder just do trivial tests such as finding out how many objects of one class are in a given folder (which may contain objects of other classes), consider recommending <a href="http://wiki.netbeans.org/wiki/view/DevFaqDotSettingsFiles" class="wikipage">.settings files</a> instead of <a href="http://wiki.netbeans.org/wiki/view/DevFaqInstanceDataObject" class="wikipage">.instance files</a> in your folders. </p>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93820#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Jun 2007 09:49:13 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93820</link>
        <guid>http://alartin.javaeye.com/blog/93820</guid>
      </item>
      <item>
        <title>Netbeans平台: 声明式的安装 VS 程序式的安装</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93815" style="color:red;">http://alartin.javaeye.com/blog/93815</a>&nbsp;
          发表时间: 2007年06月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>在很久很久以前, Netbeans中的大部分对象都是在启动的时候装载的. 当开发程序很小的时候,这个方式没有什么问题, 但是当你开发很大的应用的时候, 这种方式就是一场灾难. 每个系统的新的组件都让启动过长变得更加漫长,垃圾回收变得更加频繁,需要更多的内存支持.这种方式被称为程序式的安装.<br />
</p>
<p>不过,现在的Netbeans慢慢改变了这种方式. 大部分系统安装只涉及一个<strong>文本条目</strong>: 在<strong>XML层文件</strong>中添加一些东西,而不是运行Java代码. <strong>理想情况下,一个模块在系统启动的时候应该不做任何事情</strong>,只有需要这个模块的时候,再做处理.这种方式被称为声明式的安装.</p>
<p>声明式的安装是通过在模块的JAR文件的META-INF/services目录下创建一个文件或者创建一个XML层文件声明这个模块安装时需要处理的信息. 这样,当需要这个模块实际工作时,你的对象才被实例化.</p>
当然,如果你真的需要系统启动的时候运行一些Java代码, 你可以使用<strong>ModuleInstall类.</strong><br />
<p></p>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93815#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Jun 2007 09:31:51 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93815</link>
        <guid>http://alartin.javaeye.com/blog/93815</guid>
      </item>
      <item>
        <title>Netbeans平台: 模块是如何影响系统的?</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93811" style="color:red;">http://alartin.javaeye.com/blog/93811</a>&nbsp;
          发表时间: 2007年06月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Netbeans平台中的模块包含两个重要的内容,一个是配置数据,一个是对象. 模块有四种方式来在Netbeans平台中安装配置数据和对象, 其中三种方式是声明式的,这种机制使我们鼓励的.
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93811#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Jun 2007 09:05:04 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93811</link>
        <guid>http://alartin.javaeye.com/blog/93811</guid>
      </item>
      <item>
        <title>Netbeans平台: 窗口系统</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93213" style="color:red;">http://alartin.javaeye.com/blog/93213</a>&nbsp;
          发表时间: 2007年06月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Netbeans平台中窗口系统负责创建主应用窗口,能够在用户界面打开组件. 窗口系统位于org.openide.windows包内.实现类位于窗口模块org.netbeans.core.windows包.<br />
<br />
窗口系统最著名的两个概念: 模式(Mode)和顶层组件(TopComponent). <br />
<br />
什么是<strong>模式</strong>?<br />
模式这个名词命名的非常令人困惑, 不过由于历史原因和兼容性只能继续使用这个名词. <strong>这个名词其实仅仅指的是主窗口中Tab容器的位置.</strong> 例如在中间还是左侧,右侧还是底部等等.<br />
<br />
顶层组件<br />
我们开发的可视组件,例如一个面板通常都是继承自这个顶层组件. 这个组件是我们开发中最经常使用的. 顶层组件可以被放到Tab容器中. 如果你想快速了解顶层组件, 你可以使用程序接口创建和打开它. 只需要创建一个动作, 这个动作调用new MyTopComponent.open()就可以在Netbeans看见这个组件.
<p>窗口系统定义模式, 而我们知道模式其实是Tab容器在主窗口中占用的位置. 顶层组件是能够被放置到Tab容器中的GUI组件.<br />
</p>
<p>我们通过使用<strong>声明式的XML窗口系统API</strong>安装这些组件.这样做的原因如下:<br />
</p>
<ul>
    <li>弹性: 组件不必被创建和反序列化, 除非它们真的需要被打开</li>
    <li>单例化: 在IDE中,你肯定不需要5个项目Tab面板.使用XML API,你可以非常方便的使用组件的单例实例</li>
    <li>持久化: 和窗口系统关联的组件拥有唯一的ID,在会话间能够正确的将组件持久化.</li>
</ul>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93213#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 22 Jun 2007 17:04:01 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93213</link>
        <guid>http://alartin.javaeye.com/blog/93213</guid>
      </item>
      <item>
        <title>Netbeans平台: .setting文件</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93200" style="color:red;">http://alartin.javaeye.com/blog/93200</a>&nbsp;
          发表时间: 2007年06月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <tt>.settings</tt> files are similar to <tt><a href="http://wiki.netbeans.org/wiki/view/DevFaqInstanceDataObject" class="wikipage">.instance files</a></tt>, with the distinction that they specify all the superclasses/interfaces of the object represented, so that some code can ask Lookup/whatever &quot;Do you have one of these?&quot; without needing to actually create an instance of the object. You could call .settings files &quot;POJO persistence&quot;.
<p>They had a brief run of popularity as Yet Another Way To Store Settings a few years ago, around when the new window system was being conceived. They're not bad, but a bit baroque. The main point was to avoid loading classes or creating objects just to satisfy a test like &quot;how many object instances are there of X&quot;, &quot;does this folder/lookup/collection contain an instance of X&quot;. For NetBeans, where there are lots of classes, this sort of thing really does make a difference in performance. The observation was that huge amounts of classloading could be triggered just to find out that something was not actually of use to whatever code triggered it to be instantiated. </p>
<p><tt>.settings</tt> files can be used for the same purposes as <tt><a href="http://wiki.netbeans.org/wiki/view/DevFaqInstanceDataObject" class="wikipage">.instance files</a></tt> - as a way of indicating that the file represents some class that should be instantiated.  The main difference is that by defining all of the superclasses and interfaces of the the object they represent, it is possible for the system to delay actually instantiating the object longer - more questions about the object can be answered by the system without creating it to answer those questions. </p>
<p><tt>.settings</tt> files are typically not used for registering actions in the main menu and similar places, since these actions will need to be instantiated almost immediately anyway in order to determine if they should be enabled or not.  A future API for declarative actions will possibly change that, but at present, it does neither harm more good, and <tt><a href="http://wiki.netbeans.org/wiki/view/DevFaqInstanceDataObject" class="wikipage">.instance files</a></tt> are simpler (and for cases where the object will be instatiated immediately anyway, faster). </p>
<p>Some examples: </p>
<h4 id="section-DevFaqDotSettingsFiles-DeclaringASystemOptionAsA.settingsFileFromAnXMLLayer">Declaring a system option as a <tt>.settings file</tt> from an <tt><a href="http://wiki.netbeans.org/wiki/view/DevFaqModulesLayerFile" class="wikipage">XML layer</a></tt></h4>
Have a layer entry such as this:
<pre>  &lt;folder name=&quot;Services&quot;&gt;<br />    &lt;file name=&quot;org-openide-text-PrintSettings.settings&quot; url=&quot;PrintSettings.settings&quot;&gt;<br />      &lt;attr name=&quot;SystemFileSystem.localizingBundle&quot; stringvalue=&quot;org.netbeans.core.Bundle&quot;/&gt;<br />      &lt;attr name=&quot;SystemFileSystem.icon&quot; urlvalue=&quot;nbresloc:/org/openide/resources/printSettings.gif&quot;/&gt;<br />    &lt;/file&gt;<br />  &lt;/folder&gt;<br /></pre>
<p>Note the <tt>url</tt> attribute - it points to a file <tt>PrintSettings.settings</tt> which is in the same directory in the module jar as the layer file - it is a relative path.  That settings file will look like this: </p>
<pre>  &lt;?xml version=&quot;1.0&quot;?&gt;<br />  &lt;!DOCTYPE settings PUBLIC &quot;-//NetBeans//DTD Session settings 1.0//EN&quot; &quot;http://www.netbeans.org/dtds/sessionsettings-1_0.dtd&quot;&gt;<br />  &lt;settings version=&quot;1.0&quot;&gt;<br />    &lt;instanceof class=&quot;java.beans.beancontext.BeanContextProxy&quot;/&gt;<br />    &lt;instanceof class=&quot;org.openide.util.SharedClassObject&quot;/&gt;<br />    &lt;instanceof class=&quot;org.openide.options.SystemOption&quot;/&gt;<br />    &lt;instanceof class=&quot;org.openide.options.ContextSystemOption&quot;/&gt;<br />    &lt;instanceof class=&quot;org.openide.text.PrintSettings&quot;/&gt;<br />    &lt;instance class=&quot;org.openide.text.PrintSettings&quot;/&gt;<br />  &lt;/settings&gt;<br /></pre>
<p>The two things to note are that the <tt>.settings</tt> file declares many of the relevant parent classes of the object (so it does not need to be instantiated just to see what kind of object it is), and the layer file declares the icon and a resource bundle (for the display name) as <a href="http://wiki.netbeans.org/wiki/view/DevFaqFileAttributes" class="wikipage">file attributes </a>. </p>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93200#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 22 Jun 2007 16:37:06 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93200</link>
        <guid>http://alartin.javaeye.com/blog/93200</guid>
      </item>
      <item>
        <title>Netbeans平台: .instance文件</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93197" style="color:red;">http://alartin.javaeye.com/blog/93197</a>&nbsp;
          发表时间: 2007年06月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Netbeans平台中有.instance文件这个概念. 实际上, .instance文件代表一个对象实例, 所以也称为实例文件
<p>一个实例文件通过它的类名来表明它是哪个类的实例. 例如 com-foo-mymodule-MyObject.instance 实例文件表明它是MyObject类的实例. 实例文件可以代表任何Java类,只要它提供一个默认的构造器或者一个静态的创建方法.<br />
</p>
<p>在Netbeans的基础构建中, 一个实例文件产生InstanceDataObject,实例数据对象, 实例数据对象能够提供一个实例Cookie, InstanceCookie, 然后实例Cookie初始化这个JavaBean. 所以获得系统文件系统中声明的对象的一个实例的代码看起来就像:<br />
</p>
<pre>public static Object getTheObject (String pathInSystemFilesystem) {<br />    InstanceCookie ck =  DataObject.find (Repository.getDefault().getDefaultFileSystem().getRoot()<br />        .getFileObject(pathInSystemFilesystem)).getCookie(InstanceCookie.class);<br />    return ck.instanceCreate();<br />}<br /></pre>
<p>或者使用FolderLookup, FolderLookup提供一个快捷的方法获得一个目录下对象的所有实例:<br />
</p>
<pre>FileObject f = Repository.getDefault().getDefaultFileSystem().getRoot().getFileObject(&quot;MyFolder&quot;);<br />DataFolder fld = DataFolder.findFolder(f);<br />FolderLookup lkp = new FolderLookup (fld);<br />Lookup.Result res = lkp.getLookup().lookup (new Lookup.Template(WhatISaidToPutHere.class));<br />res.allInstances();<br /></pre>
<p>注意XML层文件不需要默认的构造器,你也可以提供一个静态方法来创建对象:<br />
</p>
<pre><file name="ObjectTypes.instance"><br />  </file><br />&lt;file name=&quot;ObjectTypes.instance&quot;&gt;<br />  &lt;attr name=&quot;instanceCreate&quot; methodvalue=&quot;org.netbeans.core.ui.UINodes.createObjectTypes&quot; /&gt;<br />  &lt;attr name=&quot;instanceClass&quot; stringvalue=&quot;org.openide.nodes.Node&quot; /&gt;<br />&lt;/file&gt;<file name="ObjectTypes.instance"><attr name="instanceCreate" methodvalue="org.netbeans.core.ui.UINodes.createObjectTypes">  <attr name="instanceClass" stringvalue="org.openide.nodes.Node"><br /></attr><br /></attr></file></pre>
<p>第二个条目instanceClass的值意味着系统不必初始化你的对象,仅仅看一下它是否和类节点匹配.<br />
</p>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93197#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 22 Jun 2007 16:32:01 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93197</link>
        <guid>http://alartin.javaeye.com/blog/93197</guid>
      </item>
      <item>
        <title>Netbeans平台: 文件对象</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93195" style="color:red;">http://alartin.javaeye.com/blog/93195</a>&nbsp;
          发表时间: 2007年06月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Netbeans平台中的文件对象(FileObject)是存在Netbeans文件系统(FileSystem)中的虚拟文件. 它可以是磁盘上的文件,也可以是任何类似文件的东西.例如远端FTP服务器上的文件,JAR包里的一个文件条目,甚至XML文件中的一个条目,等等.<br />
<br />
Netbeans平台中的文件对象和java.io.File文件有很大不同:<br />
<ul>
    <li>你不能生成一个代表<strong>尚不存在的文件</strong>的文件对象, 就是说如果真正的文件不存在,你不能生成一个对应的Netbeans文件对象</li>
    <li>你可以<strong>监听</strong>文件对象的变化.</li>
    <li>文件对象可以拥有<strong>键值对形式的文件属性</strong></li>
</ul>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93195#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 22 Jun 2007 16:10:58 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93195</link>
        <guid>http://alartin.javaeye.com/blog/93195</guid>
      </item>
      <item>
        <title>Netbeans平台: 文件的识别</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93184" style="color:red;">http://alartin.javaeye.com/blog/93184</a>&nbsp;
          发表时间: 2007年06月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          很多应用程序通过用户界面来显示目录和文件, Netbeans用户界面是通过系统文件系统中的虚拟文件来创建的,很多Netbeans的用户界面其实是系统文件系统的一个视图.而系统文件系统其实是运行时根据解析所有模块的层次文件layer.xml构建的.<br />
<p>基本的机制是:特定的,已知的文件类型分别具有自己的图标,菜单选项和行为或者动作. </p>
<p>Netbeans如何知道这些文件的类型呢?</p>
<p>答案是:这些文件其实或者是FileObject包装起来的<strong>文件</strong>(java.io.File),或者是<strong>配置文件</strong>(通过包装模块的XML文件). 真正你看到的其实是节点. 节点提供文件相关的动作,名字等其他事情. 而在节点和文件对象之间的是数据对象: </p>
<p>Node &lt;---&gt; DataObject &lt;---&gt; FileObject</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |-------- DataObject知道文件的类型,不同的文件扩展名对应不同的类型的DataObject(由实现文件类型支持接口的模块提供), 例如图片模块能够识别和打开gif,png格式的图片</p>
识别不同文件类型的模块安装了不同的<strong>DataLoader数据装载器</strong>. <strong>数据装载器是文件类型特异的数据对象的工厂类</strong>.
<p>所以当一个目录被打开时,Netbeans系统就会询问每个已知的数据装载器: 你认识这个文件类型么? <strong>第一个</strong>回答认识的数据装载器负责创建对应的数据对象.实际上这个识别过程会有一些优化过程在里面.但是基本流程是这样的.</p>
<p>为了实际显示每个文件的一些数据,Netbeans系统会调用每个对应数据对象的<strong>getNodeDelegate()</strong>方法, 这些节点是你在Netbeans用户界面看到的真正的东西.<br />
</p>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93184#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 22 Jun 2007 15:16:47 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93184</link>
        <guid>http://alartin.javaeye.com/blog/93184</guid>
      </item>
      <item>
        <title>Netbeans平台:系统文件系统</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/93159" style="color:red;">http://alartin.javaeye.com/blog/93159</a>&nbsp;
          发表时间: 2007年06月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Netbeans平台中有一个概念: System FileSystem, <strong>系统文件系统, 又叫配置文件系统</strong>.<br />
<br />
系统文件系统其实就是Netbeans的配置数据的中心仓库,也就是用来存储配置数据信息的.系统文件系统由Netbeans系统在运行时根据所有模块的XML层文件(XML Layer, layer.xml)文件组装配置形成. 各个模块使用系统文件系统的目录去定义<strong>扩展点</strong>(Extension Point).<br />
<br />
<strong>扩展点: </strong>每个模块可以定义一个目录或者文档来指定<strong>其他模块</strong>可以放置到此的文件或者对象(通常是<strong>实例文件, instance file</strong>),Netbeans系统在运行时扫描并且装载这些内容.<br />
<br />
系统文件系统的<strong>顶层</strong>是<strong>用户目录</strong>(在Windows下,通常是登陆用户,在Document and Setting目录下,当然你可以指派用户目录)底下的<strong>config子目录.</strong>系统文件系统在这个目录下进行读写和比较操作,例如在Netbeans系统上去掉帮助文件,不是真正的删除物理文件,而是在这个目录下生成一个空文件, 例如HelpFile.instance_hidden,这样Netbeans系统就不显示帮助文件了. 任何类型的文件都能放入系统文件系统中, 这取决于Netbeans中的模块以及模块定义的目录或者文档.<br />
<br />
系统文件系统识别文件的机制和一般的机制一样,所以你可以将java文件放到系统文件系统中去,你可以使用编辑器打开,编辑,和存储.就像其他地方的java文件一样,当然它将被保存到用户目录下面. 这也是Netbeans中你可以编辑文件模版的机制和原因.<br />
<br />
系统文件系统中一些特定的目录包含特定的信息, 他们其实就是组成Netbeans平台的部分模块定义的:<br />
<ul>
    <li> <strong><tt>Actions动作</tt></strong>  存储系统中所有的全局动作,可以拥有分类的子目录,通过.instance文件安装动作 </li>
</ul>
<ul>
    <li> <strong><tt>Menu菜单</tt></strong>  主窗口中菜单条的内容,每个菜单都有一个目录,还有子菜单具有子目录, 下面的.instance文件用来指定哪些动作可以在菜单上显示.<br />
    </li>
</ul>
<ul>
    <li> <strong><tt>Loaders加载器</tt></strong> - 包含定义MIME类型的子目录,例如 <tt>Loaders/text/x-java</tt> , MIME类型用来定义不同的属性, 例如弹出菜单(右键)就可以根据节点文件的MIME类型来显示不同的动作. 例如html文件可以激活浏览器, java文件可以激活编译动作.</li>
</ul>
还有其他一些事情可以被模块API指定, 从而影响对象的使用:<br />
<ul>
    <li> 文件的位置: 一个模块可以指定一个目录,直接将对象放入这个目录,或者要求其他客户模块在这个目录中创建子目录,从而使得整个文件路径具有语义(看下面)</li>
</ul>
<ul>
    <li> 文件的类型 : 你会经常安装各中代表Java对象的.instance文件, 通常模块指定目录下的那些类或者接口能够被使用</li>
</ul>
<ul>
    <li> <span class="wikipage">文件的属性</span>:  需要额外信息来描述如何对待文件时需要指定文件属性键值对. </li>
</ul>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/93159#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 22 Jun 2007 14:18:05 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/93159</link>
        <guid>http://alartin.javaeye.com/blog/93159</guid>
      </item>
      <item>
        <title>Apache VFS(7): 文件管理器解析文件的方法</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/92436" style="color:red;">http://alartin.javaeye.com/blog/92436</a>&nbsp;
          发表时间: 2007年06月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一般来说，我们使用Apache VFS时，直接从VFS对象获得的文件管理器是<strong>StandardFileSystemManager</strong>,StandardFileSystemManager从DefaultFileSystemManager继承而来。而解析文件在<strong>DefaultFileSystemManager</strong>中完成。<br />
绝大部分时候，你会提供一个URI来定位你的文件系统，例如：<strong>ftp://yourftp/rootdir或者http://yourweb/rootdi</strong>r或者file://c:/rootdir<br />
，然后你将这个字符串作为参数传给StandardFileSystemManger, 这时候DefaultFileSystemManger的<strong>resolveFile方法</strong>负责处理URI的解析，并且最终返回一个FileObject文件对象。我们看一下这个方法：<br />
这个方法有5种重载方式，分别接受不同的参数，但核心方法只有一个：<br />
<br />
/**<br />
&nbsp;&nbsp;&nbsp; &nbsp;* Resolves a URI, realtive to a base file with specified FileSystem<br />
&nbsp;&nbsp;&nbsp; &nbsp;* configuration<br />
&nbsp;&nbsp;&nbsp; &nbsp;*/<br />
&nbsp;&nbsp;&nbsp; public FileObject resolveFile(final FileObject baseFile, final String uri,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; final FileSystemOptions fileSystemOptions)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throws FileSystemException<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; final FileObject realBaseFile;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (baseFile != null &amp;&amp; VFS.isUriStyle()<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &amp;&amp; baseFile.getName().getType() == FileType.FILE)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; realBaseFile = baseFile.getParent();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; realBaseFile = baseFile;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // TODO: use resolveName and use this name to resolve the fileObject<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; UriParser.checkUriEncoding(uri);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (uri == null)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throw new IllegalArgumentException();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Extract the scheme<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; final String scheme = UriParser.extractScheme(uri);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (scheme != null)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // An absolute URI - locate the provider<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; final FileProvider provider = (FileProvider) providers.get(scheme);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (provider != null)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return provider.findFile(realBaseFile, uri, fileSystemOptions);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Otherwise, assume a local file<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Handle absolute file names<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (localFileProvider != null<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &amp;&amp; localFileProvider.isAbsoluteLocalName(uri))<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return localFileProvider.findLocalFile(uri);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (scheme != null)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // An unknown scheme - hand it to the default provider<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (defaultProvider == null)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throw new FileSystemException(&quot;vfs.impl/unknown-scheme.error&quot;,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; new Object[]<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; { scheme, uri });<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return defaultProvider.findFile(realBaseFile, uri,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fileSystemOptions);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Assume a relative name - use the supplied base file<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (realBaseFile == null)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throw new FileSystemException(&quot;vfs.impl/find-rel-file.error&quot;, uri);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return realBaseFile.resolveFile(uri);<br />
&nbsp;&nbsp;&nbsp; }<br />
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/92436#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 20 Jun 2007 16:09:01 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/92436</link>
        <guid>http://alartin.javaeye.com/blog/92436</guid>
      </item>
      <item>
        <title>Apache VFS(6): 几个重要的概念性接口</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/92412" style="color:red;">http://alartin.javaeye.com/blog/92412</a>&nbsp;
          发表时间: 2007年06月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          理解Apache VFS的概念性接口很重要，因为Apache VFS例子太少，如果不仔细研究的话，根本农不清楚：<br />
<br />
<strong>VfsComponent接口 </strong><br />
这个接口号称是用来管理所有VFS组件的生命周期的。方法比较简单：<br />
<ol>
    <li>init 用来初始化组件</li>
    <li>close 用来关闭组件</li>
    <li>setContext(VfsComponentContext ctx) 设置<strong>组件上下文</strong>，注意它维护了一个<strong>组件上下文：VfsComponentContext</strong></li>
    <li>setLogger 设置日志</li>
</ol>
有一个抽象类实现了这个接口<strong>AbstractVfsComponent</strong>抽象类，这个抽象类加了一个方法getContext()来获得组件上下文。AbstractVfsComponent抽象类很重要，有几个重要的类继承它：<br />
<ol>
    <li>AbstractFilesCache</li>
    <li>AbstractFileSystem</li>
    <li>AbstractVfsContainer</li>
    <li>DefaultFileReplicator</li>
</ol>
VfsComponentContext接口<br />
这个接口允许VFS组件访问他们需要的服务，例如<br />
<strong>FileReplicator接口<br />
</strong>这个接口的任务是创建文件的本地复制品。只有一个方法<strong>replicateFile(FileObject src, FileSelector sel)</strong>， 返回一个File对象。有两个类实现这个接口：<br />
<ol>
    <li>DefaultFileReplicator 一个简单的文件复制器和临时文件仓库，同时实现了FileReplicator接口，TemporaryFileStore接口和VfsComponent接口<br />
    </li>
    <li>PriviledgedFileReplicator 一个文件复制器的包装类，接受一个文件复制器作为参数。这个包装类能够执行某些需要权限的动作</li>
</ol>
<strong>TemporaryFileStore接口<br />
</strong>这个接口负责管理本地临时文件仓库，只有一个实现类，就是DefaultFileReplicator类。方法只有一个allocateFile(String basename) 接受一个字符串，返回一个File对象。这个方法将分配一个临时文件，当这个仓库关闭时，临时文件以及所有子文件被删除。<br />
<br />
<strong>FileProvider接口</strong><br />
每个FileProvider文件提供器负责处理特殊类型的URI模式，例如Ftp, Http等都有自己的文件提供器
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/92412#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 20 Jun 2007 14:33:28 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/92412</link>
        <guid>http://alartin.javaeye.com/blog/92412</guid>
      </item>
      <item>
        <title>Apache VFS (5): 使用它！</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/92332" style="color:red;">http://alartin.javaeye.com/blog/92332</a>&nbsp;
          发表时间: 2007年06月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          使用Apache VFS比较简单，第一个面对的对象是<strong>org.apache.commons.vfs.VFS对象</strong>。它有三个<strong>静态</strong>的方法：<br />
<ol>
    <li><strong>getManager </strong>这个方法最重要，将返回一个默认的<strong>FileSystemManager接口<br />
    </strong></li>
    <li>setUriStyle</li>
    <li>isUriStyle 判断是否是URI形式</li>
</ol>
<strong>FileSystemManager接口，文件系统管理器接口<br />
</strong>文件系统管理器负责一系列文件系统，通过文件系统使用名字来定位一个文件对象，定位方法是<strong>resolveFile()</strong>方法<br />
文件系统管理器可以识别多种类型的文件名：<br />
<ol>
    <li><strong>绝对的URI</strong>: 必须以协议Schema开始，例如<strong>file:,ftp:</strong>然后跟着文件名：file:/c:/temp.txt, ftp://myftp.org/somefile.txt等</li>
    <li><strong>绝对的本地文件名</strong>：例如/home/my.txt或C:\dir\file.txt, <strong>注意分隔符可以用&ldquo;\&quot;,也可以用&rdquo;/&quot;</strong>.</li>
    <li><strong>相对路径</strong>： 例如../dir/file.txt或者 home/myfile.txt等</li>
</ol>
<div id="dictdiv" style="margin: 5px; background: yellow none repeat scroll 0%; position: absolute; left: 0pt; top: 0pt; z-index: 1000; font-family: arial; font-size: 13px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; -moz-border-radius-bottomright: 5px; -moz-border-radius-bottomleft: 5px; opacity: 0.9; display: none;">&nbsp;</div>
<div id="dictaudio">&nbsp;</div>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/92332#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 20 Jun 2007 10:25:19 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/92332</link>
        <guid>http://alartin.javaeye.com/blog/92332</guid>
      </item>
      <item>
        <title>Apache VFS(4): 事件</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/92318" style="color:red;">http://alartin.javaeye.com/blog/92318</a>&nbsp;
          发表时间: 2007年06月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Apache VFS的事件只有文件改变事件，这个事件模型比较特别：<br />
<br />
<strong>org.apache.commons.vfs.FileChangeEvent类</strong>是顶层，也是具体类，只有一个方法：getFile(),返回触发事件的文件对象。<br />
<br />
<strong>org.apache.commons.vfs.events.AbstractFileChangeEvent抽象类</strong>继承了上述的FileChangeEvent具体类，增加了一个抽象方法：<strong>notify(FileListener listener)</strong>来通知监听器<br />
<br />
我们真正使用的有三个继承上述抽象类的具体类：<br />
<ol>
    <li>ChangedEvent</li>
    <li>CreatedEvent</li>
    <li>DeletedEvent</li>
</ol>
他们分别实现了上述抽象方法
<div id="dictdiv" style="margin: 5px; background: yellow none repeat scroll 0%; position: absolute; left: 0pt; top: 0pt; z-index: 1000; font-family: arial; font-size: 13px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; -moz-border-radius-bottomright: 5px; -moz-border-radius-bottomleft: 5px; opacity: 0.9; display: none;">&nbsp;</div>
<div id="dictaudio">&nbsp;</div>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/92318#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 20 Jun 2007 09:39:53 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/92318</link>
        <guid>http://alartin.javaeye.com/blog/92318</guid>
      </item>
      <item>
        <title>Apache VFS(3): 文件过滤器和选择器</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/92101" style="color:red;">http://alartin.javaeye.com/blog/92101</a>&nbsp;
          发表时间: 2007年06月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Apache VFS提供了<strong>FileFilter</strong>接口和<strong>FileSelector</strong>接口以及<strong>FileSelectInfo</strong>接口。这三个接口很容易让人摸不着头脑，都声称是<br />
遍历文件层次结构中用来选择文件的。只不过FileFilter说是直接的子文件 (direct children of the base)<br />
<br />
<strong>FileSelectInfo</strong><br />
只有三个方法：<br />
<ol>
    <li>getBaseFolder 返回遍历的根目录<br />
    </li>
    <li>getDepth 返回文件相对根目录(Base Folder)的深度<br />
    </li>
    <li>getFile 返回考虑的文件对象</li>
</ol>
<br />
<strong>FileFilter</strong><br />
FileFilter用来在遍历直接的子文件的过程中选择文件。只有一个方法: <strong>accept(FileSelectInfo info)</strong><br />
注意：使用<strong>FileSelectInfo对象作为参数</strong>。<br />
<br />
<strong>FileSelector<br />
</strong>只有两个方法,都使用<strong>FileSelectInfo对象作为参数</strong>：<br />
<ol>
    <li>includeFile(FileSelectInfo info) 判断是否这个文件或者目录应该被选择，这个方法使用深度优先，首先检查子文件(that is, it is called for the children  of a folder before it is called for the folder itself)</li>
    <li>traverseDescendents(FileSelectInfo info) 判断这个目录是否应该被遍历I，如果这个方法返回真的话，对每个这个目录的子文件都会调用includeFile(FileSelectInfo info)方法，并且每个子目录都递归遍历。对于一个目录，这个方法在includeFile方法调用之前调用。</li>
</ol>
<strong>FileSelector的实现类</strong><br />
Apache VFS 提供四个FileSelector实现类：<br />
<ol>
    <li>AllFileSelector 顾名思义，将选择所有文件<br />
    </li>
    <li>FileDepthSelector (int minDepth, int maxDepth) 选择特定深度的所有文件,以最小深度，最大深度为参数<br />
    </li>
    <li>FileFilterSelector 选择所有给定文件对象的子文件。和FileFilter非常象。（那还要这个干什么？？），可以接受一个FileFilter作为参数<br />
    </li>
    <li>FileTypeSelector (FileType type) 选择特定类型的文件。不要被这个迷惑! Apache VFS的文件类型FileType对象只有FILE,FILE_OR_FOLDER, FOLDER, FILE_IMAGINARY 四种类型。就是文件，目录，文件或目录， 尚不存在的文件。</li>
</ol>
<strong>例子<br />
</strong>&nbsp;比如我们的任务是从根目录中选择所有的以&ldquo;ABC－&rdquo;开头的文件， 根目录为&ldquo;/base/folder&quot;<br />
<br />
<br />
<strong>方法一：使用FileFilter:</strong><br />
<pre>FileFilter ff = new FileFilter()<br />{<br />    public boolean accept(FileSelectInfo fileInfo)<br />    {<br />        FileObject fo = fileInfo.getFile();<br />        return fo.getName().getBaseName().startsWith(&quot;ABC-&quot;);<br />    }<br />                <br />};<br />VFS.getManager().resolveFile(&quot;/base/folder&quot;).findFiles(new FileFilterSelector(ff));<br /><br /><strong>方法二：使用FileSelector:<br /><br /></strong>FileSelector ff = new FileSelector()<br />{<br />    public boolean includeFile(FileSelectInfo fileInfo) throws Exception<br />    {<br />        FileObject fo = fileInfo.getFile();<br />        return fo.getName().getBaseName().startsWith(&quot;ABC-&quot;);<br />    }<br /><br />    public boolean traverseDescendents(FileSelectInfo fileInfo) throws Exception<br />    {<br />        return true;<br />    }                   <br />};<br />VFS.getManager().resolveFile(&quot;/base/folder&quot;).findFiles(ff);</pre>
<div id="dictdiv" style="margin: 5px; background: yellow none repeat scroll 0% 50%; position: absolute; left: 0pt; top: 0pt; z-index: 1000; font-family: arial; font-size: 13px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; -moz-border-radius-bottomright: 5px; -moz-border-radius-bottomleft: 5px; opacity: 0.9; display: none;"> </div>
<div id="dictaudio"> </div>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/92101#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 19 Jun 2007 17:07:10 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/92101</link>
        <guid>http://alartin.javaeye.com/blog/92101</guid>
      </item>
      <item>
        <title>Apache VFS(2):文件的监听和监控</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/92084" style="color:red;">http://alartin.javaeye.com/blog/92084</a>&nbsp;
          发表时间: 2007年06月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Apache VFS有文件监听和监控功能。<br />
<br />
FileListener接口监听三种事件：<br />
<ul>
    <li>fileChanged(FileChangeEvent eve): 文件变化，只有使用了FileMonitor才触发</li>
    <li>fileCreated(FileChangeEvent eve): 文件创建</li>
    <li>fileDeleted(FileChangeEvent eve): 文件删除</li>
</ul>
FileChangeEvent很简单，只有一个方法getFile(),返回触发事件的FileObject对象。
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/92084#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 19 Jun 2007 16:00:13 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/92084</link>
        <guid>http://alartin.javaeye.com/blog/92084</guid>
      </item>
      <item>
        <title>Apache VFS(1)：基本介绍</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/92053" style="color:red;">http://alartin.javaeye.com/blog/92053</a>&nbsp;
          发表时间: 2007年06月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Apache VFS提供了一种虚拟文件系统，能够让你通过程序很方便的和位于本地文件系统，FTP文件系统，HTTP文件打交道。<br />
在Apache VFS中核心是<strong>FileObject接口</strong>。它代表一个文件，和Java File不同，它具有更多延伸的功能和信息。实现FileObject接口的文件对象有很多：例如AbstractFileObjet抽象类提供了部分FileObject实现。大部分FileObject实现类都继承AbstractFileObject类：<br />
<ol>
    <li>LocalFile:(很奇怪为什么不是LocalFileObject)</li>
    <li>FtpFileObject</li>
    <li>HttpFileObject</li>
    <li>SftpFileObject</li>
    <li>ZipFileObject</li>
    <li>TarFileObject</li>
    <li>RamFileObject</li>
    <li>UrlFileObject</li>
    <li>DelegateFileObject</li>
    <li>CompressedFileObject</li>
</ol>
FileObject代表一个文件，能够用来访问文件内容和结构。文件是以层次结构组织的，每个层次组织形成一个文件系统。一个文件系统就像本地操作系统中的文件系统一样，例如Windows文件系统，或者一个Http服务器，或者一个Zip文件包。<br />
<br />
文件有两种类型：<strong>目录</strong>和<strong>普通文件</strong>。普通文件拥有数据或者说内容，而目录不含有内容，只能包含其他文件，普通文件不能包含其他文件。<br />
<br />
<strong>文件名<br />
</strong>FileObject拥有一个FileName对象，将文件名字作为一个独立的对象处理。文件名是不可变的。文件名对象有很多方法：<br />
<ol>
    <li>getBaseName</li>
    <li>getDepth</li>
    <li>getExtension</li>
    <li>getFriendlyURI</li>
    <li>getParent</li>
    <li>getPath</li>
    <li>getRoot</li>
    <li>等等</li>
</ol>
<br />
<strong>文件内容的读取</strong><br />
注意：和Java File不同的是FileObject拥有一个<strong>FileContent对象</strong>，如果想访问文件内容的话，需要使用FileObject.getFileContent()方法，这个方法返回一个FileContent对象。FileContent代表一个文件的内容。<br />
简单的说读取文件内容使用：FileContent.<strong>getInputStream()</strong><br />
写内容使用：FileContent.<strong>getOutputStream()</strong><br />
FileContent内部有一个<strong>final AbstractFileObject</strong>的引用。<br />
<br />
FileContent的重要方法有：<br />
<ol>
    <li>close 关闭文件内容使用的所有资源，包括所有打开的文件流。<strong>当心！！</strong><br />
    </li>
    <li>get/set Attribute/Attributes: 不能用目前，除非自己重写，其实调用AbstractFileObject的doGet/SetAttribute方法<br />
    </li>
    <li>getContentInfo 返回一个<strong>ContentInfo对象</strong>, ContentInfo对象记录了内容的类型和编码信息<br />
    </li>
    <li>getInputStream 读文件内容</li>
    <li>getOutputStream 写文件内容</li>
    <li>isOpen 检查看看该文件有没有打开的文件流</li>
    <li>getFile 返回FileObject对象</li>
    <li>get/setLastModifiedTime</li>
</ol>
<br />
<strong>文件的操作</strong><br />
基本的文件操作例如创建，删除，重命名，拷贝都可以通过FileObject来完成。<br />
<ol>
    <li>copyFrom(FileObject src,FileSelector selector) 从其他地方的源文件拷贝到这个文件中，包括源文件的子文件，有一个文件选择器参数和源文件参数</li>
    <li>delete() 删除此文件</li>
    <li>delete(FileSelector selector) 删除符合文件选择器的所有该文件的子文件</li>
    <li>createFile() 如果这个文件不存在，创建它</li>
    <li>createFolder() 如果这个目录不存在，创建它</li>
</ol>
VFS为了支持高级的操作例如和版本控制工具配合，提供了FileOperation对象，不过VFS根本没有任何实现，如果你想玩，自己玩去吧。<br />
在这里批判一下VFS: VFS的开发有些地方非常不合理，例如FileObject号称支持对文件设置属性，后来发现其AbstractFileObject的getAttributes()方法只返回一个空Map,而setAttribute()更离谱，干脆直接抛出不支持的异常。这个功能非常简单啊，如果你需要的话，自己改一下吧。因此，使用VFS时，千万注意这些陷阱，谁让这是开源软件那 <strong>ON YOUR OWN RISK!</strong>
<div id="dictdiv" style="margin: 5px; background: yellow none repeat scroll 0% 50%; position: absolute; left: 0pt; top: 0pt; z-index: 1000; font-family: arial; font-size: 13px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; -moz-border-radius-bottomright: 5px; -moz-border-radius-bottomleft: 5px; opacity: 0.9; display: none;"> </div>
<div id="dictaudio"> </div>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/92053#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 19 Jun 2007 14:26:24 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/92053</link>
        <guid>http://alartin.javaeye.com/blog/92053</guid>
      </item>
      <item>
        <title>Netbeans平台的API: 数据系统（Datasystem API）</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/91591" style="color:red;">http://alartin.javaeye.com/blog/91591</a>&nbsp;
          发表时间: 2007年06月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Netbeans平台的数据系统是<strong>文件系统和面向文件操作之间的逻辑层</strong>，提供在<strong>文件对象</strong>(file object)之上的工作API,能够文件的逻辑处理：图标，名字，操作等等。例如Netbeans如何识别HTML文件，XML文件，Java源文件等，对于不同的文件/数据类型，Netbeans会以不同的方式处理，例如可以对Java源文件编译，可以对XML文件提供折叠显示等。Netbeans通过<strong>数据加载器DataLoader</strong>实现这个功能的， 基本流程是系统加载池 System Data Loader Pool负责扫描磁盘上的目录，过滤掉不相关的文件，然后依次询问在<strong>系统注册了的</strong>数据加载器是否对这个文件类型进行处理。<strong>第一个遇到的匹配的加载器</strong>负责处理该文件类型，它将为这个文件类型创建一个<strong>匹配的数据对象</strong>Data Ob ject，这个数据对象在Netbeans中负责这个文件类型。通过数据加载器，你能够将一些不同类型的文件聚集在一起形成组。例如可视化Swing可以识别app1.java, app1.form, app1.class将他们视为一组文件，这组文件能够共享一个数据对象，并且共享一组动作。在查看器窗口中，为这个数据对象只创建一个主节点。对于用户来说，他们只看到一个节点，因此不会将这些相关的文件隔离开，分别对待。而不相关的文件，例如测试输出文件，备份文件等，将不被考虑，直接滤除。<br />
<br />
注意，在Netbeans中，数据对象要比文件对象高一层次,而数据系统高于文件系统（这通常和我们的直觉相反）。因此，数据对象能够拥有一些文件对象没有的行为。这些行为是通过<strong>Cookie</strong>提供的(这里的Cookie和Web中的Cookie概念不同)。这样，数据对象能够通过拥有一个Cookie,从而和一个打开的编辑器相关联，或者数据对象能够作为一个模版供别人使用等等，或者当更名或者移除时进行一系列特定操作。通过数据加载器能够实现特定的伪文件，例如DataShadows.<br />
<br />
数据系统API包括三个包：<br />
<ol>
    <li>org.openide.loaders 负责处理文件，将他们关联到组，然后设置数据类型<br />
    </li>
    <li>org.openide.cookies 提供了一种设计模式，能够对数据对象和节点提供附加的行为<br />
    </li>
    <li>org.openide.util.datatransfer 实现了一些剪切版的扩展</li>
</ol>
<div id="dictdiv" style="margin: 5px; background: yellow none repeat scroll 0%; position: absolute; left: 0pt; top: 0pt; z-index: 1000; font-family: arial; font-size: 13px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; -moz-border-radius-bottomright: 5px; -moz-border-radius-bottomleft: 5px; opacity: 0.9; display: none;">&nbsp;</div>
<div id="dictaudio">&nbsp;</div>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/91591#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Jun 2007 14:07:08 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/91591</link>
        <guid>http://alartin.javaeye.com/blog/91591</guid>
      </item>
      <item>
        <title>Netbeans平台的API: 节点API(Node)</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/91556" style="color:red;">http://alartin.javaeye.com/blog/91556</a>&nbsp;
          发表时间: 2007年06月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Netbeans使用Node将JavaBeans或者其他具备属性的容器以树状的结构展现。Netbeans中有专门的Node包负责使用和创建节点，同时提供Cookies(以后会讲到)和动作，能够被查看器以树状结构显示。<br />
<ol>
    <li>什么是节点？可以说节点是<strong>任何Netbeans中的数据对象的包装器</strong>，这些对象通过节点来显示和执行任务（通过节点的动作），一般来说这些数据对象由<strong>数据系统接口</strong>（Datasystem API）提供。当然数据对象也可以根据特定需要单独创建。你看到的查看器中的图标，对话框，组件窗口都是基于节点的，他们通过查看器API显示。节点本身不存储数据，这个任务是由数据对象完成，节点仅仅是数据对象的表现层。实际上，节点是JavaBean概念的延伸。从开发完整的企业级应用来讲（例如Netbeans本身）JavaBean忽略了很多东西：完整的层次支持，Cookie和动作，节点特定的动作（例如序列化节点，剪切粘贴等），关键的一点是JavaBean需要自省机制，不管属性列表是否需要，都要自省，这带来严重的性能问题。而节点能够支持动态修饰属性列表。</li>
    <li>节点的显示。节点的显示是靠<strong>查看器API(</strong>Explorer API)的，通过查看器API，节点可以使用BeanTreeView, TreeView, MenuView, TreeTableView等形式来显示节点的整个树或者子树。在查看器中可以触发节点支持的动作（通常右键显示这些动作），基于Cookie的动作开关（例如节点的选择会影响工具栏某些工具是否可用，比如编译按钮），剪切复制等动作，以及对子节点的排序，创建，删除，以及节点图标名字的状态改变等等。</li>
    <li>节点是活的！最重要的是，节点是活的组件。在系统中发生的任何事件都可能让查看器中的视图更新，比如可视化Swing开发中，如果将一个组件拖到可视化开发面板中，那么相应的查看器中的组件树就会刷新，新的组件被加入到组件树中。同时任何查看器中发生的动作都可能影响系统，比如Netbeans全局配置查看器中如果改变了工具栏的配置，那么工具栏会立刻更新。而这一切都是通过节点接口的<strong>富事件通知机制</strong>（Rich Event Notification）实现的。</li>
    <li>常见的节点类型：</li>
</ol>
<ul>
    <li>基于数据对象的数据节点：</li>
    <li>数据目录节点：</li>
    <li>磁盘上用户自己开发的JavaBean:</li>
    <li>JavaBean衍生的节点：</li>
    <li>高级选项的设置节点</li>
    <li>组件窗口</li>
    <li>调试器中的断点</li>
    <li>项目桌面节点</li>
</ul>
节点的注意问题：<br />
<ol>
    <li>节点Node是抽象类,不是接口，具有两个子类：<strong>AbstractNode, FilterNode.</strong><br />
    </li>
    <li>AbstractNode<strong>不是抽象类！通常自定义的节点要继承AbstractNode或他的子类.</strong></li>
    <li><strong>自定义的节点要提供一个子节点列表给节点构造器，如果这个节点是叶节点，传参数Children.LEAF给构造器</strong></li>
    <li>从AbstractNode继承而来的自定义节点不需要覆盖或实现特定方法（AbstractNode不是抽象类），不过有几个方法通常需要覆盖：一些编辑方法例如AbstractNode.canCopy()等，他们默认的是true, 每个节点有两个名字，一个是显示名字，一个是内部系统名字，内部名字用来序列化和反序列化等使用。Node.setName(), Node.setDisplayName(). 还有节点的图片，例如展开时的节点图片等。</li>
    <li>节点的属性，集和表单</li>
</ol>
<br />
<div id="dictdiv" style="margin: 5px; background: yellow none repeat scroll 0% 50%; position: absolute; left: 0pt; top: 0pt; z-index: 1000; font-family: arial; font-size: 13px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; -moz-border-radius-bottomright: 5px; -moz-border-radius-bottomleft: 5px; opacity: 0.9; display: none;"> </div>
<div id="dictaudio"> </div>
          <br/>
          <span style="color:red;">
            <a href="http://alartin.javaeye.com/blog/91556#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Jun 2007 10:37:28 +0800</pubDate>
        <link>http://alartin.javaeye.com/blog/91556</link>
        <guid>http://alartin.javaeye.com/blog/91556</guid>
      </item>
      <item>
        <title>Netbeans平台的API们</title>
        <author>alartin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://alartin.javaeye.com">alartin</a>&nbsp;
          链接：<a href="http://alartin.javaeye.com/blog/91552" style="color:red;">http://alartin.javaeye.com/blog/91552</a>&nbsp;
          发表时间: 2007年06月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Netbeans平台上开发富客户端需要仔细研究他的API，这里简单梳理一下：<br />
<br />
<ul>
    <li><span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><font color="#ff0000"><font size="4"><strong><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-actions/overview-summary.html" target="classFrame">Actions APIs</a></strong></font> </font>-                                                                                     <!--Begin of first sentenece-->最重要的也是开发者必须使用的API,负责处理象表单和工具栏等上面的动作， 想一下Swing的Action.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-apache-tools-ant-module/overview-summary.html" target="classFrame">Ant</a> -Ant的整合API<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-project-ant/overview-summary.html" target="classFrame">Ant-Based Project Support</a> -如上                                                                                     <!--Begin of first sentenece-->                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><font size="4"><strong><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-autoupdate-services/overview-summary.html" target="classFrame">Auto Update Services</a></strong></font> - 自动更新支持，非常方便模块的更新和添加等。                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-classfile/overview-summary.html" target="classFrame">Classfile Reader</a> -                                                                                     <!--Begin of first sentenece-->访问类文件信息的API                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-sendopts/overview-summary.html" target="classFrame">Command Line Parsing API</a> -                                                                                     <!--Begin of first sentenece-->支持命令行的API                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-spi-palette/overview-summary.html" target="classFrame">Common Palette</a> -                                                                                     <!--Begin of first sentenece-->项目间共享的组件属性窗口                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-convertor/overview-summary.html" target="classFrame">Convertor</a> -                                                                                     <!--Begin of first sentenece-->XML和对象间的转换器                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-db/overview-summary.html" target="classFrame">Database Explorer</a> -                                                                                     <!--Begin of first sentenece-->支持数据库查看器的API                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong><font size="4"><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-loaders/overview-summary.html" target="classFrame">Datasystems API</a></font> </strong>-                                                                                     <!--Begin of first sentenece--> 负责扫描目录中的文件，根据需要按照逻辑组成平台相关的结构                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-api-debugger/overview-summary.html" target="classFrame">Debugger Core API</a> -                                                                                     <!--Begin of first sentenece-->支持调试的API                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-spi-debugger-ui/overview-summary.html" target="classFrame">Debugger Core - UI</a> -                                                                                     <!--Begin of first sentenece-->调试界面API                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong><font size="4"><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-dialogs/overview-summary.html" target="classFrame">Dialogs API</a> </font></strong>-                                                                                     <!--Begin of first sentenece--> 负责对话框的API,例如事件通知等                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-diff/overview-summary.html" target="classFrame">Diff</a> -                                                                                     <!--Begin of first sentenece-->支持查看文件间的不同之处的API                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/overview-summary.html" target="classFrame">Editor Code Completion</a> -                                                                                     <!--Begin of first sentenece-->编辑器的代码补全API                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-fold/overview-summary.html" target="classFrame">Editor Code Folding</a> -                                                                                     <!--Begin of first sentenece-->编辑器的行折叠API                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-guards/overview-summary.html" target="classFrame">Editor Guarded Sections</a> -                                                                                     <!--Begin of first sentenece-->编辑器的代码保护API,例如可视化Swing的自动生成的代码不可编辑                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-lib/overview-summary.html" target="classFrame">Editor Library</a> - 编辑器中和平台无关的库文件API                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-lib2/overview-summary.html" target="classFrame">Editor Library 2</a> -同上                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor/overview-summary.html" target="classFrame">Editor Module</a> -                                                                                     <!--Begin of first sentenece-->提供整套方案（包括表单编辑，浏览，编译，调试）的编辑器模块T                         </span> </li>
    <li> <span style="background: rgb(224, 192, 192) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-settings-storage/overview-summary.html" target="classFrame">Editor Settings Storage</a> -                                                                                     <!--Begin of first sentenece-->     The module is an implementation of the      <strong>org.netbeans.modules.editor.settings</strong> providing a settings storage on the default filesystem<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(224, 192, 192) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-util/overview-summary.html" target="classFrame">Editor Utilities</a> -                                                                                     <!--Begin of first sentenece-->Editor Utilities module contains useful utility classes and methods used by other editor related modules<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-errorstripe-api/overview-summary.html" target="classFrame">Error Stripe API</a> -                                                                                     <!--Begin of first sentenece-->The Error Stripe shows an overview of important information of an edited source code<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-execution/overview-summary.html" target="classFrame">Execution API</a> -                                                                                     <!--Begin of first sentenece-->The IDE uses a small interface to describe the execution of Java-based classes together with arguments<!--<b>ExecutionAPI</b> controls the execution of user-level classes<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><font size="4"><strong><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-explorer/overview-summary.html" target="classFrame">Explorer &amp; Property Sheet API</a></strong></font> -                                                                                     <!--Begin of first sentenece-->      The      <strong>ExplorerAPI</strong> is build around Explorer - solely a user-interface device: it has no particular knowledge of the structure of the IDE<!--<b>NodesAPI</b> .
    A given Explorer instance will be some visual component (such as a Swing panel)
    displaying some representation of a subtree of the complete Node hierarchy;
    the topmost node being displayed is said to be the root of the Explorer.
    Be careful not to confuse the root of a particular Explorer instance, which is
    selected according to what the user wishes to see, with the root(s) of
    the entire Node hierarchy, which generally are fixed.
    <!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-project-libraries/overview-summary.html" target="classFrame">External Libraries</a> -                                                                                     <!--Begin of first sentenece-->Permits libraries to be defined, customized, and stored by the user for reuse in multiple projects<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-filesystems/overview-summary.html" target="classFrame"><font size="4"><strong>File System AP</strong></font>I</a> -                                                                                     <!--Begin of first sentenece-->The Filesystems API provides a common API to access files in a uniform manner<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-queries/overview-summary.html" target="classFrame">General Queries API</a> -                                                                                     <!--Begin of first sentenece-->General kinds of queries between modules<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-io/overview-summary.html" target="classFrame">I/O APIs</a> -                                                                                     <!--Begin of first sentenece-->The Input/Output API is a small API module which contains InputOutput and related interfaces used in driving the Output Window<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-j2ee-metadata/overview-summary.html" target="classFrame">Java EE Metadata</a> -                                                                                     <!--Begin of first sentenece-->The project provides a generic framework for accessing Java EE metadata models<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><font size="4"><strong><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-javahelp/overview-summary.html" target="classFrame">JavaHelp Integration</a></strong></font> -                                                                                     <!--Begin of first sentenece-->The JavaHelp integration API wraps the standard JavaHelp extension library<!--<b>JavaHelpIntegrationAPI</b>
    <!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-java-platform/overview-summary.html" target="classFrame">Java Platform</a> -                                                                                     <!--Begin of first sentenece-->Many Java-based project types need to be able to configure the version and location of Java to be used when building and running the project<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-java-project/overview-summary.html" target="classFrame">Java Project Support</a> -                                                                                     <!--Begin of first sentenece-->Provides support infrastructure for projects working with the Java language<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(224, 192, 192) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-java-j2seproject/overview-summary.html" target="classFrame">Java SE Projects</a> -                                                                                     <!--Begin of first sentenece-->Provides a project type for plain Java projects<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-java-source/overview-summary.html" target="classFrame">Java Source</a> -                                                                                     <!--Begin of first sentenece-->       XXX no answer for arch-what     <!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-api-java/overview-summary.html" target="classFrame">Java Support APIs</a> -                                                                                     <!--Begin of first sentenece-->Models basic aspects of the metadata surrounding Java source files, such as the classpath<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-api-debugger-jpda/overview-summary.html" target="classFrame">JPDA Debugger API</a> -                                                                                     <!--Begin of first sentenece-->The debuggerjpda/api (Debugger JPDA API) defines API for NetBeans Java Debugger<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-junit/overview-summary.html" target="classFrame">JUnit Tests</a> -                                                                                     <!--Begin of first sentenece-->The module makes creating, running and navigation between tests easier<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-lexer/overview-summary.html" target="classFrame">Lexer</a> -                                                                                     <!--Begin of first sentenece-->Lexer module provides token lists for various text inputs<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(224, 192, 192) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-swing-plaf/overview-summary.html" target="classFrame">Look &amp; Feel Customization Library</a> -                                                                                     <!--Begin of first sentenece-->The plaf library consists primarily of code that used to be in core<!--<b>PlafAPI</b>
    <!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-looks/overview-summary.html" target="classFrame">Looks</a> -                                                                                     <!--Begin of first sentenece-->Looks provides an SPI for converting arbitrary objects into displayable form<!--<b>LooksAPI</b>
    <!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(224, 192, 192) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-masterfs/overview-summary.html" target="classFrame">Master Filesystem</a> -                                                                                     <!--Begin of first sentenece-->MasterFileSystems is just implementation of FileSystem provided in standalone module including implementation of URLMapper that resolves file protocol and is responsible for conversion from URL into FileObject and vice versa<!--<b>MasterFileSystemAPI</b>
    <!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-mimelookup/overview-summary.html" target="classFrame">MIME Lookup API</a> -                                                                                     <!--Begin of first sentenece-->Each editor provides an EditorKit which controls the policy of specific MIME content type<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/overview-summary.html" target="classFrame">Module System API</a> -                                                                                     <!--Begin of first sentenece-->The Modules API lies at the core of NetBeans and describes how plug-in modules are added and managed<!--<b>ModulesAPI</b>
    <!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/overview-summary.html" target="classFrame">MultiView Windows</a> -                                                                                     <!--Begin of first sentenece-->Multi views are general mechanism for displaying several perspectives, or views of data, which will be used consistently across whole IDE window system<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-spi-navigator/overview-summary.html" target="classFrame">Navigator API</a> -                                                                                     <!--Begin of first sentenece-->    Navigator module is a base API module which provides:              A place for modules to show structure/outline of their documents      Ability for modules to show their view only when special document(node)      is active in the system      UI for switching between multiple views available for currently active document(node)      Coalescing of fast coming selected node changes to show content for       <!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(224, 192, 192) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-nbjunit/overview-summary.html" target="classFrame">NB JUnit</a> -                                                                                     <!--Begin of first sentenece-->Module contains NetBeans extension to JUnit<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><font size="4"><strong><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-nodes/overview-summary.html" target="classFrame">Nodes API</a></strong></font> -                                                                                     <!--Begin of first sentenece-->节点提供平台中对象的可视化工作，注意这里的节点远远超出Swing中节点的含义。                         </span> </li>
    <li> <span style="background: rgb(221, 204, 128) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-options-api/overview-summary.html" target="classFrame">Options Dialog and SPI</a> -                                                                                     <!--Begin of first sentenece-->This module contains implementation of Options Panel and simple SPI<!--<!--End of first sentenece-->.                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><font size="4"><strong><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-api-progress/overview-summary.html" target="classFrame">Progress API</a> </strong></font>-                                                                                     <!--Begin of first sentenece-->跟踪显示任务进度的API                         </span> </li>
    <li> <span style="background: rgb(255, 255, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-projectapi/overview-summary.html" target="classFrame">Project API</a> -                                                                           