這個 gy66.zip 內有 Gui6.java
(比 gui5.java 多一個有照片的 Button,
且可播放聲音, 有考慮 Java Application 和 Applet)
是從之前給大家的 gui.java 修改的,
必須搭配我寫的 MyApplet.java,
因為要生出有照片的 Label(標籤),
用到了 MyApplet 內我寫的一段小程式,
所以必須 把 extends Applet 改為 extends MyApplet,
即使你只要寫 Application 也須 extends MyApplet,
不然你就要自己寫生出有照片的那段:-(
請注意, 這程式仍是可同時當作 Application 和 Applet !
測試方法有四:
(1)直接下達 java 命令執行 gy66.zip:
java -jar gy66.zip
(2)做一個網頁含有以下這句:
<applet code=Gui6 archive=gy66.zip width=766 height=555>
</applet>
然後就可以測試該網頁了
(3)把 gy66.zip 解壓縮, 然後執行 Gui6.class
javac Gui6.java (會自動把 MyApplet.java 也編譯)
java Gui6
(4)把 gy66.zip 解壓縮後, 建立一個簡單網頁含有以下這句:
<applet code=Gui6 width=766 height=555>
</applet>
然後就可以測試該網頁, 這與(2)只差了說 archive=gy66.zip
看到沒, 你可以先不用管 MyApplet 裡面寫那些甚麼碗糕,
阿就依樣畫葫蘆, 像我在 Gui6.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
D:\jtest> linenum < Gui6.java
01 //Gui6.java -- Gui6 sample, @CopyLeft by tsaiwn@cs.nctu.edu.tw
02 //這版本再多放 GiGi 照片的 Button, 按會 play 音效大笑聲 (see MyApplet.java)
03 //Java 建議: class 的第一個字要用大寫字母!
04 //Java 建議: 變數和函數用小寫開頭! 常數(final 的變數)全用大寫字母!
05 //package ...; // 指定我這 class 的命名空間 namespace, 阿就是要放哪個目錄啦
06 import java.applet.*;
07 import java.awt.*;
08 import java.awt.event.*;
09 import javax.swing.*;
10 import java.net.*; // URL
11 // 注意要寫 public class 不然 Applet 有問題
12 public class Gui6 extends MyApplet implements ActionListener { // 我就是 Applet
13 static final String MY_WEB =
14 "http://www.cs.nctu.edu.tw/~tsaiwn/oop/java/" +
15 "03_sample_JavaPrograms/13_soundwin/";
16 Panel ppp; // 木板 (面板)
17 Button bbb; // 按鈕
18 TextArea tt; // 文字區
19 TextField tx; // 文字一列的欄
20 JButton btGiGi;
21 static boolean isApplication = false; // 用來辨認是 Application or Applet
22
23 public static void main(String gg[ ]) { // Java 的主程式都這樣寫
24 isApplication = true;
25
26 JFrame f = new JFrame("Windows 2011"); // 開個窗 f
27 f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
28 // JFrame 可以設成按右上角的 X 會關窗, 這樣不必自己處理 WindowEvent !
29 Gui6 me = new Gui6( ); // 模仿 Applet .. // 生出自己 (class Gui6)
30 me.init( ); // 因為 Applet 被生出後先做 init( );
31 me.start( ); // .. 再做 start( )
32 f.add(me, "Center"); // 把 Applet (me) 放入窗 f 內
33 f.setSize(680, 520); // Frame 是 Window, 用 BorderLayout
34 f.setVisible(true); // f.show( );
35 } // main(
36
37 static void println(String fmt, Object... oo) { print(fmt+"\n", oo); }
38 static void print(String fmt, Object... oo){System.out.printf(fmt, oo); }
39 static void printf(String fmt, Object... oo){System.out.printf(fmt, oo); }
40 static int rand( ) { return (int) (32768* Math.random( ) ); }
41 static void srand( int x) { return; }
42
43 public Gui6( ) {
44 super( ); // 可以不寫
45 println(" Now doing ... Gui6 constructor !");
46 } // Constructor; 注意要寫 public 不然 Applet 有問題
47 public void start( ) {
48 super.start( );
49 println(" Now in start( ) ... ");
50 }// start(
51 /////////////////////////////
52 public void init( ) {
53 ppp = new Panel( );
54 tt = new TextArea("Hahaha\n", 5,20,TextArea.SCROLLBARS_BOTH);
55 tx=new TextField("你可以在這打字", 38);
56 tx.setCaretPosition(32767); // 沒那麼多字吧!
57 tx.addActionListener(this); // 由"這" class 的 actionPerformed()處理
58 // TextField 是在按下 ENTER 時觸發 ActionEvent
59 tx.setForeground(Color.BLUE);
60 tx.setFont(new Font("標楷體", Font.BOLD, 24) ); // 24x24
61
62 // note that JLabel is in javax.swing.*
63 JLabel labJiang = // see MyApplet.java // JLabel
64 createLabelWithPicture("img/mypic.gif", "猜猜我是誰");
65 //
66 btGiGi = // JButton , now is Global
67 createButtonWithPicture("img/gigi.jpg", "這是按鈕喔");
68 btGiGi.addActionListener( new Ghost( ) ); // see below class
69
70 // btGiGi.setEnabled(false); // 不准按這
71 btGiGi.setMinimumSize( new Dimension(58,58));
72 btGiGi.setPreferredSize( new Dimension(218,198));
73 //btGiGi.setSize(168,158);
74 btGiGi.updateUI();
75 btGiGi.setCursor( new Cursor(Cursor.HAND_CURSOR) ); // 出現"手"
76 // btGiGi.add???Listener( ???
77 //////
78 ppp.setLayout( new BorderLayout( ) );
79 ppp.add(labJiang, "West"); // 左 (江蕙)
80 ///
81 JPanel tmpPan = new JPanel( );
82 tmpPan.setLayout( new BorderLayout( ) );
83 tmpPan.add(btGiGi, "West"); // GiGi
84 ///
85 bbb = new Button(" empty "); // 這是當作看板 !
86 bbb.setCursor( new Cursor(Cursor.HAND_CURSOR) ); // 出現"手"
87 bbb.setFont(new Font("標楷體",1,36));
88 bbb.addActionListener(this);
89
90 Panel p3= new Panel( new BorderLayout( ) );
91 Panel p3Up = new Panel( );
92 p3.add(p3Up, "North"); // 塞一些空間 :-)
93 Panel p3Down = new Panel( );
94 p3.add(p3Down, "South");
95 p3.add(bbb, "Center");
96 ///
97 // p3Down.setSize( new Dimension(123,99) );
98 p3Up.setPreferredSize(new Dimension(200,38) );
99 p3Down.setPreferredSize(new Dimension(200,98) );
100 ////////////
101 tmpPan.add(p3, "Center"); //
102 tmpPan.setBackground( new Color(198, 0, 168) );
103 //
104 ppp.add(tmpPan, "Center"); //再把 tmpPan 塞入 ppp 木板Center但右邊沒東西
105
106 //ppp.setSize(158, 58); // 好像沒有用ㄟ ?
107 ppp.setPreferredSize(new Dimension(168,198)); // height 有用
108
109 setLayout(new BorderLayout( ) ); // change Layout Manager 擺設經理
110 // 因為 Applet 是 Panel, 其 default Layout Manager 是 FlowLayout
111 // 設為 BorderLayout 後就可以指定 東西南北中 五個方位 放入元件
112 ppp.setBackground(Color.pink); // 背景色 粉紅
113 add(ppp, "North"); /// ppp 放 我 (Gui6, 是Applet)的 北邊
114 add(tt, "Center"); /// tt 文字區塊 放 我 (Gui6, 是Applet)的 正中間
115 tt.setFont(new Font("Ariel",3,32)); // 字體大一些
116 Panel pn = new Panel( );
117 Panel ptt=new Panel( );
118 Panel pOut = new Panel( );
119 pOut.setLayout(new BorderLayout( )); // 外匡面版用 BorderLayout
120 pOut.add(pn, "South"); // pn 塞在 pOut 這 Panel 內 :-) 木板上再放木板!
121 pOut.add(ptt,"North"); // pOut 內塞兩個 Panel : pn, ptt
122 // 現在 pOut 木板上有兩塊木板: ptt 上, 下是 pn (南)
123 ptt.add(new Button("請在右邊打字: ")); // 放入 ptt
124 ptt.add(tx); // 依序 放入 ptt
125 /// 再來, pn 這木板上 放入很多按鈕 ! 所以用 array 陣列 比較方便 !
126 pn.setBackground(Color.yellow);
127 bt = new Button[98]; // 只會生出 98 個參考 (阿其實就是 C++ 的指標啦)
128 // 上列生出 98 個 參考(Reference) 不會用很多記憶體 :-)
129 // 實際上會生出幾個按鈕是由 bMsg.length 決定 (看下列)
130 for(int i=1; i< bMsg.length; ++i) { // 這樣寫是個好習慣!
131 // 因為你去改 bMsg 陣列增加元素也不用來改這裡 :-)
132 bt[i] = new Button(bMsg[i]); // 真正生出六個 Button (注意0 故意不用)
133 pn.add(bt[i]); bt[i].setFont(new Font("細明體",1,16));
134 // 注意上列是在做勞作 :-) 把按鈕加入 pn 木板 !
135 bt[i].addActionListener(this); // 請求監聽 "動作事件"(ActionEvent)
136 // 注意上列是要求監聽 bb[i] 喔 !
137 } // for int i
138 add(pOut, "South"); // 把 pOut 塞入我(Gui6)這個 Applet 南邊
139 bt[3].setForeground(Color.red);
140 bt[2].setForeground(Color.BLUE);
141 validate( ); // 做了一些對圖形元件 的動作記得要做這 validate( );
142 } // init(
143
144 Button bt[ ]; // 宣告說 bt[ ] 是 Button 陣列 (array)
145 String bMsg[ ] = {"000", "Bt001", "看另一個範例",
146 "哈哈哈會讀書入", "bt西西", "BT五", "六六大順 囉", "Bye",
147 "張三", "李四", "十全十美" };
148 int kk = 0; // Global variable to this class
149
150 public void paint(Graphics g) {
151 System.out.println(" Paint kk = " + kk++);
152 // do drawing something ...
153 validate( ); //
154 tx.requestFocus( );
155 } // paint(
156
157 //////// ================================================== ///////////////
158 Color yyc[ ] = { Color.red, Color.blue, Color.green, Color.pink };
159 int cid = 0;
160
161 public void actionPerformed(ActionEvent e) {
162 Object who = e.getSource( ); // 誰被按了一下 ?
163 String gg = "You press " + e.getActionCommand( );
164
165 if(who == bbb) {
166 cid = (cid+1) % yyc.length;
167 bbb.setForeground( yyc[cid] );
168 repaint( );
169 return;
170 } // if(
171
172 if(who == bt[7]) System.exit(0);
173 if(who == bt[1]) ppp.setBackground(Color.red);
174 if(who == bt[2]) openWebWindow( MY_WEB );
175 if(who == bt[6]) { ppp.setBackground(Color.green);
176 tt.append("如果 林志玲 來演講, 你會去聽嗎? "); } // if
177 bbb.setLabel(gg); tt.append(gg+"\n");
178 if(who == bt[3] || who == tx) {
179 tt.append("讀到 " + tx.getText( ) + "\n");
180 ppp.setBackground(Color.gray);
181 } // if(who
182 repaint( ); // 會偷叫 update(Graphics);
183 } // actionPerformed(
184
185 public void update(Graphics g) { // 只是看看何時會跑過來這
186 System.out.println(" update ==> kk = " + kk++);
187 super.update(g); // 叫用上層(super class)的 update( )
188 } // update( will called by repaint( )
189
190 void openWebWindow(String web) { // note different when in Application
191 try {
192 if(isApplication){ // utilize the Runtime exec function
193 try { // 注意格式, 因字串中含有 " 雙引號 "
194 Runtime.getRuntime().exec(
195 "cmd /c \"start " + web +"\" " );
196 } catch (Exception e95){ // try Win 95/98
197 Runtime.getRuntime().exec(
198 "start " + web ); //Win95/98中 start 是內建
199 }
200 } else { // is Applet, we are in Browser, use showDocument( )
201 URL url = new URL(web);
202 getAppletContext().showDocument(url, "_blank");
203 } // see AppletContext
204 // _blank means in New Window
205 } catch (Exception e) {; }
206 } // openWebWindow(
207 //////////////////////////////////////////////////////////////////////
208
209 // 故意新寫一個 inner class, 編譯後看看目錄內多出啥 class 檔案?
210 class Ghost implements ActionListener {
211 public void actionPerformed(ActionEvent e) {
212 Object who = e.getSource( ); // 誰被按了一下 ?
213 if(who == btGiGi) { // 預留以後可能處理其他的 Action
214 try {
215 System.out.println("Laughing ...");
216 playFile("img/laugh.au"); // make Laugh 大笑(Applet)
217 } catch (Exception e2) {;}
218 }//if
219 }//actionPerformed(
220 } //class Ghost // an inner class
221 } // class Gui6
D:\jtest>