//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