Dev Zone
偏执狂才能生存,人生/事业的路上需要再坚持一下
但是又怎么说得清坚持的结果,道得尽坚持的含义

  下午,试用了SkinLF(http://www.l2fprod.com),感觉非常好,程序的外观得到了很大的改善,还可以根据自己的需要随意调整得到自己想要的外观,但是要将SkinLF应用到Web Start中还有点问题。这是因为,web start使用到的资源必须包装成jar文件,以的形式定义到jnlp资源文件中,而SkinLF的外观配置文件是zip形式的。也许有人会说,把zip转化成jar文件就可以了。是的,想象中这应当是可以的,可是实际情况不是如此,你会发现使用ClassLoader.getResourceStream("themepack.jar")的时候返回了Null,SkinLookAndFeel.loadLookAndFeel()会异常Stream closed.

  调试之后发现,即使是在客户端,在Eclipse中运行的时候,如果不把themepack.jar定义到ClassPath中,也是无法加载的。

  我想这是一个普遍的问题,根据我的理解,如果其他资源,比如图片、xml文件、属性文件等等能够被加载,themepack.jar也应该被加载。事实上应该是这样,但是关键在于SkinLF需要采用ZipInputStream解析zip(jar)文件,这时情况就不一样了。具体的原因目前没有搞清楚。

  在网上找了半天,终于发现一个Open Source的组件:Rachel,使用它很轻易就可以解决上面提到的问题。

  Rachelhttp://rachel.sourceforge.net)是一个为解决Web start装载资源困难而开发的组件。它提供了两种方法解决资源装载问题。

     方法一,使用class://URL Handler。
      这个方法采用新的URL协议:class://从jar文件中获取资源。

     Step 1,注册新的URL Handler,以支持class://协议(protocal)。
     例子:java.net.URL.setURLStreamHandlerFactory( new RachelUrlFactory() );

     Step 2,采用class://协议构造URL,从jar文件中读取资源。
  语法:class:///
  例子:

class://test.LookAndFeelTest/themepack.zip
class://com.l2fprod.gui.plaf.skin.SkinLookAndFeel/themepack.zip


  注意:这里,是Rachel用来定义资源文件所在的jar的,后面的相对于jar中的根目录而言。上述例子中的jar的结构如下:

      test.jar:

      test
/LookAndFeelTest.class
      com
/l2fprod/gui/plaf/skin/SkinLookAndFeel.class
      themepack.zip
      images
/example.png
      html
/index.htm

  Step 3,采用java.net.URL获取资源。
      例子:

    URL url = new URL("class://test.LookAndFeelTest/themepack.zip");
    URL url 
= new URL("class://test.LookAndFeelTest/html/index.html");
    URL url 
= new URL("class://test.LookAndFeelTest/images/example.png");

    URL url 
= new URL("class://com.l2fprod.gui.plaf.skin.SkinLookAndFeel/themepack.zip");
    SkinLookAndFeel.setSkin( SkinLookAndFeel.loadThemePack(url) );

  方法二,在程序中嵌入多线程的,小型的http server。

  Step 1,把你的资源放到jar中。

  Step 2,在每一个jar中增加一个anchor class,帮组server定位资源所在的jar文件,这点类似于方法一class:///的的
  例子:

   public class CrossRefAnchor
   {
     
public CrossRefAnchor() {}
   }

  CrossRefAnchor没有任何的实际意义,只是为了帮组定义资源所在的jar。

  Step 3,为每一个包含资源的jar用ClassResourceLoader注册到WebResourceManager。
  例子:

   WebResourceManager roots = WebResourceManager.getInstance();
   roots.addResourceLoader( 
new ClassResourceLoader( CrossRefAnchor.class ) );
   roots.addResourceLoader( 
new ClassResourceLoader( JavaDocAnchor.class ) );

  Step 4,启动Server。
  例子:

   try
   {
     WebServer http 
= new WebServer( 7272, roots );
     http.start();
   }
   
catch( IOException e )
   {
     e.printStackTrace();
   }

  Step 5,采用URL从server获取资源。
  例子:

   URL crossRefUrl = new URL( "http://localhost:7272/crossref/index.html" );
   URL url 
= new URL( "http://localhost:7272/test.LookAndFeelTest/themepack.zip" );
   URL url 
= new URL( "http://localhost:7272/test.LookAndFeelTest/html/index.html" );
   URL url 
= new URL( "http://localhost:7272/test.LookAndFeelTest/images/example.png" );
posted on 2005-05-17 22:11 dev 阅读(1077) 评论(4)  编辑  收藏
Comments
  • # re: 使用Rachel轻松解决Web Start装载资源难的问题
    Dennis
    Posted @ 2005-05-18 12:05
    有更簡單的方法

    不是把 zip 取為 jar, 而是把 zip 放到 jar 內

    把 themepack.zip 再在外打包成一個只有一個檔案的 jar
    (放在主要程式的 jar 內也可, 但獨立放置更方便更新)

    例如
    themepack.jar
    \resource\themepack.zip

    themepack.jar
    \themepack.zip

    把 jar 放入 classpath (加到 webstart 的 jnlp 也可以)

    再使用 ClassLoader.getResourceStream("themepack.jar")
    或 ClassLoader.getResourceStream("/resource/themepack.jar")
    (跟據 themepack.jar 的內部路徑而定)

      回复  更多评论   
  • # re: 使用Rachel轻松解决Web Start装载资源难的问题
    jdev
    Posted @ 2005-05-18 13:24
    不行的,会异常,你可以试一下。  回复  更多评论   
  • # re: 使用Rachel轻松解决Web Start装载资源难的问题
    Dennis
    Posted @ 2005-05-18 16:06
    會嗎!?

    我只是把 zip 檔以一般 resource (e.g. *.properties, *.png) 的方式來做吧~?
    只是檔案會比較大吧!?

    (上面打錯了 path, jar 內的是 zip 才對)  回复  更多评论   
  • # re: 使用Rachel轻松解决Web Start装载资源难的问题
    jdev
    Posted @ 2005-05-18 18:38
    我做过测试,不行。特殊就特殊在是zip格式,SkinLF需要读取zip中的内容,也就是说需要采用ZipInputStream读取zip文件,读取的时候会异常,也许这是sun的一个bug。  回复  更多评论   

只有注册用户登录后才能发表评论。


网站导航: