這個 g99.zip 內有  Gui9.java 
此版本跟前面 gui8.java 類似, (幾乎一樣!)
只是多了滑鼠移到江蕙的照片上會有變化! 其他都沒改!

當然還是必須搭配我寫的 MyApplet.java, 
因為與照片有關的功能都是利用我寫在 MyApplet.java 內的函數!
 
所以必須 把 extends Applet 改為 extends MyApplet,
即使你只要寫 Application 也須 extends MyApplet,
不然你就要自己寫與照片有關的那些:-(  
請注意, 
   這程式仍是可同時當作 Application 和 Applet !
測試方法有四: 
(1)直接下達 java 命令執行 g99.zip:  
   java -jar g99.zip 
(2)做一個網頁含有以下這些句: 
   <applet code=Gui9 archive=g99.zip width=988 height=555>
   <PARAM name="MSG" value="Test 測試看看啦">
   </applet>  
  然後就可以測試該網頁了
(3)把 g99.zip 解壓縮, 然後執行 Gui9.class  
   javac Gui9.java     (會自動把 MyApplet.java 也編譯) 
   java Gui9 
(4)把 g99.zip 解壓縮後, 建立一個簡單網頁含有以下這句: 
   <applet code=Gui9 width=988 height=555>
   </applet>   
  然後就可以測試該網頁, 這與(2)只差了說 archive=g99.zip   
看到沒, 你可以先不用管 MyApplet 裡面寫那些甚麼碗糕,
阿就依樣畫葫蘆, 像我在 gui8.java 內這樣:  
       JLabel labMyPic =    // see MyApplet.java
          createLabelWithPicture("img/mypic.gif", "猜猜我是誰");  
這樣就生出一張有照片的 Label,
當然你要先把照片放在子目錄 img 之下!此例是 img/mypic.gif
認真的同學可以研究一下 MyApplet.java
看不太懂可以看看以下這兩個範例: (第一堂課就給大家了 :)

  http://www.cs.nctu.edu.tw/~tsaiwn/oop/java/03_sample_JavaPrograms/11_grid/
或是壓縮成 haha.jar  (注意與以前給的同名但不同喔!)的

 http://www.cs.nctu.edu.tw/~tsaiwn/oop/java/03_sample_JavaPrograms/12_gridjar/

和這個更好玩的:

http://www.cs.nctu.edu.tw/~tsaiwn/oop/java/03_sample_JavaPrograms/13_soundwin/
 
裡面都有Java程式碼原始檔, 
都可以當作 Application 與 Applet

以下是 Gui9.java 搭配 HTML
以下是 gui8.java 搭配 HTML

按這裡抓 g99.zip
按這裡抓 g88.zip


D:\jtest> linenum < Gui9.java  
   01 //Gui9.java -- Gui9 sample, @CopyLeft by tsaiwn@cs.nctu.edu.tw
   02 //Java 建議: class name 第一個字用大寫字母!
   03 //Java 建議: 函數與變數用小寫開頭, 常數(就是final的變數)用全部大寫字母
   04 //package ...;  // 指定我這 class 的命名空間 namespace, 阿就是要放哪個目錄啦
   05 import java.applet.*;
   06 import java.awt.*;
   07 import java.awt.event.*;
   08 import javax.swing.*;
   09 import java.net.*;  // URL
   10   // 注意要寫 public class 不然  Applet 有問題
   11 public class Gui9 extends MyApplet implements ActionListener {   // 我就是 Applet
   12    static final String MY_WEB = 
   13        "http://www.cs.nctu.edu.tw/~tsaiwn/oop/java/"  +
   14         "03_sample_JavaPrograms/13_soundwin/";
   15    Panel ppp;    // 木板 (面板)
   16    Button bbb;   // 按鈕
   17    TextArea tt;    // 文字區
   18    TextField tx;   // 文字一列的欄
   19    JButton btGiGi;
   20    static boolean isApplication = false;  // 用來辨認是 Application or Applet
   21 
   22    public static void main(String gg[ ]) {     // Java 的主程式都這樣寫
   23        isApplication = true;
   24        JFrame f = new JFrame("Windows 2011");        // 開個窗 f
   25        f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
   26        // JFrame 可以設成按右上角的 X 會關窗, 這樣不必自己處理  WindowEvent !
   27        Gui9 me = new Gui9( );       // 模仿 Applet ..   // 生出自己 (class Gui9 )
   28        me.init( );      // 因為 Applet 被生出後先做 init( );
   29        me.start( );     // ..    再做  start( )
   30        f.add(me, "Center");   // 把 Applet (me) 放入窗 f 內
   31        f.setSize(999, 520);   // Frame 是 Window, 用 BorderLayout
   32        f.setVisible(true);   // f.show( );
   33    } // main(
   34 
   35    void println(String fmt, Object... oo) { print(fmt+"\n", oo); }
   36    void print(String fmt, Object... oo){System.out.printf(fmt, oo); }
   37  
   38    public Gui9( ) { 
   39        super( );   // 可以不寫
   40        println(" Now doing ...  Gui9 constructor !");
   41    } // Constructor; 注意要寫 public 不然  Applet 有問題
   42    public void txSetting( ) {
   43        tx.addActionListener(this);  // 由"這" class 的 actionPerformed()處理
   44          // TextField 是在按下 ENTER 時觸發 ActionEvent
   45        tx.setForeground(Color.BLUE);
   46        tx.setFont(new Font("標楷體", Font.BOLD, 24) );  // 24x24
   47        // tx.setFocusable(false); /// false 使得無法 Focus, 滑鼠點也不行!
   48        ///
   49        String s = "" + tx.getText( ) ;  // 取得格子內目前字串
   50        int len = s.length( );  // 算出目前字串長度 
   51        tx.setCaretPosition(len);    ////////// NEW8  設游標到字串最右邊
   52        tx.requestFocus( );      //////////////  NEW7
   53    }
   54    public void start( ) {
   55        super.start( );
   56        println(" Now in start( ) ... kk = " + kk++);
   57        labJiang.setVerticalTextPosition(1);  // 上
   58        labJiang.setHorizontalTextPosition(0);  // 中間
   59    }// start(
   60   /////////////////////////////
   61    public void init( ) {
   62       fetchImage( );  ////////// NEW 9   先抓好兩張江蕙照片備用
   63       ppp = new Panel( );  
   64       tt = new TextArea("Hahaha\n", 5,20,TextArea.SCROLLBARS_BOTH);
   65       tx=new TextField("你可以在這打字", 38);
   66 
   67       bbb = new Button(" empty 按這裡看看");   // 這是當作看板 !
   68       bbb.setCursor( new Cursor(Cursor.HAND_CURSOR) ); // 出現"手"
   69 
   70       btGiGi =     // JButton , now is Global
   71           createButtonWithPicture("img/gigi.jpg", "這是按鈕喔");
   72       btGiGi.addActionListener( new Ghost( ) ); // see below class
   73       // btGiGi.setEnabled(false);  // 不准按這 
   74 
   75        // note that JLabel is in javax.swing.*
   76       labJiang =   new JLabel(jiangIcon);  // see MyApplet.java 
   77       labJiang.setText("猜猜我是誰");   /////// NEW 9
   78            // createLabelWithPicture("img/mypic.gif", "猜猜我是誰");  
   79       labJiang.addMouseListener( new Amigo( ) ); // anonymous object
   80    //
   81        ppp.setLayout( new BorderLayout( ) );
   82        ppp.add(labJiang, "West");    // 左 (江蕙)
   83 
   84        decoratePpp( );
   85 
   86        ppp.setSize(new Dimension(280,128));   // 好像沒有用ㄟ ?
   87 
   88        bbb.setFont(new Font("標楷體",Font.BOLD,36));
   89        bbb.addActionListener(this);
   90 
   91        setLayout(new BorderLayout( ) );  // change Layout Manager 擺設經理
   92          // 因為 Applet 是 Panel, 其 default Layout Manager 是 FlowLayout
   93           // 設為  BorderLayout 後就可以指定 東西南北中  五個方位 放入元件
   94 
   95        add(ppp, "North");    /// ppp 放 我 (Gui9,  是Applet)的 北邊
   96        add(tt, "Center");    /// tt 文字區塊 放 我 (Gui9,  是Applet)的 正中間
   97        tt.setFont(new Font("Ariel",2,32));   // 斜體, 字體大一些
   98        Panel pn = new Panel( ); 
   99        Panel ptt=new Panel( );
  100        Panel pOut = new Panel( ); 
  101 
  102        pOut.setLayout(new BorderLayout( ));   // 外匡面版用 BorderLayout
  103        pOut.add(pn, "South");  // pn 塞在  pOut 這 Panel 內 :-) 木板上再放木板!
  104        pOut.add(ptt,"North");  // pOut 內塞兩個 Panel : pn, ptt
  105        //  現在 pOut 木板上有兩塊木板:  ptt 上, 下面是 pn  (南)
  106 
  107        ptt.add(new JLabel("請在右邊打字: "));     // 放入 ptt
  108        ptt.add(tx);      // 依序 放入 ptt
  109       /// 再來, pn 這木板上 放入很多按鈕 ! 所以用 array 陣列 比較方便 !
  110        pn.setBackground(Color.yellow); 
  111        tx.setFont(new Font("標楷體",1,16));   // 1 == Font.BOLD
  112        bt = new Button[98];  // 只會生出 98 個參考 (阿其實就是 C++ 的指標啦)
  113           // 上列生出 98 個 參考(Reference) 不會用很多記憶體 :-)
  114           // 實際上會生出幾個按鈕是由 bMsg.length 決定 (看下列)
  115        for(int i=1; i< bMsg.length; ++i) {     // 這樣寫是個好習慣!
  116                             // 因為你去改 bMsg 陣列增加元素也不用來改這裡  :-)
  117            bt[i] = new Button(bMsg[i]);  // 真正生出六個 Button(注意 0故意不用)
  118            pn.add(bt[i]); bt[i].setFont(new Font("細明體",1,16));
  119                  // 注意上列是在做勞作 :-)  把按鈕加入 pn 木板 !
  120            bt[i].addActionListener(this);   // 請求監聽 "動作事件"(ActionEvent)
  121                // 注意上列是要求監聽 bb[i] 喔 !
  122        } // for int i
  123        add(pOut, "South");   // 把 pOut 塞入我(Gui9)這個 Applet 南邊
  124        bt[3].setForeground(Color.red); 
  125        bt[2].setForeground(Color.BLUE); 
  126        bt[2].setCursor( new Cursor(Cursor.HAND_CURSOR) ); // 出現"手"
  127        txSetting( );
  128        validate( );  //  做了一些對圖形元件 的動作記得要做這  validate( ); 
  129    } // init(
  130 
  131    private void decoratePpp( ) {
  132       btGiGi.setMinimumSize( new Dimension(58,58));
  133       btGiGi.setPreferredSize( new Dimension(218,198));   ///
  134       btGiGi.updateUI();
  135       btGiGi.setCursor( new Cursor(Cursor.HAND_CURSOR) );  // 出現"手"
  136     ///
  137        JPanel tmpPan = new JPanel( );
  138        tmpPan.setLayout( new BorderLayout( ) );
  139        tmpPan.add(btGiGi, "West"); // GiGi
  140     ///
  141        Panel p3= new Panel( new BorderLayout( ) );
  142          Panel p3Up = new Panel( );
  143           p3.add(p3Up, "North");   // 塞一些空間 :-)
  144          Panel p3Down = new Panel( );
  145           p3.add(p3Down, "South");
  146         p3.add(bbb, "Center");
  147       ///
  148        p3Down.setPreferredSize(new Dimension(200,98) );
  149        p3Up.setPreferredSize(new Dimension(200,38) );
  150       ////////////
  151        tmpPan.add(p3, "Center"); //
  152        tmpPan.setBackground( new Color(198, 0, 168) );
  153      //
  154        ppp.add(tmpPan, "Center"); //再把tmpPan塞入 ppp木板Center但右邊沒東西
  155        //ppp.setSize(280, 120);    // 好像沒有用ㄟ ?
  156        ppp.setBackground(Color.pink);    // 背景色 粉紅
  157    } // private void decoratePpp(
  158 
  159    Button bt[ ];   // 宣告說 bt[ ]  是 Button 陣列 (array)
  160    String bMsg[ ] = {"000", "Bt001", "看另一個範例",
  161        "哈哈哈會讀書入", "bt西西", "BT五", "六六大順 囉", "Bye",
  162          "張三", "李四", "十全十美"    }; 
  163    int kk = 0;  // Global variable to this class
  164 
  165    public void paint(Graphics g) {
  166        System.out.println(" Paint kk = " + kk++);
  167        // do drawing something ...
  168        tx.requestFocus( );    /////////////////////// NEW 9
  169        validate( );  //
  170    } // paint(
  171 
  172   ////////   ======================================   ///////////////
  173    Color yyc[ ] = { Color.red, Color.blue, Color.green, Color.pink };
  174    int cid = 0;
  175 
  176    int rand( ) { return (int) (32768* Math.random( ) ); }
  177 
  178    public void actionPerformed(ActionEvent e) {
  179        Object who = e.getSource( );    // 誰被按了一下 ?
  180        String gg = "You press " + e.getActionCommand( );
  181 
  182        if(who == bbb) {   // 上方看板 (Button)
  183           cid =  (cid+1) % yyc.length;
  184           bbb.setForeground( yyc[cid] ); 
  185           repaint( );   //////////// NEW 9
  186           return;  // 不再做其他事
  187         }// if
  188 
  189        if(who == bt[7]) System.exit(0);
  190        if(who == bt[1]) ppp.setBackground(Color.red);
  191        if(who == bt[2]) {  doOpenWin( ); return; }
  192 
  193        if(who == bt[6]) {
  194            ppp.setBackground(Color.green);
  195            tt.append("如果 林志玲 來演講, 你會去聽嗎? "); 
  196        } // if  bt[6]  (六六大順按鈕)
  197        bbb.setLabel(gg);  tt.append(gg+"\n");
  198        //////
  199        if(who == bt[3]  || who == tx)  {    //////////////// NEW7
  200            tt.append("讀到 " + tx.getText( ) + "\n");
  201            ppp.setBackground(Color.gray);  }
  202        repaint( );  // 會偷叫 update(Graphics);
  203    } // actionPerformed( 
  204 
  205    public void update(Graphics g) {  // 只是看看何時會跑過來這
  206        System.out.println(" update ==> kk = " + kk++);
  207        super.update(g); //  叫用上層(super class)的 update( )
  208    } // update(  will called by repaint( )
  209 
  210    void doOpenWin( ) {   // openWebWindow( MY_WEB );
  211        // new a Thread to do it 
  212        javax.swing.SwingUtilities.invokeLater(new Runnable( ) {
  213           public void run() {
  214              openWebWindow( MY_WEB );
  215              return;
  216           } // run(
  217        }); // javax...
  218    } // doOpenWin( 
  219 
  220    void openWebWindow(String web) {  // note different when in Application
  221        try {
  222           if(isApplication){  // utilize the Runtime exec function
  223              try {              // 注意格式, 因字串中含有 " 雙引號 "
  224                 Runtime.getRuntime().exec(
  225                   "cmd /c \"start " + web +"\" " );
  226              } catch (Exception e95){  // try Win 95/98
  227                 Runtime.getRuntime().exec(
  228                   "start " + web );   //Win95/98中 start 是內建
  229              }
  230           } else { // is Applet, we are in Browser, use showDocument( )
  231              URL url = new URL(web); 
  232              getAppletContext().showDocument(url, "_blank"); 
  233           }   // see AppletContext
  234                          // _blank means in New Window
  235        } catch (Exception e) {; }
  236    } // openWebWindow(  
  237 
  238   // 故意新寫一個 inner class, 編譯後看看目錄內多出啥 class 檔案?
  239    class Ghost implements ActionListener { 
  240       public void actionPerformed(ActionEvent e) {
  241          Object who = e.getSource( );   // 誰被按了一下 ? 
  242          if(who == btGiGi) {   // 預留以後可能處理其他的 Action
  243             try {
  244                System.out.println("Laughing ...");
  245                playFile("img/laugh.au");  // make Laugh 大笑(Applet)
  246             } catch (Exception e2) {;}
  247          }//if
  248          repaint( );  //////// NEW 9
  249       }//actionPerformed(
  250    }  //class Ghost  // an inner class 
  251 
  252  //////////// Another inner class
  253  //這個 Amigo 有能力處理部份 Mouse event
  254  class Amigo extends MouseAdapter {
  255     public void mouseEntered(MouseEvent e) {
  256         Object who = e.getSource( );   /* 查哪零件觸發 Mouse event? */
  257       ///
  258         if(who == labJiang) {
  259           jiangIcon.setImage(jiangImage2);
  260           labJiang.setText("江蕙啦");
  261           labJiang.updateUI( );
  262         }
  263         repaint( );      // it will call our paint( )
  264     } //mouseEntered(
  265     public void mouseExited(MouseEvent e) { 
  266         Object who = e.getSource( );   /* 查哪零件觸發 Mouse event? */
  267       ///
  268         if(who == labJiang) {
  269           jiangIcon.setImage(jiangImage);
  270           labJiang.setText("我是誰");
  271           labJiang.updateUI( );
  272         }
  273         repaint( );     // it will call our paint( ) through update( )
  274         validate( );
  275     }  // mouseExited(
  276  } // class Amigo == means friend in spanish
  277  ///// end of inner class Amigo 
  278 
  279   void fetchImage( ) {
  280       try {       // Application 中讀取 Image 方法與 Applet 中不同
  281          if(isApplication) {  
  282              // use my function newImage to load Image file
  283             jiangImage = newImageBoth(JH_PIC);   // fix Bug when in Jar 
  284          } else
  285             jiangImage = getImage(new URL( getCodeBase()+ JH_PIC)); 
  286          ///
  287          jiangImage2 = newImageBoth(JH_PIC2);  // fix Bug when in Jar
  288        // newImageBoth(String) is good for both Application and Applet
  289           // prepare to flip pic when mouse enters
  290       } catch (Exception e) { ; }
  291       jiangIcon = new ImageIcon(jiangImage); 
  292       labJiang =  new JLabel(jiangIcon);   //////// NEW 9
  293       labJiang.setVerticalTextPosition(0);
  294       labJiang.setHorizontalTextPosition(2);
  295   } //fetchImage(
  296    //JLabel labJiang;  // 因為要換照片必須放這
  297    Image jiangImage, jiangImage2;
  298    ImageIcon jiangIcon;
  299    JLabel labJiang;    // new JLabel("江蕙" );
  300    //// labJiang will use ImageIcon jiangIcon
  301    static final String JH_PIC = "img/mypic.gif";
  302    static final String JH_PIC2 = "img/mypic2.gif"; 
  303 } // class Gui9

D:\jtest>