Swing應用程序框架API緒論

 

概述

本文檔是原型Swing應用程序框架的簡介,目標讀者是那些願意評論初始原型的的開發者。它既不是綜合的教程,也不是開發者指南,它只是通過示例引入框架主要特性的概觀。在檢查規格說明(javadoc)和實現之前,閱讀本材料是明智之舉。

目標

本API的目標是由原始的Java規格請求(JSR) JSR-296所定義, 它在2006年5月批准。 其整體目標是簡化構建Swing應用程序,讓桌面Java開發人員對此的工作也是直截了當的。通過提供一小組類,也叫“框架”來達到此目標。框架定義了對大多數桌面應用程序的共有的基礎設施:

  • 應用程序生命週期管理,特別是GUI的啓動和關閉。
  • 對資源管理和載入的支持,這些資源是字符串,格式化的消息,圖像,顏色,字體以及桌面應用程序共有的其他類型的資源。
  • 對動作定義,管理和綁定的支持,其中包含了異步運行的動作(在後臺運行)。
  • 持久化會話狀態:支持自動地,有選擇地保存應用程序一次運行到下次運行的GUI狀態。 比如頂層的窗口幾何位置。

框架API概述

框架應用程序建立Application基類的子類,它定義了應用程序的生命週期,特別是應用程序的啓動時所爲,關閉時所爲。當應用程序啓動時,建立這個子類的單個實例。ApplicationContext 單體支持Application類的子類。它提供對動作,資源,任務,對話狀態和存儲和其它對象和服務的訪問。它對應用程序來說是全局的。框架的整體結構可根據這兩個單體來描述.

 

SR-296架構:應用程序(Application),ApplicationContext 單體模式

免責聲明

這是初稿。在許多方面未完成,並且這裏所述的API的確在演進當中。它打算爲那些對框架API當前狀態好奇並能容忍其瑕疵的開發人員所作。我希望它將激發那種讓代碼和文檔下次修訂更好的建設性反饋來。

應用程序框架示例

對開發者來說,熟悉新的API最容易的方法是通過學習幾個示例。本節提供一系列示例增量式地展示許多API最爲重要的方面。每個示例的源代碼可在示例包中找到。

下面的示例節包含類它們依賴的框架類的簡單梗概。要獲得更完整的解釋,請參見下面主要章節,或者查詢javadoc規範。

基於Hello World的Application

爲了編寫應用程序,只需要做幾件事情:

  • 擴展Application 類並覆蓋startup方法。 startup方法應當建立和顯示應用程序初始的GUI。
  • 當應用程序退出時,當用戶關閉最頂層的窗口時,調用Application.exit()。這將導致應用程序讓exitListeners運行並最終運行Application.shudown().
  • 在main方法裏,調用Application.launch方法。這將構建並啓動在事件分派線程上的Application子類。

下列實例正是這樣做的。實際上基於SingleFrameApplication類這種應用程序非常簡單,因爲它處理應用程序JFrame的構建和配置。但是本例這個版本應當使得在SingleFrameApplication 類裏的“鉤子下面(under the hood)”發生的事情更加明瞭。

 

public class ApplicationExample1 extends Application {
    JFrame mainFrame 
= null;
    @Override 
protected void startup(String[] ignoreArgs) {
        JLabel label 
= new JLabel("Hello World", JLabel.CENTER);
        label.setFont(
new Font("LucidaSans", Font.PLAIN, 32));
        mainFrame 
= new JFrame(" Hello World ");
        mainFrame.add(label, BorderLayout.CENTER);
        mainFrame.addWindowListener(
new MainFrameListener());
        mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        mainFrame.pack();
        mainFrame.setLocationRelativeTo(
null);  // center the window
        mainFrame.setVisible(true);
    }
    
private class MainFrameListener extends WindowAdapter {
        
public void windowClosing(WindowEvent e) {
            exit(e);
        }
    }
    
public static void main(String[] args) {
        launch(ApplicationExample1.
class, args);
    }
}
    

 

如果運行ApplicationExample1,結果如下:

ApplicationExample1 (Hello World) 屏幕截圖

在此仍然存在許多(JFrame)樣板,因爲應用程序基類不能假定應用程序到底構建GUI的數量。下一個示例顯示了通過使用一個擴展Application 叫做SingleFrameApplication的類,如何更簡單地完成相同的工作。

基於Hello World的SingleFrameApplication

爲了建立只有一個主JFrame的應用程序,只要擴展SingleFrameApplication類即可。應用程序的子類應當覆蓋建立應用程序的主GUI面板的startup方法,然後建立,配置和顯示包含這個面板的JFrame。

 

public class SingleFrameExample1 extends SingleFrameApplication {
    
public void startup(String[] args) {
        JLabel label 
= new JLabel(" Hello World ");
        label.setFont(
new Font("LucidaSans", Font.PLAIN, 32));
        show(label);
    }
    
public static void main(String[] args) {
        launch(SingleFrameExample1.
class, args);
    }
}
    

 

儘管本例和前面的例子完全一致,但是建立和配置主JFrame的樣本文件是由SingleFrameApplication.show 方法處理的。SingleFrameApplication也負責打點一些其它的公共的生命週期雜務,比如載入資源和保存/恢復對話狀態。

帶有資源的SingleFrameApplication

在前面示例中,建立了帶有文字字符串的JLable。由用戶讀取的字符串應當本地化。爲了完成本地化,字符串應當從ResourceBundle載入。應用程序框架支持自動初始化從ResourceBundle資源載入的有名組件的特性。對“資源注入(resource injection)”的支持超出了字符串的範疇;數值的初始值,顏色,字體和大多數其它的公共桌面GUI類型都能夠用資源來定義。

這裏是前面例子的新版本。本例除了設置它的名稱之外,對JLabel沒作任何配置:

public class SingleFrameExample2 extends SingleFrameApplication {
    
public void startup(String[] args) {
        JLabel label 
= new JLabel();
        label.setName(
"label");
        show(label);
    }
    
public static void main(String[] args) {
        launch(SingleFrameExample2.
class, args);
    }
}

 
SingleFrameExample2的ResourceBundle是以相同名字的特性文件,它駐留在資源子包裏。文件中的資源定義了一個名叫"label"組件的初始值:

label.opaque = true
label.background = 0, 0, 0
label.foreground = 255, 255, 255
label.text = Hello World
label.font = Lucida-PLAIN-48
label.icon = earth.png

本例簡單演示了配置從ResourceBundle的組件。在實際應用程序裏,將使用很可能需要本地化的值的資源,有時是諸如顏色、字體那些和本地化值緊密相關的特性。通過用資源而不是用代碼定義,隔離依賴於像圖像文件之類的外部對象的組件特性也是有用的。這使得開發者比較容易理解應用程序外部資源依賴是什麼,並能簡化對系統的變化的處理。

如果運行SingleFrameExample2,那麼其效果如下:

SingleFrameExample2 (Hello World) 屏幕截圖

 

SingleFrameApplication.show方法使用ResourceMap的injectComponents方法初始化從應用程序的ResourceBundle載入的每個有名組件的特性。

退出應用程序

通過調用Applcaiton.exit方法,應用程序應當能順利退出。當關閉主JFrame時,SingleFrameApplication的職責所在。在實際的應用程序裏,確保用戶在關閉是真的希望退出經常是重要的。例如,可能希望詢問未保存的文檔或者未完成的事務處理。在exit()真的終止應用程序之前,通過調用canExit方法輪詢所有的exitListener。如果任何一個canExit方法返回false,退出過程將終止。否則,調用exitListener的willExit方法,並最終調用Appliciton 的shutdown方法。這些方法正是打理任何清掃工作的地方。

本例在下面正是用一個對話來詢問用戶確認退出的。

 

public class SingleFrameExample3 extends SingleFrameApplication {
    
public void startup(String[] args) {
        ExitListener maybeExit 
= new ExitListener() {
            
public boolean canExit(EventObject e) {
                
int option = JOptionPane.showConfirmDialog(null"Really Exit?");
                
return option == JOptionPane.YES_OPTION;
            }
            
public void willExit(EventObject e) { }
        };
        addExitListener(maybeExit);
        JButton button 
= new JButton();
        button.setName(
"button");
        button.setAction(
new ActionAdapter() {
                
public void actionPerformed(ActionEvent e) {
                    exit(e);
                }
            });
        show(button);
    }
    
public static void main(String[] args) {
        launch(SingleFrameExample3.
class, args);
    }
}

本例的ResourceBundle和前面相似,既然這樣還是配置了這個JButton。也增加了一個定義主JFrame的標題的資源。SingleFrameApplication命名它建立的JFrame爲"mainFrame"。

mainFrame.title = ExitListener Demo
button.background = 255, 255, 255
button.foreground = 0, 0, 0
button.text = Click to Exit
button.font = Lucida-PLAIN-48
button.icon = exit.png

如果運行SingleFrameExample3,單擊窗口的關閉按鈕或者按下巨大的“Click to Exit”按鈕嘗試退出,將提示操作者確認:

SingleFrameExample3 屏幕截圖

在本例裏,使用建立一個實現了javax.swing.Action的匿名類的實例的常規方法來設置按鈕的動作特性。動作對象的actionPerformed方法只是調用exit。應用程序框架則通過使用新的@Action標註從而建立動作對象的建立。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章