我們經常都需要創建一個類,使其既可作為一個窗口調用,亦可作為一個程序片調用。為做到這一點,只需為程序片簡單地加入一個main()即可,令其在一個Frame(幀)裡構建程序片的一個實例。作為一個簡單的示例,下面讓我們來看看如何對Button2New.java作一番修改,使其能同時作為應用程序和程序片使用:
//: Button2NewB.java // An application and an applet import java.awt.*; import java.awt.event.*; // Must add this import java.applet.*; public class Button2NewB extends Applet { Button b1 = new Button("Button 1"), b2 = new Button("Button 2"); TextField t = new TextField(20); public void init() { b1.addActionListener(new B1()); b2.addActionListener(new B2()); add(b1); add(b2); add(t); } class B1 implements ActionListener { public void actionPerformed(ActionEvent e) { t.setText("Button 1"); } } class B2 implements ActionListener { public void actionPerformed(ActionEvent e) { t.setText("Button 2"); } } // To close the application: static class WL extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // A main() for the application: public static void main(String[] args) { Button2NewB applet = new Button2NewB(); Frame aFrame = new Frame("Button2NewB"); aFrame.addWindowListener(new WL()); aFrame.add(applet, BorderLayout.CENTER); aFrame.setSize(300,200); applet.init(); applet.start(); aFrame.setVisible(true); } } ///:~
內部類WL和main()方法是加入程序片的唯一兩個元素,程序片剩余的部分則原封未動。事實上,我們通常將WL類和main()方法做一結小的改進復制和粘貼到我們自己的程序片裡(請記住創建內部類時通常需要一個外部類來處理它,形成它靜態地消除這個需要)。我們可以看到在main()方法裡,程序片明確地初始化和開始,因為在這個例子裡浏覽器不能為我們有效地運行它。當然,這不會提供全部的浏覽器調用stop()和destroy()的行為,但對大多數的情況而言它都是可接受的。如果它變成一個麻煩,我們可以:
(1) 使程序片句柄為一個靜態類(以代替局部可變的main()),然後:
(2) 在我們調用System.exit()之前在WindowAdapter.windowClosing()中調用applet.stop()和applet.destroy()。
注意最後一行:
aFrame.setVisible(true);
這是Java 1.1 AWT的一個改變。show()方法不再被支持,而setVisible(true)則取代了show()方法。當我們在本章後面部分學習Java Beans時,這些表面上易於改變的方法將會變得更加的合理。
這個例子同樣被使用TextField修改而不是顯示到控制台或浏覽器狀態行上。在開發程序時有一個限制條件就是程序片和應用程序我們都必須根據它們的運行情況選擇輸入和輸出結構。
這裡展示了Java 1.1 AWT的其它小的新功能。我們不再需要去使用有錯誤傾向的利用字符串指定BorderLayout定位的方法。當我們增加一個元素到Java 1.1版的BorderLayout中時,我們可以這樣寫:
aFrame.add(applet, BorderLayout.CENTER);
我們對位置規定一個BorderLayout的常數,以使它能在編譯時被檢驗(而不是對老的結構悄悄地做不合適的事)。這是一個顯著的改善,並且將在這本書的余下部分大量地使用。
2. 將窗口接收器變成匿名類
任何一個接收器類都可作為一個匿名類執行,但這一直有個意外,那就是我們可能需要在其它場合使用它們的功能。但是,窗口接收器在這裡僅作為關閉應用程序窗口來使用,因此我們可以安全地制造一個匿名類。然後,main()中的下面這行代碼:
aFrame.addWindowListener(new WL());
會變成:
aFrame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });
這有一個優點就是它不需要其它的類名。我們必須對自己判斷是否它使代碼變得易於理解或者更難。不過,對本書余下部分而言,匿名內部類將通常被使用在窗口接收器中。
3. 將程序片封裝到JAR文件裡
一個重要的JAR應用就是完善程序片的裝載。在Java 1.0版中,人們傾向於試法將它們的代碼填入到單個的程序片類裡,因此客戶只需要單個的服務器就可適合下載程序片代碼。但這不僅使結果凌亂,難以閱讀(當然維護也然)程序,但類文件一直不能壓縮,因此下載從來沒有快過。
JAR文件將我們所有的被壓縮的類文件打包到一個單個兒的文件中,再被浏覽器下載。現在我們不需要創建一個糟糕的設計以最小化我們創建的類,並且用戶將得到更快地下載速度。
仔細想想上面的例子,這個例子看起來像Button2NewB,是一個單類,但事實上它包含三個內部類,因此共有四個。每當我們編譯程序,我會用這行代碼打包它到一個JAR文件:
jar cf Button2NewB.jar *.class
這是假定只有一個類文件在當前目錄中,其中之一來自Button2NewB.java(否則我們會得到特別的打包)。
現在我們可以創建一個使用新文件標簽來指定JAR文件的HTML頁,如下所示:
<head><title>Button2NewB Example Applet </title></head> <body> <applet code="Button2NewB.class" archive="Button2NewB.jar" width=200 height=150> </applet> </body>
與HTML文件中的程序片標記有關的其他任何內容都保持不變。