//GiGiok3.java  --- @CopyLeft by tsaiwn@csie.nctu
// http://www.csie.nctu.edu.tw/~tsaiwn/course/java/...
package gigi;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
public class GiGiok3 {
       public static final String BN = "gigi/";  // "" BaseName
       public static final String ZOOM_FILE = "gigi/zoom-in.gif"; //OK2
     public static void main( String s[ ]) {
           new GiGiok3( );  //can NOT use non-static var in main( )
     } // main(
  // Java Application 一定要有 public static void main,
  // 但是 static member function 不能使用非 static 的東東
  // 所以一個好方法是: 把工作全寫到 constructor, 在 main 中只 new 自己
  //先準備好所有需要的零件: (各零件屬各自 class, 各有其 methods 可用)
      String myCursorName = BN+"mycursor.gif";    //後面還用 zoom-in.gif
      int xSize=380, ySize=280;   /* default size for f */
      Frame f = new Frame("Window 2011");    // GUI 程式都需要個 Frame 窗
      Panel p;  // 這個 板子(Panel)是要用來貼一些按鈕的
      Button n,b1,b2,b3,bq, big;    // 名稱最好取有意義的
      TextArea tx=   new TextArea("Hey 我愛 GiGi", 5,20,
               TextArea.SCROLLBARS_HORIZONTAL_ONLY);
      Dimension dim =     /* get the screen size 1024x768? */
           Toolkit.getDefaultToolkit( ).getScreenSize( );
   // 這些零件可立刻 new 出來, 也可稍後再 new 出來
   // 若要做的事不多, 寫在 Constructor 即可,
   // 否則, 可以寫一些 functions 方便在 Constructor 裡叫用
  /// @@@ 寫個 function to createMyOwnCursor 方便使用@@@
   Cursor createMyCursor(String fname)  throws IndexOutOfBoundsException {
      Toolkit tkt = Toolkit.getDefaultToolkit( );
      Image csrImg = tkt.getImage(fname);  //for application
       //Image csrImg = getImage(getCodeBase( ), fname); //for Applet
      return tkt.createCustomCursor(csrImg, new Point(1,1), "my cursor");
   }
   void layout( ) {   // 排列或貼圖, 安排各圖形元件
       b1=new Button("111");  b2=new Button("222");
       f.add(b1,BorderLayout.WEST);  f.add(b2,"East"); /* b1 左, b2 右邊*/
       // Layout 與做勞作類似, 順序隨你意思, 自己覺得方便就好
       // 接著我想先在 p 上貼 n, bq, big 三按鈕再貼到 Frame f 的南邊
       p = new Panel( ); n= new Button("HahaHehehe");
       p.add(n);  // 把 n 這 Button 貼到 p 裡面 (p用FlowLayout)
       bq=new Button("Quit");  p.add(bq);
       big=new Button("Bigger"); p.add(big);
       // 注意 Panel 的 default 擺設經理為 FlowLayout
       // 但 Frame 與 Window 的 default 擺設經理為 BorderLayout
       f.add(tx,"Center");  //文字 tx 擺Frame f中間
       f.add(p,BorderLayout.SOUTH);   /* panel p 放南邊*/
   }
   void init( ) {
       layout( ); /*先安排好各圖形元件 GUI component */
       f.setSize(xSize,ySize);    /* 設定 Frame f 的寬與高 */
       f.setLocation(100, 100);   /* 設定 Frame f 的左上角位置 */
       tx.append("\n=== ==== ====       TextArea tx=");
       tx.append(" new TextArea(\"Hey 我愛 GiGi\",  5,20,");
       tx.append(
            " TextArea.SCROLLBARS_HORIZONTAL_ONLY);\n");
       tx.append(
             "If  如果 GiGi 不漂亮, 你還會覺得她的歌好聽嗎?\n");
   }
   //==========================================
   public GiGiok3( ) {  // Constructor
       init( );   /* 上司管下司, 鋤頭管畚箕 :-) */
       b1.setCursor(new Cursor(Cursor.HAND_CURSOR) ); 
       bq.setCursor(new Cursor(Cursor.HAND_CURSOR) ); 
    /*** 在 b1, bq 這些 Button 上滑鼠游標為手型 ***/
       tx.setCursor(new Cursor(2) );  /* 猜猜看 tx 文字窗中游標會啥形狀 */
       Cursor myCsr = createMyCursor(myCursorName) ; 
       b2.setCursor(myCsr);   /*  use my own Cursor */
       big.setCursor(createMyCursor(ZOOM_FILE));  ///檔名直接寫是壞習慣
       bq.setBackground(new Color(38,38,38));
       bq.setForeground(Color.red);
       big.setForeground(new Color(255,0,0)); 
       n.setBackground(Color.green);
       Handler chang3 = new Handler( ); // 請一個外勞chang3
       n.addActionListener(chang3); //有事交給chang3
                                            // 的actionPerformed( )
       b1.addActionListener(chang3);  // 也要監聽 b1 的 Action event
       bq.addActionListener(chang3);
       big.addActionListener(chang3);
          b2.addActionListener(chang3);
          f.addWindowListener(chang3); // 注意要確定chang3有能力處理視窗事件
       Amigo lee4 = new Amigo( );  // 錢多再請個外勞
       b1.addMouseListener(lee4); // b1 上 Mouse event(滑鼠事件)交 lee4 處理
        // 要求監聽 b1 上 滑鼠 的 event 就要 b1.addMouseListener(有能力者);
        // 注意 lee4 和 chang3 的能力不同喔
       f.setVisible(true);  //f.show();  和 f.hide();是舊的寫法
   }
//an inner class to handle Window events and Action event
// inner class 的好處是它看得見 Global 變數, 不必傳參數就可以用
//這個 Handler 有能力處理部份 Window event, 以及 Action event
class Handler extends WindowAdapter implements ActionListener {
    public void windowClosing(WindowEvent e){
         f.dispose( );   //System.exit(0);
    } 
    public void actionPerformed(ActionEvent evt){
          if(evt.getSource( ) == n) {  
              n.setLabel(" 777 ");  n.setBackground(Color.red);
          } /*  evt...  == n  */
          if(evt.getSource( ) == b1) n.setLabel("Eleven");
          if(evt.getSource( ) == bq) System.exit(0);
          if(evt.getSource( ) == b2) {
                     n.setBackground(new Color(88,234,38)); //RGB
                     tx.append("\nYou press Button-2" ); }
          if(evt.getSource( ) == big) {   //increase window size
                xSize = (int) (xSize*1.2);
                if(xSize>dim.width) xSize= dim.width;
                ySize = (int) (ySize*1.2); 
                if(ySize>dim.height) ySize= dim.height;
                tx.append("\n"+xSize+ "," + ySize);
                f.setSize(xSize,ySize);   // resize the frame
         }
         f.validate( );  // so that Layout Manager do ...
    } /* actionPerformed */
} // end of Handler
// another inner class Amigo to handle Mouse events
//這個 Amigo 有能力處理部份 Mouse event
class Amigo extends MouseAdapter {
    public void mouseEntered(MouseEvent e){
         tx.append("\nMouse entered .. " );
         Object who = e.getSource( );   /* 查哪零件觸發 Mouse event? */
         Class what = who.getClass( ); /* Java 可以 dynamic type checking */
         tx.append( who.getClass( ).toString( ));
         String msg;
         if(what == (new Button()).getClass( ) ) //is Button
              msg = " "+((Button)who).getLabel( );  // 看手冊知道各有何method
         else if(what == (new Frame()).getClass( ) ) //is Frame
               msg = " "+((Frame)who).getTitle( );
         else msg = " "+((Component)who).getName( ); // 看手冊知道各有何method
         tx.append(msg);
    }
    public void mouseExited(MouseEvent e){   /*還沒寫 :-) */   }
} // Amigo == means friend in spanish
}
