在預設GUI外觀、列印和運行效能方面,Java平台一直在努力縮小本機應用程式和Java應用程式程式是之間的差距。隨著Java SE 6(代碼名為Mustang)的問世,一些新的功能又被加入,包括新的系統托盤功能,更好的列印支援和案頭API(java.awt.Desktop API),從而進一步縮小以上差距。本文中描述的這些新型案頭API允許Java應用程式與主機平台上的特定檔案類型的預設應用程式進行互動。為了更有效地描述這些API,本文還將向你展示一個簡單的應用程式範例DesktopDemo。
一、 案頭概述
這種新功能是由java.awt.Desktop類所提供的。這種API來源於JDesktop整合組件(JDIC)工程。該工程的目的是,使得基於Java技術的應用程式成為案頭平台上的"第一等公民",並實現與案頭API的無縫整合。具體地說,這種新型案頭API允許你的Java應用程式實現如下功能:
· 使用一個特定的統一資源標誌符(URI)啟動主機系統的預設瀏覽器
· 啟動主機系統的預設電子郵件用戶端
· 啟動特定的應用程式以開啟、編輯或列印與之相關聯的檔案
這些案頭API使用你的主機作業系統的檔案關聯以啟動與特定檔案類型相相關 App程式。例如,如果開放文檔文本(.odt)副檔名與OpenOffice書寫器應用程式相關聯,那麼你的Java應用程式就可以啟動OpenOffice書寫器以開啟、編輯或列印與這種關聯相關的檔案。根據你的主機系統的不同,不同的應用程式可能關聯不同的行為。
二、 運行DesktopDemo應用程式
DesktopDemo是一個簡單Java應用程式-它使用了Mustang的案頭API。該應用程式提供了一個主視窗,允許你實現如下三項功能:
1. 以一個特定的URI啟動預設瀏覽器。
2. 用一個郵件接收者啟動預設電子郵件用戶端。
3. 啟動一個相相關 App程式以開啟、編輯或列印檔案。
圖1顯示了這個使用者介面(UI)。
你可以通過下載應用程式原始碼及相關的JAR檔案來運行這個應用程式-把你的控制台的活動目錄改變為該應用程式工程的dist目錄,並且使用一個Mustang JDK執行下列命令:
java -jar DesktopDemo.jar
三、 確定是否支援Desktop API
在啟動瀏覽器、電子郵件用戶端或任何應用程式之前,DesktopDemo必須確定是否你的平台支援這種API。然而,DesktopDemo首先停用所有的圖形化的文本域和按鈕。在確定該平台支援它們之後它該程式才啟用這些圖形組件。
在執行個體化這些UI後,該應用程式的構造器快速停用這個應用程式的少數幾個組件,如下列代碼所示:
public DesktopDemo() {
//初始化所有的GUI組件.
initComponents();
// 停用啟動瀏覽器和電子郵件用戶端的按鈕
// 停用開啟,編輯和列印檔案的按鈕
disableActions();
...
}
/**
* 停用所有的圖形組件,直到我們瞭解
* 是否支援它們的功能.
*/
private void disableActions() {
txtBrowserURI.setEnabled(false);
btnLaunchBrowser.setEnabled(false);
txtMailTo.setEnabled(false);
btnLaunchEmail.setEnabled(false);
rbEdit.setEnabled(false);
rbOpen.setEnabled(false);
rbPrint.setEnabled(false);
txtFile.setEnabled(false);
btnLaunchApplication.setEnabled(false);
}
...
public javax.swing.JTextField txtBrowserURI;
public javax.swing.JButton btnLaunchBrowser;
public javax.swing.JTextField txtMailTo;
public javax.swing.JButton btnLaunchEmail;
public javax.swing.JRadioButton rbEdit;
public javax.swing.JRadioButton rbOpen;
public javax.swing.JRadioButton rbPrint;
public javax.swing.JTextField txtFile;
public javax.swing.JButton btnLaunchApplication; |
使用Desktop.isDesktopSupported()方法來確定是否案頭API可用。在Solaris作業系統和Linux平台上,這種API是依賴於Gnome庫的。如果這些庫不可用,那麼這個方法將返回false。在確定支援這種API(也就是說,isDesktopSupported()返回true)之後,該應用程式就可以使用靜態方法getDesktop()來檢索一個Desktop執行個體。
Desktop desktop = null;
//在使用更多的Desktop API前,首先檢查
//是否這種API為該特定主機上的特別的虛擬機器所支援。
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
... |
如果你的應用程式在調用getDesktop()之前不使用isDesktopSupported()進行API支援檢查,那麼它必須準備捕獲一個UnsupportedOperationException異常-當你的應用程式在一個不支援這種特性的平台上請求一個Desktop執行個體時將拋出這種異常。另外,如果你的應用程式運行於一種無鍵盤、滑鼠和監視器環境下,該getDesktop()方法將拋出一個java.awt.HeadlessException異常。
一旦檢索完畢,該Desktop執行個體即允許你的應用程式瀏覽、郵寄、開啟、編輯或甚至列印一個檔案或URI,但是只有在被檢索的Desktop執行個體支援這些活動的前提下才行。每個這些活動被稱為一個行為(Action),並且每一個行為被描述為一個Desktop.Action枚舉執行個體:
· BROWSE-描述主機的預設瀏覽器執行的一種瀏覽行為
· MAIL-描述主機的預設電子郵件用戶端執行的一種郵件行為
· OPEN-描述一種與開啟一特定的檔案類型相相關 App程式執行的開啟行為
· EDIT-描述一種與編輯一特定的檔案類型相相關 App程式執行的編輯表現方式
· PRINT-描述一種與列印一特定的檔案類型相相關 App程式執行的列印行為
在調用任何這些行為之前,一個應用程式必須確定是否該Desktop執行個體支援它們。這與確定是否一個Desktop執行個體可用是有所不同的。這個Desktop.isDesktopSupported()方法告訴你是否能夠建立一個執行個體。一旦獲得一個Desktop對象,你就可以查詢該對象來確定支援哪些特定類型的行為。如果該Desktop對象不支援特定的行為,或如果該案頭API本身並不被支援,那麼DesktopDemo簡單地停用那些受影響的圖形組件。2所示,在停用狀態下,不能使用這些組件來調用案頭特性。
通過使用一個新的Desktop執行個體,下列代碼檢查負責是否支援Desktop.Action並且啟用適當的圖形組件:
public DesktopDemo() {
...
//在使用更多的案頭API前,首先檢查
//是否這種API為該特定主機上的特別的虛擬機器所支援。
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
// 現在,啟用按鈕以實現被支援的行為
enableSupportedActions();
}
...
}
/**
*啟用在該主機上被支援的行為。
*這些行為有:開啟瀏覽器,
*開啟電子郵件用戶端,和使用它們相相關 App程式開啟,編輯與列印檔案。
*/
private void enableSupportedActions() {
if (desktop.isSupported(Desktop.Action.BROWSE)) {
txtBrowserURI.setEnabled(true);
btnLaunchBrowser.setEnabled(true);
}
if (desktop.isSupported(Desktop.Action.MAIL)) {
txtMailTo.setEnabled(true);
btnLaunchEmail.setEnabled(true);
}
if (desktop.isSupported(Desktop.Action.OPEN)) {
rbOpen.setEnabled(true);
}
if (desktop.isSupported(Desktop.Action.EDIT)) {
rbEdit.setEnabled(true);
}
if (desktop.isSupported(Desktop.Action.PRINT)) {
rbPrint.setEnabled(true);
}
if (rbEdit.isEnabled() || rbOpen.isEnabled() || rbPrint.isEnabled()) {
txtFile.setEnabled(true);
btnLaunchApplication.setEnabled(true);
}
} |
一旦該應用程式確定了被支援的行為,它即啟用適當的圖形組件。如果所有的組件都被啟用,那麼相應的UI應該看上去3所示。
四、 開啟瀏覽器
調用下列執行個體方法將開啟你的主機的預設瀏覽器:
| public void browse(URI uri) throws IOException |
因為僅當支援相關聯的Desktop.ActionDesktopDemo時,UI組件才被啟用,所以,在實際調用browse()方法之前,這個簡單的示範應用程式不需要進行行為支援檢查。然而,在每一種調用之前檢查行為支援在實際中將增加程式的健壯性:
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//啟動瀏覽器
...
} |
DesktopDemo把一個java.awt.event.ActionListener添加到每一個按鈕上。當被啟用時,"Launch Browser"按鈕通過它的ActionListener調用下列方法:
private void onLaunchBrowser(java.awt.event.ActionEvent evt) {
URI uri = null;
try {
uri = new URI(txtBrowserURI.getText());
desktop.browse(uri);
}
catch(IOException ioe) {
ioe.printStackTrace();
}
catch(URISyntaxException use) {
use.printStackTrace();
}
...
} |
這個browse()方法可能拋出各種類型的異常,這包括:當該URI為null時拋出一個NullPointerException異常;如果不支援BROWSE行為將拋出一個UnsupportedOperationException異常;如果不能發現或啟動一個預設的瀏覽器或應用程式則拋出一個IOException異常;如果一個安全管理器否定一次調用則拋出一個SecurityException異常。
然而,如果一切順利,那麼聽取器(Listener)將從圖4中相聯絡的文本域中檢索文本,建立一個URI並且調用browse()方法。上面的代碼將啟動你的系統的預設瀏覽器並且指示該瀏覽器裝載該URI,5所示。
圖4:使用一個特定URI啟動預設瀏覽器。
圖5:使用案頭API啟動預設瀏覽器。 |
五、 寄送電子郵件
如果支援該行為的話,該應用程式能夠啟動主機的預設電子郵件用戶端-通過調用這個Desktop執行個體方法:
public void mail(URI uri) throws IOException
DesktopDemo為"Launch Mail"按鈕提供了一個ActionListener。在這種情況中,該聽取器調用下列方法:
private void onLaunchMail(java.awt.event.ActionEvent evt) {
String mailTo = txtMailTo.getText();
URI uriMailTo = null;
try {
if (mailTo.length() > 0) {
uriMailTo = new URI("mailto", mailTo, null);
desktop.mail(uriMailTo);
} else {
desktop.mail();
}
}
catch(IOException ioe) {
ioe.printStackTrace();
}
catch(URISyntaxException use) {
use.printStackTrace();
}
...
} |
該onLaunchMail()方法從相關的文本域中檢索電子郵件接收者,並且在存在一位接收者時使用一種mailto模式的參數建立URI,然後調用mail()方法。這個mail()方法被重載,這樣你可以使用(或不使用)一個描述其mailto接收者的URI(見圖6)來調用這個方法。
圖6:使用一個電子郵件接收者啟動預設電子郵件用戶端。 |
當建立這個URI時,你可以使用多個電子郵件接收者。這個mailto模式支援CC,BCC,SUBJECT和BODY域。例如,可以使用下列文本來建立一個mailto URI:
mailto:duke@sun.com?SUBJECT=Happy New Year!&BODY=Happy New Year, Duke!
圖7顯示出相應的結果。
圖7:案頭API使用多個mailto參數啟動預設電子郵件用戶端。 |
當然,你也可以不使用參數來調用mail()。在這種情況中,你的電子郵件用戶端將啟動一個新的沒有指定接收者、主題或郵件內文的電子郵件視窗。
六、 開啟、編輯和列印檔案
Java應用程式可以分別使用一個Desktop對象的open(),edit()和print()方法來從與其相聯絡的應用程式中開啟,編輯和列印檔案(見圖8)。同樣,僅在該Desktop執行個體支援它們時,DesktopDemo才允許這些行為,因此在本應用程式環境下,不必再次進行這種支援檢查。
DesktopDemo中的每一個選項按鈕也都有它自己的ActionListener。在這種情況中,每一個選項按鈕都設定一個執行個體變數,以便描述最近選擇的按鈕的相關聯Desktop.Action:
Desktop.Action action;
private void onPrintAction(java.awt.event.ActionEvent evt) {
action = Desktop.Action.PRINT;
}
private void onEditAction(java.awt.event.ActionEvent evt) {
action = Desktop.Action.EDIT;
}
private void onOpenAction(java.awt.event.ActionEvent evt) {
action = Desktop.Action.OPEN;
} |
當你按下"Launch Default Application"按鈕時,它調用它自己的聽取器-這將調用下列方法:
private void onLaunchDefaultApplication(java.awt.event.ActionEvent evt) {
String fileName = txtFile.getText();
File file = new File(fileName);
try {
switch(action) {
case OPEN:
desktop.open(file);
break;
case EDIT:
desktop.edit(file);
break;
case PRINT:
desktop.print(file);
break;
}
}
catch (IOException ioe) {
ioe.printStackTrace();
}
...
} |
這個方法決定選擇哪個Desktop.Action並且調用適當的Desktop執行個體方法-open(),edit()或print()。每個方法都需要一個File參數-它被用於執行要求的行為。
有趣的是,不同的應用程式可以針對甚至相同的檔案類型上的這些不同的行為進行註冊。例如,可以使用OPEN行為啟動Firefox瀏覽器,使用EDIT行為啟動Emacs,甚至使用PRINT行為啟動另外不同的應用程式。你的主機案頭的關聯用來決定應該調用什麼樣的應用程式。
注意 使用Mustang中現有案頭API來操作案頭檔案關聯是不可能的,而且目前只能使用平台依賴的工具來建立或改變這些關聯。
七、 總結
案頭整合是Mustang的一個重要主題。Mustang支援這種主題的一種方式是提供一組java.awt.Desktop API。這種API允許Java應用程式啟動主機的預設瀏覽器和電子郵件用戶端。另外,Java應用程式能夠啟動與特定的檔案類型相相關 App程式以開啟,編輯和列印檔案。儘管Java應用程式不能操作,建立,或改變檔案關聯,但是這些案頭API確定允許Java應用程式啟動預設的相相關 App程式。
出處:天極 原文連結:http://soft.yesky.com/360/2408860.shtml