//gui9.java -- gui9 sample, @CopyLeft by tsaiwn@cs.nctu.edu.tw
//package ...;  // 指定我這 class 的命名空間 namespace, 阿就是要放哪個目錄啦
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;  // URL
  // 注意要寫 public class 不然  Applet 有問題
public class gui9 extends MyApplet implements ActionListener {   // 我就是 Applet
   static final String MY_WEB = 
       "http://www.cs.nctu.edu.tw/~tsaiwn/oop/java/"  +        "03_sample_JavaPrograms/13_soundwin/";
   Panel ppp;    // 木板 (面板)
   Button bbb;   // 按鈕
   TextArea tt;    // 文字區
   TextField tx;   // 文字一列的欄
   JButton btGiGi;
   static boolean isApplication = false;  // 用來辨認是 Application or Applet

   public static void main(String gg[ ]) {     // Java 的主程式都這樣寫
       isApplication = true;
       JFrame f = new JFrame("Windows 2011");        // 開個窗 f
       f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
       // JFrame 可以設成按右上角的 X 會關窗, 這樣不必自己處理  WindowEvent !
       gui9 me = new gui9( );       // 模仿 Applet ..   // 生出自己 (class gui9 )
       me.init( );      // 因為 Applet 被生出後先做 init( );
       me.start( );     // ..    再做  start( )
       f.add(me, "Center");   // 把 Applet (me) 放入窗 f 內
       f.setSize(999, 520);   // Frame 是 Window, 用 BorderLayout
       f.setVisible(true);   // f.show( );
   } // main(

   void println(String fmt, Object... oo) { print(fmt+"\n", oo); }
   void print(String fmt, Object... oo){System.out.printf(fmt, oo); }
 
   public gui9( ) { 
       super( );   // 可以不寫
       println(" Now doing ...  gui9 constructor !");
   } // Constructor; 注意要寫 public 不然  Applet 有問題
   public void doSomething( ) {
       tx.addActionListener(this);  // 由"這" class 的 actionPerformed()處理
         // TextField 是在按下 ENTER 時觸發 ActionEvent
       tx.setForeground(Color.BLUE);
       tx.setFont(new Font("標楷體", Font.BOLD, 24) );  // 24x24
       // tx.setFocusable(false); /// false 使得無法 Focus, 滑鼠點也不行!
       ///
       String s = "" + tx.getText( ) ;  // 取得格子內目前字串
       int len = s.length( );  // 算出目前字串長度 
       tx.setCaretPosition(len);    ////////// NEW8  設游標到字串最右邊
       tx.requestFocus( );      //////////////  NEW7
   }
   public void start( ) {
       super.start( );
       println(" Now in start( ) ... ");
   }// start(
  /////////////////////////////
   public void init( ) {
      fetchImage( );  ////////// NEW 9   先抓好兩張江蕙照片備用
      ppp = new Panel( );  
      tx=new TextField("你可以在這打字", 38);
      bbb = new Button(" empty ");   // 這是當作看板 !
      bbb.setCursor( new Cursor(Cursor.HAND_CURSOR) ); // 出現"手"

      btGiGi =     // JButton , now is Global
          createButtonWithPicture("img/gigi.jpg", "這是按鈕喔");
      btGiGi.addActionListener( new Ghost( ) ); // see below class
      // btGiGi.setEnabled(false);  // 不准按這 

       // note that JLabel is in javax.swing.*
      labJiang =   new JLabel(jiangIcon);  // see MyApplet.java 
      labJiang.setText("猜猜我是誰");   /////// NEW 9
           // createLabelWithPicture("img/mypic.gif", "猜猜我是誰");  
      labJiang.addMouseListener( new Amigo( ) ); // anonymous object
   //
       ppp.setLayout( new BorderLayout( ) );
       ppp.add(labJiang, "West");    // 左 (江蕙)

       decoratePpp( );

       ppp.setSize(new Dimension(280,128));   // 好像沒有用ㄟ ?

       bbb.setFont(new Font("標楷體",36,36));
       bbb.addActionListener(this);

       setLayout(new BorderLayout( ) );  // change Layout Manager 擺設經理
         // 因為 Applet 是 Panel, 其 default Layout Manager 是 FlowLayout
          // 設為  BorderLayout 後就可以指定 東西南北中  五個方位 放入元件
       tt = new TextArea("Hahaha\n", 5,20,TextArea.SCROLLBARS_BOTH);
       add(ppp, "North");    /// ppp 放 我 (gui9,  是Applet)的 北邊
       add(tt, "Center");    /// tt 文字區塊 放 我 (gui9,  是Applet)的 正中間
       tt.setFont(new Font("Ariel",32,32));   // 字體大一些
       Panel pn = new Panel( ); 
       Panel ptt=new Panel( );
       Panel pOut = new Panel( ); 
       pOut.setLayout(new BorderLayout( ));   // 外匡面版用 BorderLayout
       pOut.add(pn, "South");  // pn 塞在  pOut 這 Panel 內 :-) 木板上再放木板!
       pOut.add(ptt,"North");  // pOut 內塞兩個 Panel : pn, ptt
       //  現在 pOut 木板上有兩塊木板:  ptt 上, 下面是 pn  (南)
       ptt.add(new Button("請在右邊打字: "));     // 放入 ptt
       ptt.add(tx);      // 依序 放入 ptt
      /// 再來, pn 這木板上 放入很多按鈕 ! 所以用 array 陣列 比較方便 !
       pn.setBackground(Color.yellow); 
       tx.setFont(new Font("標楷體",16,16));
       bt = new Button[98];  // 只會生出 98 個參考 (阿其實就是 C++ 的指標啦)
          // 上列生出 98 個 參考(Reference) 不會用很多記憶體 :-)
          // 實際上會生出幾個按鈕是由 bMsg.length 決定 (看下列)
       for(int i=1; i< bMsg.length; ++i) {     // 這樣寫是個好習慣!
                            // 因為你去改 bMsg 陣列增加元素也不用來改這裡  :-)
           bt[i] = new Button(bMsg[i]);   // 真正生出六個 Button (注意 0 故意不用)
           pn.add(bt[i]); bt[i].setFont(new Font("細明體",16,16));
                 // 注意上列是在做勞作 :-)  把按鈕加入 pn 木板 !
           bt[i].addActionListener(this);    // 請求監聽 "動作事件"(ActionEvent)
               // 注意上列是要求監聽 bb[i] 喔 !
       } // for int i
       add(pOut, "South");   // 把 pOut 塞入我(gui9)這個 Applet 南邊
       bt[3].setForeground(Color.red); 
       doSomething( );
       validate( );  //  做了一些對圖形元件 的動作記得要做這  validate( ); 
   } // init(

   private void decoratePpp( ) {
      btGiGi.setMinimumSize( new Dimension(58,58));
      btGiGi.setPreferredSize( new Dimension(218,198));   ///
      btGiGi.updateUI();
      btGiGi.setCursor( new Cursor(Cursor.HAND_CURSOR) );  // 出現"手"
    ///
       JPanel tmpPan = new JPanel( );
       tmpPan.setLayout( new BorderLayout( ) );
       tmpPan.add(btGiGi, "West"); // GiGi
    ///
       Panel p3= new Panel( new BorderLayout( ) );
         Panel p3Up = new Panel( );
          p3.add(p3Up, "North");   // 塞一些空間 :-)
         Panel p3Down = new Panel( );
          p3.add(p3Down, "South");
        p3.add(bbb, "Center");
      ///
       p3Down.setPreferredSize(new Dimension(200,98) );
       p3Up.setPreferredSize(new Dimension(200,38) );
      ////////////
       tmpPan.add(p3, "Center"); //
       tmpPan.setBackground( new Color(198, 0, 168) );
     //
       ppp.add(tmpPan, "Center");  //再把 tmpPan 塞入 ppp 木板Center但右邊沒東西
       //ppp.setSize(280, 120);    // 好像沒有用ㄟ ?
       ppp.setBackground(Color.pink);    // 背景色 粉紅
   } // private void decoratePpp(

   Button bt[ ];   // 宣告說 bt[ ]  是 Button 陣列 (array)
   String bMsg[ ] = {"000", "Bt001", "看另一個範例",
       "哈哈哈會讀書入", "bt西西", "BT五", "六六大順 囉", "Bye",
         "張三", "李四", "十全十美"    }; 
   int kk = 0;  // Global variable to this class

   public void paint(Graphics g) {
       System.out.println(" Paint kk = " + kk++);
       // do drawing something ...
       tx.requestFocus( );    /////////////////////// NEW 9
       validate( );  //
   } // paint(

  ////////   ======================================   ///////////////
   Color yyc[ ] = { Color.red, Color.blue, Color.green, Color.pink };
   int cid = 0;

   int rand( ) { return (int) (32768* Math.random( ) ); }

   public void actionPerformed(ActionEvent e) {
       Object who = e.getSource( );    // 誰被按了一下 ?
       String gg = "You press " + e.getActionCommand( );

       if(who == bbb) {   // 上方看板 (Button)
          cid =  (cid+1) % yyc.length;
          bbb.setForeground( yyc[cid] ); 
          repaint( );   //////////// NEW 9
          return;  // 不再做其他事
        }// if

       if(who == bt[7]) System.exit(0);
       if(who == bt[1]) ppp.setBackground(Color.red);
       if(who == bt[2]) openWebWindow( MY_WEB );
       if(who == bt[6]) {
           ppp.setBackground(Color.green);
           tt.append("如果 林志玲 來演講, 你會去聽嗎? "); 
       } // if  bt[6]  (六六大順按鈕)
       bbb.setLabel(gg);  tt.append(gg+"\n");
       //////
       if(who == bt[3]  || who == tx)  {    //////////////// NEW7
           tt.append("讀到 " + tx.getText( ) + "\n");
           ppp.setBackground(Color.gray);  }
       repaint( );  // 會偷叫 update(Graphics);
   } // actionPerformed( 

   public void update(Graphics g) {  // 只是看看何時會跑過來這
       System.out.println(" update ==> kk = " + kk++);
       super.update(g); //  叫用上層(super class)的 update( )
   } // update(  will called by repaint( )

   void openWebWindow(String web) {    // note different when in Application
       try {
          if(isApplication){  // utilize the Runtime exec function
             try {              // 注意格式, 因字串中含有 " 雙引號 "
                Runtime.getRuntime().exec(
                  "cmd /c \"start " + web +"\" " );
             } catch (Exception e95){  // try Win 95/98
                Runtime.getRuntime().exec(
                  "start " + web );   //Win95/98中 start 是內建
             }
          } else { // is Applet, we are in Browser, use showDocument( )
             URL url = new URL(web); 
             getAppletContext().showDocument(url, "_blank"); 
          }   // see AppletContext
                         // _blank means in New Window
       } catch (Exception e) {; }
   }
  // 故意新寫一個 inner class, 編譯後看看目錄內多出啥 class 檔案?
   class Ghost implements ActionListener { 
      public void actionPerformed(ActionEvent e) {
         Object who = e.getSource( );   // 誰被按了一下 ? 
         if(who == btGiGi) {   // 預留以後可能處理其他的 Action
            try {
               System.out.println("Laughing ...");
               playFile("img/laugh.au");  // make Laugh 大笑(Applet)
            } catch (Exception e2) {;}
         }//if
         repaint( );  //////// NEW 9
      }//actionPerformed(
   }  //class Ghost  // an inner class

 //////////// Another inner class
 //這個 Amigo 有能力處理部份 Mouse event
 class Amigo extends MouseAdapter {
    public void mouseEntered(MouseEvent e) {
        Object who = e.getSource( );   /* 查哪零件觸發 Mouse event? */
      ///
        if(who == labJiang) {
          jiangIcon.setImage(jiangImage2); labJiang.setText("江蕙啦");
          labJiang.updateUI( );
        }
        repaint( );      // it will call our paint( )
    } //mouseEntered(
    public void mouseExited(MouseEvent e) { 
        Object who = e.getSource( );   /* 查哪零件觸發 Mouse event? */
      ///
        if(who == labJiang) {
          jiangIcon.setImage(jiangImage);  labJiang.setText("我是誰");
          labJiang.updateUI( );
        }
        repaint( );     // it will call our paint( ) through update( )
        validate( );
    }  // mouseExited(
 } // class Amigo == means friend in spanish
 ///// end of inner class Amigo

  void fetchImage( ) {
      try {       // Application 中讀取 Image 方法與 Applet 中不同
         if(isApplication) {  
             // use my function newImage to load Image file
            jiangImage = newImageBoth(JH_PIC);   // fix Bug when in Jar 
         } else
            jiangImage = getImage(new URL( getCodeBase()+ JH_PIC)); 
         ///
         jiangImage2 = newImageBoth(JH_PIC2);  // fix Bug when in Jar
       // newImageBoth(String) is good for both Application and Applet
          // prepare to flip pic when mouse enters
      } catch (Exception e) { ; }
      jiangIcon = new ImageIcon(jiangImage); 
      labJiang =  new JLabel(jiangIcon);   //////// NEW 9
      labJiang.setVerticalTextPosition(0);
      labJiang.setHorizontalTextPosition(2);
  } //fetchImage(
   //JLabel labJiang;  // 因為要換照片必須放這
   Image jiangImage, jiangImage2;
   ImageIcon jiangIcon;
   JLabel labJiang;    // new JLabel("江蕙" );
   //// labJiang will use ImageIcon jiangIcon
   static final String JH_PIC = "img/mypic.gif";
   static final String JH_PIC2 = "img/mypic2.gif";
} // class gui9
