下午,試用了SkinLF(http://www.l2fprod.com),感覺非常好,程序的外觀得到了很大的改善,還可以根據(jù)自己的需要隨意調(diào)整得到自己想要的外觀,但是要將SkinLF應(yīng)用到Web Start中還有點問題。這是因為,web start使用到的資源必須包裝成jar文件,以的形式定義到j(luò)nlp資源文件中,而SkinLF的外觀配置文件是zip形式的。也許有人會說,把zip轉(zhuǎn)化成jar文件就可以了。是的,想象中這應(yīng)當(dāng)是可以的,可是實際情況不是如此,你會發(fā)現(xiàn)使用ClassLoader.getResourceStream("themepack.jar")的時候返回了Null,SkinLookAndFeel.loadLookAndFeel()會異常Stream closed.
調(diào)試之后發(fā)現(xiàn),即使是在客戶端,在Eclipse中運(yùn)行的時候,如果不把themepack.jar定義到ClassPath中,也是無法加載的。
我想這是一個普遍的問題,根據(jù)我的理解,如果其他資源,比如圖片、xml文件、屬性文件等等能夠被加載,themepack.jar也應(yīng)該被加載。事實上應(yīng)該是這樣,但是關(guān)鍵在于SkinLF需要采用ZipInputStream解析zip(jar)文件,這時情況就不一樣了。具體的原因目前沒有搞清楚。
在網(wǎng)上找了半天,終于發(fā)現(xiàn)一個Open Source的組件:Rachel,使用它很輕易就可以解決上面提到的問題。
Rachel(http://rachel.sourceforge.net)是一個為解決Web start裝載資源困難而開發(fā)的組件。它提供了兩種方法解決資源裝載問題。
方法一,使用class://URL Handler。
這個方法采用新的URL協(xié)議:class://從jar文件中獲取資源。
Step 1,注冊新的URL Handler,以支持class://協(xié)議(protocal)。
例子:java.net.URL.setURLStreamHandlerFactory( new RachelUrlFactory() );
Step 2,采用class://協(xié)議構(gòu)造URL,從jar文件中讀取資源。
語法:class:///
例子:
class://test.LookAndFeelTest/themepack.zip
class://com.l2fprod.gui.plaf.skin.SkinLookAndFeel/themepack.zip
注意:這里,是Rachel用來定義資源文件所在的jar的,后面的相對于jar中的根目錄而言。上述例子中的jar的結(jié)構(gòu)如下:
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,把你的資源放到j(luò)ar中。
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" );