目前,大部分系統(tǒng)用戶接口的開發(fā)都是和運(yùn)行平臺(tái)特性緊密相關(guān)的,這使得構(gòu)建跨平臺(tái)的系統(tǒng)非常費(fèi)時(shí)并大大增加了開發(fā)成本和風(fēng)險(xiǎn)。當(dāng)用戶希望把系統(tǒng)遷移到其它平臺(tái)比如 PDA 等手持設(shè)備時(shí),這個(gè)潛在問題會(huì)顯得更加突出,因?yàn)樾薷纳踔林匦聵?gòu)建系統(tǒng)往往需要巨大的額外花費(fèi)。盡管一些解決方案比如 JAVA 的 UI 庫(kù)已為廣大開發(fā)人員使用,但在開發(fā)跨平臺(tái)易用用戶接口時(shí),一種更精巧的輕量級(jí)方式顯得愈加迫切。XUL (XML User-interface Language - 基于XML的用戶接口語(yǔ)言)正是應(yīng)這種需要而出現(xiàn)的一個(gè)能更有效方便地開發(fā)跨平臺(tái)應(yīng)用用戶接口的新技術(shù)。
XUL (XML User-interface Language - 基于 XML 的用戶接口語(yǔ)言)是一種新的富客戶端(Rich Client)技術(shù),是 Mozilla 和 Firefox 的核心語(yǔ)言,是一種用來(lái)快速開發(fā)跨平臺(tái)用戶接口的新途徑。其實(shí)不難發(fā)現(xiàn)很多新出現(xiàn)的語(yǔ)言都是基于 XML 的,比如 FIXML(Financial Information Exchange ML 金融信息交互描述語(yǔ)言),ECML(Electronic Commerce ML 電子商務(wù)描述語(yǔ)言)等。XUL 也不例外,它完全遵循 XML 國(guó)際標(biāo)準(zhǔn),套用面向?qū)ο蟮恼f(shuō)法就是 XUL 繼承了 XML。任何能使用和解析 XML 的地方 XUL 都可以出現(xiàn)。
這是因?yàn)?XUL 和 Mozilla&Firefox 瀏覽器的"血緣關(guān)系"。Mozilla&Firefox 的出現(xiàn)和 XUL 是密不可分的,Mozilla&Firefox 本身就是基于并且用 XUL 開發(fā)的。目前所有用 XUL 開發(fā)的界面程序都必須通過 Mozilla&Firefox 瀏覽器訪問,而后者是跨平臺(tái)甚至可以運(yùn)行在手持設(shè)備 PDA上。這就注定了 XUL 跨平臺(tái)的優(yōu)越特性。
XUL 的易用性在于它非常簡(jiǎn)單易學(xué),因?yàn)?XUL 所需要的技術(shù)僅僅是 XML,JavaScript 和 CSS。只需要有基本的 html 網(wǎng)頁(yè)開發(fā)經(jīng)驗(yàn),要是開發(fā)過 JSP,ASP 乃至 Portlet,那就更能輕松掌握。當(dāng)然要實(shí)現(xiàn)非常復(fù)雜的功能還是需要一段時(shí)間的積累。
運(yùn)行基于 XUL 開發(fā)的應(yīng)用程序可以通過以下途徑訪問:
(1) 將 XUL 應(yīng)用程序運(yùn)行在 Web 服務(wù)器上,以普通 HTTP URL 的形式訪問。但這種方式會(huì)有很大的權(quán)限限制,因?yàn)檫@畢竟不是 XUL 作為富客戶端的典型特性。
(2) 讓用戶在 Web 頁(yè)面下載 XUL 應(yīng)用程序 Package,在客戶端本地安裝注冊(cè),通過 XUL 特有的 Chrome URL 方式運(yùn)行。這種則是 XUL 作為富客戶端的典型運(yùn)行方式。
需要注意的是 XUL 應(yīng)用程序只能通過 Mozilla&Firefox 訪問,也就說(shuō) Mozilla&Firefox 是所有 XUL 應(yīng)用程序的運(yùn)行平臺(tái)。
在全球化方面,由 XUL 構(gòu)建的用戶接口能通過其 Locale 和在線安裝更新機(jī)制,根據(jù)不同國(guó)家的 locale 信息改變顯示語(yǔ)言,很好地支持了全球化。
用 XUL 完成用戶接口開發(fā)后,需要把它和其他系統(tǒng)整合。XUL 能通過 Web Service 或在線安裝等方法,很好地和其它系統(tǒng)集成(例如目前流行的 J2EE 系統(tǒng))。我們甚至可以把簡(jiǎn)單的 XUL 用戶接口和普通 Html 和 JSP 一樣使用(盡管會(huì)有權(quán)限限制)。
作為用戶接口語(yǔ)言,XUL 提供了流行的圖形元素,這些通用的圖形組件可以滿足不同開發(fā)者的需求。這些組件包括輸入控制組件,工具欄,菜單,表格(普通和樹形),快捷鍵等。XUL 界面元素的特點(diǎn)是樸實(shí)易用。
下面就讓我們逐步解開 XUL 的神秘面紗吧!
上文已經(jīng)提到過運(yùn)行 XUL 應(yīng)用程序主要有兩種途徑:
1) 把 XUL 應(yīng)用程序運(yùn)行在 Web 服務(wù)器上,以普通 HTTP URL 的形式訪問,這種訪問會(huì)有很大的權(quán)限限制,例如:
2) 通過 XUL 的 Chrome URL(本文3.2有詳細(xì)介紹),在客戶端本地運(yùn)行訪問。具體又有兩種方式:
以瀏覽器方式訪問(請(qǐng)注意 URL 的特點(diǎn)):
以應(yīng)用程序形式訪問(從開始菜單-運(yùn)行窗口訪問,也可以創(chuàng)建桌面快捷方式):
下面這個(gè)例子展示了如何開發(fā)一個(gè)簡(jiǎn)單的 XUL 用戶接口:
界面效果圖:
對(duì)應(yīng)的源碼如下
從上面的代碼可以發(fā)現(xiàn) XUL 的編寫非常簡(jiǎn)單,聲明 DTD 實(shí)體,定義腳本函數(shù),然后就是定義主窗口元素。
<!DOCTYPE window [ <!ENTITY Sample "Add DTD Entity Declearation"> ]> |
是對(duì)XML DTD實(shí)體的聲明。
<window id="findfile-window" title="Find Files" orient="horizontal" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> </window> |
定義了主窗口<window>元素,所有其他界面元素的定義都包含在這里面。
<script> <![CDATA[ function sample(){ //Add your functions } ]]> </script> |
定義了JavaScript腳本函數(shù),負(fù)責(zé)對(duì)窗口事件的響應(yīng)并執(zhí)行相應(yīng)操作。
增加其他元素也非常簡(jiǎn)單,在主窗口上順序添加即可,詳細(xì)的元素列表和屬性請(qǐng)參考XUL元素列表
下面是一些XUL界面效果圖以供參考:
XUL 應(yīng)用程序架構(gòu)和 Eclipse 的插件(Plugin)結(jié)構(gòu)很相似,可以動(dòng)態(tài)加載組件。XUL 中每個(gè)功能組件相對(duì)獨(dú)立,以 Package 的形式存在(這里的 package 一般是 JAR 包以便下載安裝,也可以是普通的文件目錄)。在 Mozilla 或 Firefox 中,主要的功能組件都存放在"Mozilla&Firefox 安裝目錄/chrome"下。這個(gè)"chorme"目錄下有一個(gè)"chrome.rdf"和"installed-chrome.txt" 文件,"chrome.rdf"文件記錄了所有安裝組件(Package)的信息(包括存放路徑),"installed-chrome.txt"記錄了所有已安裝的組件列表和它們的訪問類型。因?yàn)?XUL 安裝程序會(huì)將路徑信息注冊(cè)到該"chrome.rdf"文件中,所以當(dāng)增加新的組件 Package 時(shí),你可以把它放在任何目錄下,甚至包括可以加載(mount)到本地文件系統(tǒng)的遠(yuǎn)程站點(diǎn)。
一個(gè)典型的XUL組件Package的目錄結(jié)構(gòu)如下:
Content 目錄
包含一些以".xul"為后綴的文件,它們定義了 XUL 界面窗口元素。另外還有定義了處理界面事件響應(yīng)以及負(fù)責(zé)和其它系統(tǒng)交互的 JavaScript 腳本文件,都是以".js"為文件后綴。需要注意的是 Content 目錄下可以有多個(gè) XUL 文件,但定義主窗口的 XUL 文件名必須和組件Package 名相同。
Skin 目錄
負(fù)責(zé)界面外觀的顯示細(xì)節(jié),比如色彩,圖片等。主要包含了 CSS 文件和圖片。這樣就可以獨(dú)立地修改界面外觀而不影響其功能。
Locales 目錄
存放和全球化相關(guān)的翻譯信息。每個(gè) locale 會(huì)有一個(gè)獨(dú)立的文件目錄,例如"en_US"(美國(guó)), "fr_FR"(法國(guó))等。這些子目錄下則存放了和各自 locale 相關(guān)的 DTD 和 property 文件。DTD 文件包含了 XML 實(shí)體聲明,這些實(shí)體的值用其對(duì)應(yīng)國(guó)家的語(yǔ)言表示,被 Content 目錄下的 XUL 文件引用并顯示在界面上。例如多國(guó)語(yǔ)言的快捷鍵和菜單的內(nèi)容等。Property 文件和 DTD 類似,不同的是它被腳本所使用。當(dāng)新增加一個(gè)語(yǔ)言時(shí),只需添加新的 locale 子目錄即可,無(wú)需任何額外的修改。
另外需要注意的是這三個(gè)目錄下都有一個(gè)"contents.rdf"文件,這是一個(gè)必須的配置文件,它定義了每個(gè)子目錄例如 Content 子目錄所屬的應(yīng)用程序 Package,相對(duì)路徑以及作者和版本號(hào)等信息。Mozilla&Firefox 就是用這些 contents.rdf 文件中的信息來(lái)安裝、注冊(cè)并運(yùn)行 XUL 應(yīng)用程序。
Chrome URL 是 XUL 或者說(shuō) Mozilla&Firefox 的訪問和注冊(cè)機(jī)制,所有在本地 Mozilla&Firefox 注冊(cè)安裝的應(yīng)用程序,都是用這種方式訪問的。以 Chrome URL 方式運(yùn)行的應(yīng)用程序能獲得廣泛的訪問權(quán)限。另一個(gè)優(yōu)點(diǎn)是用 Chrome URL 訪問時(shí),Mozilla 會(huì)自動(dòng)去上文提到的"chrome.rdf", "cintents.rdf"文件中尋找相關(guān)信息并將數(shù)據(jù)正確地返回。Chrome URL 本身是和物理路徑無(wú)關(guān)的,因此可以把新應(yīng)用程序安裝在任何目錄下。下面是一個(gè)具體的 Chrome URL 例子:
Chrome URL 語(yǔ)法是:chrome://<package name>/<part>/<file name>
這里的<package name>是應(yīng)用程序package名稱,<part>是指要訪問的子目錄,例如上文提到過的"Content","Skin","Locale",<file name>是對(duì)應(yīng)子目錄下的文件名??梢钥吹?Chrome URL 不包含任何物理路徑相關(guān)的信息,因?yàn)樵诎惭b新的應(yīng)用程序時(shí),所有信息(包括安裝路徑)都注冊(cè)到"chrome.rdf"和"installed-chrome.txt"文件中了。
以下是訪問 Mozilla 自帶組件的 Chrome URL 例子:
chrome://messenger/content/messenger.xul
chrome://navigator/skin/navigator.css
chrome://messenger/locale/messenger.dtd
另一種格式是例如:
chrome://navigator/content/
chrome://navigator/Skin/
chrome://navigator/Locale
當(dāng)應(yīng)用程序 Package 下的每個(gè)"Content","Skin"和"Locale"子目錄中都有一個(gè)和 Package名稱相同的文件時(shí)(例如"navigator.xul"," navigator.css"," navigator.dtd"),就可以用這種方式訪問,這樣用戶就只需知道應(yīng)用程序 Package 的名字即可。
3.3. XPCOM (Cross-platform Component Object Model)
到目前為止,我們已經(jīng)知道 XUL 能夠構(gòu)建各種復(fù)雜的用戶接口,并用 JavaScript 負(fù)責(zé)窗口的事件響應(yīng)。但如果我們想實(shí)現(xiàn)更復(fù)雜的功能,比如要求 XUL 應(yīng)用程序和獨(dú)立運(yùn)行的 Mail Server 交互,負(fù)責(zé)發(fā)送和收取信件,JavaScript 便顯得捉襟見肘了,XPCOM 便是擴(kuò)展 XUL 功能的途徑。
XPCOM 作為一個(gè)對(duì)象模型,也具備了基本的面向?qū)ο罄砟?。其中最重要的基本單位便是接口(Interface)和組件(Component)概念。每個(gè)接口(Interface)聲明了它所具備的功能和屬性,組件(Component)可以繼承多個(gè)接口,并實(shí)現(xiàn)這些接口中的所有功能。這樣做的目的是在公用接口中清楚地聲明一套 API,由組件(Component)根據(jù)需要加以組合和實(shí)現(xiàn),組件實(shí)現(xiàn)的改變不會(huì)對(duì)接口有任何地影響。
XUL本身已經(jīng)實(shí)現(xiàn)了很多組件(Component),XUL 組件列表上有詳細(xì)的說(shuō)明,我們可以在Mozilla&Firefox 平臺(tái)上直接使用這些功能。下面是一個(gè)使用 XPCOM 的例子:
例如需要對(duì)本地文件進(jìn)行操作,
- 首先獲得已經(jīng)實(shí)現(xiàn)了文件操作功能的組件:
var localFile = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsILocalFile);
請(qǐng)注意,這里的 Components本身也是一個(gè)組件,它負(fù)責(zé)其它組件的生成,查詢和管理。"@mozilla.org/file/local;1" 其實(shí)是 Mozilla 根據(jù)組件各自功能進(jìn)行分類的規(guī)則,從某種意義上也可以稱為命名空間。Components.interfaces.nsILocalFile 是我們所需要的具備文件操作功能的接口,最后我們通過 createInstangce() 函數(shù)得到了組件引用 localFile。 - 接下來(lái)可以用這個(gè)組件實(shí)現(xiàn)我們所需要的功能:
function deletFile(filePath){ var localFile = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsILocalFile); //定位文件或目錄路徑,filePath例如"/mozilla/ToRemove" localFile. initWithPath(filePath); //刪除該目錄所有 (true) 內(nèi)容 localFile.remove(true);
此外我們還可以開發(fā)并添加新的功能組件(Component),由于篇幅限制,先不作介紹,讀者可以參見 XPCOM。
3.4. XPI (Cross-platform Installation)
XPI (跨平臺(tái)安裝程序) 是一種非常靈活方便的下載安裝機(jī)制,只需將開發(fā)好的應(yīng)用程序 Package和 XPI 特定安裝腳本(install.js)這兩個(gè)文件壓縮到一個(gè)以".xpi"為后綴的文檔中,這樣一個(gè)簡(jiǎn)單的 XPI 安裝程序就完成了(注意:最好使用 Winzip 進(jìn)行壓縮,其他壓縮工具如 Winrar可能導(dǎo)致下載時(shí)無(wú)法讀取 XPI 包)。
下面是具體的步驟(假設(shè)要安裝的應(yīng)用程序名稱是"top"):
完成 install.js 安裝腳本:
//初始化,三個(gè)參數(shù)分別是應(yīng)用程序名稱,應(yīng)用程序索引,版本號(hào) initInstall("top", "top", "0.1"); //找到 Mozilla 安裝目錄下的"chrome"目錄。 var folder = getFolder("chrome"); //設(shè)置應(yīng)用程序安裝目錄即 Mozilla 安裝目錄下的 Chrome setPackageFolder(folder); //指定將安裝的應(yīng)用程序,如果應(yīng)用程序是目錄結(jié)構(gòu)則調(diào)用 addDirectory() 方法, //如果已打成 JAR 包的則調(diào)用 addFile() 方法, addDirectory("top"); //注冊(cè)應(yīng)用程序 top 的 Chrome URL,第一個(gè)參數(shù)是 Chrome 注冊(cè)類別(Content, Skin ,Locale) //第二個(gè)參數(shù)指明 contents.rdf 文件所在的目錄,contents.rdf 文件包含了 Chrome 注冊(cè)信息 //第三個(gè)參數(shù)是安裝完畢后 contents.rdf 文件所在目錄 registerChrome(Install.CONTENT|Install.DELAYED_CHROME, getFolder(folder, "content")); //如果還有 Skin 和 Locale 目錄,還要注冊(cè) Chrome Skin 和 Locale // registerChrome(Install.SKIN | Install.DELAYED_CHROME, //getFolder(folder, "skin")); // registerChrome(Install.LOCALE | Install.DELAYED_CHROME, //getFolder(folder, "locale")); //開始安裝注冊(cè)應(yīng)用程序,如果發(fā)現(xiàn)以上步驟有錯(cuò)誤還可以取消并退出安裝程序。 //getLastError() 方法返回最近出現(xiàn)的錯(cuò)誤信息。 if (0 == getLastError()){ performInstall(); }else{ cancelInstall();
}更新提供下載服務(wù)的 Web 頁(yè)面 首先在對(duì)應(yīng)的 Web 頁(yè)面上增加一個(gè)連接:
<a href="Install new XUL application!" onclick="install()"> Install new XUL application!</a>
然后為該頁(yè)面增加兩個(gè) Javascript 方法,內(nèi)容如下:
function install( ){ //設(shè)置參數(shù)-應(yīng)用程序名稱(top)和安裝程序名稱(top.xpi) var xpi={'top':'top.xpi'}; //啟動(dòng)安裝程序,并將作為參數(shù)傳入,callback 是安裝結(jié)束回調(diào)的方法名 InstallTrigger.install(xpi, callBack); } function callBack (name, result) {//安裝完成后 XPI 回調(diào)該方法。 if (result == 0) alert("Installation complete, please restart your browser."); else alert("Installation failed, Error - "+result); }
XPI 的在線安裝注冊(cè)可以概括為:
1) 編寫 install.js 安裝腳本,將應(yīng)用程序和 install.js 壓縮成以 .xpi 為后綴的包。
2) 更新提供下載服務(wù)的 Web 頁(yè)面,包括增加新的下載鏈接和腳本函數(shù)(如上文所述)。
3) 用戶在線點(diǎn)擊下載,XPI 安裝程序啟動(dòng),解壓 .xpi 安裝包,執(zhí)行 install.js
4) 新應(yīng)用程序安裝完畢,所有信息注冊(cè)到本地 Mozilla&Firefox Chrome 中。
5) 用戶重新啟動(dòng) Mozilla&Firefox, 在本地運(yùn)行新安裝的程序。
安裝過程如下:
點(diǎn)擊安裝鏈接
選擇安裝
安裝成功
以上只是一個(gè)非常簡(jiǎn)單的安裝樣例,XPI 提供了更多的方法來(lái)管理并保證整個(gè)安裝過程的順利進(jìn)行,比如記錄安裝日志,讀取操作系統(tǒng)信息,文件的解壓縮等等。更詳盡的功能請(qǐng)參考 XPI。
作為用戶接口的設(shè)計(jì)語(yǔ)言,支持全球化是一個(gè)非常重要的性能。而 XUL 本身的特點(diǎn)也很好的支持了全球化。XUL 中最方便的支持全球化的途徑便是利用 XML 實(shí)體引用機(jī)制(DTD Entities)。
我們都知道 XML 的實(shí)體機(jī)制的最大特點(diǎn)便是,"一處修改,多處呈現(xiàn)"。也就是說(shuō)只需要在定義實(shí)體的地方修改其內(nèi)容而不影響使用實(shí)體處的代碼。這就很好的支持了全球化,只要我們將接口上顯示的部分用 XML 實(shí)體抽取,統(tǒng)一地翻譯成多種語(yǔ)言。不同版本的應(yīng)用程序引用對(duì)應(yīng)國(guó)家的實(shí)體,這就實(shí)現(xiàn)了接口的多語(yǔ)言化。
下面是一個(gè)典型的支持多語(yǔ)言的 XUL 應(yīng)用:
英語(yǔ)版本的實(shí)體聲明:
<?xml version="1.0" encoding="UTF-8" ?> <?xml-stylesheet href="chrome://global/skin" type="text/css"?> <?xml-stylesheet href="./CalculateVolumetricWeight.css" type="text/css"?> <!DOCTYPE window [ <!ENTITY dp1 "Sometimes, large items with a light overall weight can be charged according to the space they take up on aircraft."> <!ENTITY dp2 "In these cases, Volumetric Weight,or dimensional (Dim) weight, is used to calculate the shipment cost."> <!ENTITY dp3 "It is recommended that you calculate the Volumetric Weight for every shipment that you send, and then compare"> <!ENTITY dp4 "this to its actual weight. The greater weight of the two is used to work out the price that we charge you."> <!ENTITY dp5 "International Volumetric Weights are calculated using the formula below:"> <!ENTITY dp6cm "Length * Width * Height in centimeters / 6000 = Volumetric Weight"> <!ENTITY dp6inch "Length * Width * Height in inches / 166 = Volumetric Weight"> <!ENTITY dp7 "Alternatively, please feel free to use our quick calculator below."> <!ENTITY title "Volumetric Weight Calculator"> <!ENTITY UnitOfMeasure "Unit of Measure"> <!ENTITY Cmskgs "Cms/kgs"> <!ENTITY InchesPounds "Inches/Pounds"> <!ENTITY Length "Length"> <!ENTITY Width "Width"> <!ENTITY Height "Height"> <!ENTITY VolumetricWeight "Volumetric Weight"> <!ENTITY Calculate "Calculate"> <!ENTITY Reset "Reset"> <!ENTITY errorLength "Invalid length format. Only positive integers are allowed. Please validate your input and try again."> <!ENTITY errorWidth "Invalid width format. Only positive integers are allowed. Please validate your input and try again."> <!ENTITY errorHeight "Invalid height format. Only positive integers are allowed. Please validate your input and try again."> <!ENTITY cm "cm"> <!ENTITY kg "kg"> <!ENTITY Inch "Inch"> <!ENTITY Pound "Pound"> ]> |
中文版本的實(shí)體聲明:
<?xml version="1.0" encoding="GBK" ?> <?xml-stylesheet href="chrome://global/skin" type="text/css"?> <?xml-stylesheet href="./CalculateVolumetricWeight.css" type="text/css"?> <!DOCTYPE window [ <!ENTITY dp1 "總重量較輕的大件物品可以根據(jù)其在飛機(jī)上占據(jù)的空間付費(fèi),在這個(gè)情況下, 體積重量將作為貨物運(yùn)費(fèi)的參考依據(jù)。"> <!ENTITY dp2 "建議您計(jì)算每件發(fā)送貨物的體積重量,并和實(shí)際數(shù)據(jù)比較。較大的體積重量 將作為您付費(fèi)的依據(jù)。"> <!ENTITY dp5 "國(guó)際標(biāo)體積準(zhǔn)重量計(jì)算公式如下:"> <!ENTITY dp6cm "長(zhǎng)度 * 寬度 * 高度 (單位厘米) / 6000 = 重量"> <!ENTITY dp6inch "長(zhǎng)度 * 寬度 * 高度 (單位英寸)/ 166 = 重量"> <!ENTITY dp7 "或者您可以使用下面的計(jì)算器實(shí)現(xiàn)快速計(jì)算。"> <!ENTITY title "體積重量計(jì)算器"> <!ENTITY UnitOfMeasure "度量單位"> <!ENTITY Cmskgs "厘米/千克"> <!ENTITY InchesPounds "英寸/磅"> <!ENTITY Length "長(zhǎng)"> <!ENTITY Width "寬"> <!ENTITY Height "高"> <!ENTITY VolumetricWeight "體積重量"> <!ENTITY Calculate "計(jì)算"> <!ENTITY Reset "重置"> <!ENTITY errorLength "長(zhǎng)度錯(cuò)誤! 只允許正數(shù), 請(qǐng)檢查并重新輸入!"> <!ENTITY errorWidth "寬度錯(cuò)誤! 只允許正數(shù), 請(qǐng)檢查并重新輸入!"> <!ENTITY errorHeight "高度錯(cuò)誤! 只允許正數(shù), 請(qǐng)檢查并重新輸入!"> <!ENTITY cm "厘米"> <!ENTITY kg "千克"> <!ENTITY Inch "英寸"> <!ENTITY Pound "磅"> ]> |
兩中語(yǔ)言版本中實(shí)體引用代碼是相同的,例如:
<row flex="1" id="row2"> <label value="&Length;" /> <textbox id="length" maxlength="6" /> <label id="unit1" value="&cm;" /> </row> <row flex="1" id="row3"> <label value="&Width;" /> <textbox id="width" maxlength="6" /> <label id="unit2" value="&cm;" /> </row> |
最后顯示的效果如下:
英語(yǔ)版本效果圖:
中文版本效果圖:
此外借助上文提到的 XPI 安裝程序,我們可以實(shí)現(xiàn)語(yǔ)言包的動(dòng)態(tài)下載,這使得增加新語(yǔ)言包非常容易,以下是一個(gè)簡(jiǎn)要的步驟:
1) 將新語(yǔ)言包的 XPI 安裝程序添加到 Web 頁(yè)面上。
2) 用戶選擇下載新語(yǔ)言包,XPI 安裝程序激活,并開始下載安裝和注冊(cè)。
3) 語(yǔ)言包安裝完畢,信息注冊(cè)到 Mozilla 的 Chrome.rdf 中。
4) 用戶重新啟動(dòng) XUL 應(yīng)用程序。
請(qǐng)注意,如果只是更新語(yǔ)言包,我們可以使用 XPI 的下面兩個(gè)方法:
Install.RegisterChrome(LOCALE,srcDir, xpiPath) ; InstallTrigger.installChrome(InstallTrigger.LOCALE,URL,Displayname); |
具體的安裝過程和 3.4 部分類似,就不再累述。
5. 用 Web Service 實(shí)現(xiàn) XUL 應(yīng)用程序和服務(wù)器的集成
XUL 的主要任務(wù)是構(gòu)建用戶接口,負(fù)責(zé)界面的顯示和事件響應(yīng)。為了增加其擴(kuò)展性,XUL 提供了一系列和其他系統(tǒng)的集成方法(包括 3.4 介紹的在線安裝),這里介紹一種比較典型而且比較流行的途徑 - Web Service。
XUL Web Service 調(diào)用的核心是 SOAP(Simple Object Access Protocol)。SOAP 是一種基于 XML的 Web Service 通訊協(xié)議。XUL 本身實(shí)現(xiàn)了 Web Service 相關(guān)的一系列組件(Components),具體 API 請(qǐng)參考 XUL Web Services。Mozilla1.0 以后的版本都包含了基于 SOAP 的 Web Service 操作組件,可以在 JavaScript 中直接使用(但必須得到安全訪問權(quán)限)。
請(qǐng)看下面的簡(jiǎn)單樣例:
將一個(gè)簡(jiǎn)單的學(xué)生學(xué)號(hào)查詢方法發(fā)布成 Web Service(RPC/Encode方式),函數(shù)如下:
public class Finder { public String findStudentName(String num) { int[] studentNums = { 1, 2, 3, 4, 5, 6 }; String[] studentNames = { "Jack", "Tony", "Evan", "Mike", "John", "Betty" }; int stuNum = Integer.parseInt(num); for (int i = 0; i < studentNums.length; i++) { if (studentNums[i] == stuNum) { System.out.println("Found the student: " + studentNames[i]); return studentNames[i]; } } return "No such student!"; } } |
相關(guān) WSDL 文件請(qǐng)參見附件列表:
執(zhí)行腳本如下(具體請(qǐng)參見附件列表):
<script> <![CDATA[ function find(){ //得到用戶輸入的檢索信息 var num = document.getElementById("num").value; //參數(shù)列表,Web Service 函數(shù)的 參數(shù)名/參數(shù)值 var p = new Array(); p[0] = new SOAPParameter(num,"num"); //得到腳本的跨平臺(tái)訪問安全權(quán)限 netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); //新的 SOAP 調(diào)用組件 var soapCall = new SOAPCall(); //Web Service 地址 soapCall.transportURI = "http://localhost:9080/xul_webservice/services/Finder"; //調(diào)用 Web Service soapCall.encode(0, "findStudentName", "http://string.xul", 0, null, p.length, p); //跟蹤返回結(jié)果 var returnObject = soapCall.invoke(); response = returnObject.getParameters(false, {}); alert("Return value: " + response[0].value); } ]]> </script> |
注:
- soapCall.transportURI = "http://localhost:9080/xul_webservice/services/Finder"; 在 wsdl 中為 <wsdlsoap:address location="http://localhost:9080/xul_webservice/services/Finder"/>
- encode 函數(shù)的參數(shù)分別為調(diào)用的 WebService 函數(shù)名,命名空間 URI,參數(shù)個(gè)數(shù),參數(shù)列表。
在 wsdl 中為:
<wsdl:definitions targetNamespace=http://string.xul <wsdl:operation name="findStudentName" parameterOrder="num"> |
- 本例 Web Service 構(gòu)建工具是 IBM WSAD5.1,僅供演示測(cè)試使用。
- 為了最簡(jiǎn)單地說(shuō)明 XUL 中 Web Service 調(diào)用,這里使用了本地服務(wù)器模式。如果要采用跨平臺(tái)模式測(cè)試,請(qǐng)用"about:config"訪問 Mozilla 或 Firefox,找到 "signed.applets.codebase_principal_support"選項(xiàng),確保其值為 true,這樣就關(guān)閉了Mozilla & Firefox 對(duì)跨平臺(tái)權(quán)限的限制。
成功調(diào)用界面如下:
XUL是一個(gè)充滿活力的嶄新技術(shù),對(duì)XUL的學(xué)習(xí)和研究伴隨著 Mozilla & Firefox 的誕生和發(fā)展。本文只是對(duì) XUL 的一個(gè)初步介紹,希望能起到穿針引線的作用,讓更多的朋友加入到這一領(lǐng)域,發(fā)掘 XUL 更深入,更強(qiáng)大的功能。
- 本文樣碼下載: XUL_Sample Code.zip
- XUL Forum
- XUL Tutorial
- Mozilla Developer
- Mozilla Web Service
- Create Applications with Mozilla
- XUL Programmer's Reference API