第 13章 圖形介面 AWT
Java 2 程式設計入門與應用
2
目錄13-1 AWT的簡介13-2 AWT的視窗元件13-3 AWT的事件處理 13-4 AWT的繪圖 溫故知新自我突破習題
3
13-1 AWT 的簡介
13-1.1 AWT 的架構13-1.2 Component 與 Container 類別的函式
4
前言: Java 提供了許多圖形使用者介面( Graphical U
ser Interface ,簡稱 GUI )的元件,可以設計讓使用者與應用程式互動的介面,虛擬視窗工具( Abstract Window Toolkit ,簡稱 AWT )就是 Java 最早用來處理視窗程式的類別。
5
3-1.1 AWT的架構 AWT 套件是處理視窗程式最基本的工具,雖然它提供了視窗、按鈕與其他元件,但是具有下列幾項缺點:
1. 當視窗中的元件比較多,或程式比較複雜時,就會出現執行速度慢與耗費較多記憶體的情況。2. AWT 不支援跨平台,造成視窗程式在其他作業系統可能無法執行。3. AWT 套件中的許多類別不是利用 Java 語言撰寫的,存在一些問題。
因此, Java 後來以 AWT 為基礎,另外發展出 Swing套件,關於 Swing 套件將在下一節介紹。
6
AWT套件的相關元件皆定義在 java.awt類別庫中,下面為視窗應用類別的繼承圖:
從上圖可以發現 AWT 套件的類別都是繼承自 Object 類別,而 java.awt 類別庫中的類別也具有繼承關係,每個子類別皆可以使用父類別中的資源,並且發現 Swing 套件的類別都是繼承自 AWT 套件的類別。
7
13-1.2 Component 與 Container類別的函式因為 AWT 套件的元件幾乎是繼承自 Compone
nt 與 Container 類別,所以可以使用這兩個類別的成員函式。
8
下面是 Component 類別常見的函式 -1 :
9
下面是 Component 類別常見的函式 -2 :
10
下面是 Component 類別常見的函式 -3 :
上面函式中出現的 Color 與 Font 是 java.awt 類別庫的常用類別,關於這兩個類別的用法說明如下。
11
Color類別:建立 Color 物件的語法有下面兩種:
Color 物件名稱 =new Color( 數值 R, 數值 G, 數值 B);語法中的數值範圍皆介於 0~255 之間,數值 R表示紅色,數值 G 表示綠色,數值 B 表示藍色,例如: Color c=new Color(220,0,150) 。而利用
Color 類別的 getRed 、 getGreen 與 getBlue 函式可以傳回 Color 物件的數值 R 、數值 G 與數值B 。
12
語法中的參數是 Color 類別中內建的常數值,共有下列幾種顏色:Color 物件名稱 =Color.常數 ;
例如: Color c=Color.pink; 。
13
Font類別: 建立 Font 物件的語法為 Font 物件名稱 =new Font(String name, int style, int size); 。name :字體名稱,必須是 Java 提供的字型。 style :字型樣式(粗體、斜體或標準),利用 Font 常數來設定,有下列幾種樣式:
如果要同時設定兩種樣式,可以將 Font 常數相加,例如: Font f=new Font("Arial", Font.BOLD +Font.ITALIC, 20); ,表示粗斜體。
size :字體大小。
14
Container類別的函式:Container 是指可以存放其他元件的容器,例如:將視窗看成一個容器,而視窗中可以存放許多像按鈕、標籤與文字方塊等元件。
15
下面是 Container類別常見的函式:
16
13-2 AWT的視窗元件13-2.1 視窗元件 Frame13-2.2 按鈕元件 Button13-2.3 標籤元件 Label13-2.4 文字元件 TextField 與 TextArea13-2.5 版面配置元件 13-2.6 其他元件
17
前言:AWT 套件所提供的視窗元件可以建立一般常見的應用程式視窗,利用這些元件的成員函式可以設計想要的視窗與樣式。
18
13-2.1 視窗元件 Frame
利用 Frame 類別可以建立一個包含標題列與邊框的容器,也就是“視窗”,在視窗中可以加入按鈕與標籤等元件,除了繼承父類別的函式以外, Frame 類別還有下面幾個常見的函式。
19
下面是 Frame類別常見的函式:
20
例如下面的程式碼:
21
22
完成後,執行程式的畫面顯示如下:
23
24
13-2.2 按鈕元件 Button
利用 Button 類別可以建立按鈕元件,除了繼承父類別的函式以外, Button 類別還有下面幾個常見的函式:
25
例如建立一個按鈕元件,其程式碼如下:
26
上述建立一個按鈕元件的程式碼說明如下:上述程式碼第 7 行利用 setLayout 函式將原本
AWT 預設的版面設定成 null ,取消該版面配置,如果不撰寫此行,則預設的版面配置會將最晚加入視窗的元件放到跟視窗一樣大,這樣就會蓋住原本視窗的設定。第 13 行必須利用 add 函式將按鈕元件加入到視窗中,才會在視窗看見新建立的按鈕。
27
完成後,畫面顯示如下:完成後執行程式,會發現在第 12 行設定的按鈕位置,表示按鈕左上角的座標會在距離視窗左上角 (50,50) 的位置,必須將視窗標題列的高度計算進去,畫面顯示如下:
28
13-2.3 標籤元件 Label
利用 Label 類別可以建立標籤元件,除了繼承父類別的函式以外, Label 類別還有下面幾個常見的函式:
29
例如建立一個標籤元件,其程式碼如下:
30
完成後,畫面顯示如下:完成後執行程式,會發現標籤的背景顏色與文字顏色分別為第 9 與 11 行設定的顏色,而且標籤中的文字會靠右對齊,畫面顯示如下:
31
13-2.4 文字元件 TextField 與 TextArea利用 TextComponent 類別衍生的 TextField 類別可以建立單行的文字方塊,而 TextArea 類別可以建立多行的文字方塊。文字元件與 Label 元件不同之處在於, Label元件僅能以唯讀方式顯示文字,但是文字元件可以由使用者改變內容,其繼承圖如下所示:
32
TextComponent 類別有下面幾個常見的函式:
33
TextField文字方塊:TextField 類別除了繼承父類別的函式以外,還有下面幾個常見的函式。
34
TextField類別有下面幾個常見的函式 -1:
35
TextField類別有下面幾個常見的函式 -2:
36
上述 TextField類別函式的說明如下:1. 利用 TextField 類別的 setColumns 函式設定欄位寬度,必須配合 AWT 套件的 FlowLayout版面配置(請見 13-2.5 ),才可以設定成功。2. 利用 setEchoChar 函式設定回應字元後,執行程式,會將文字方塊中的文字以回應字元顯示,但利用 getText 函式傳回的仍然是輸入的文字。
37
TextArea文字區域:TextArea 類別建立的多行文字區域,可以配合上下與左右捲軸觀看文字區域的內容,它除了繼承父類別的函式以外,還有下面幾個常見的函式。
38
TextArea類別有下面幾個常見的函式 -1:
39
TextArea類別有下面幾個常見的函式 -2:
40
下面為 TextArea類別常見的幾個函式 -3:
若要利用上述函式設定文字區域的欄位寬度與高度,必須配合 AWT 套件的 FlowLayout 版面配置(請見 13-2.5 ),才可以設定成功。
41
例如建立一個文字區域,其程式碼如下:
42
43
44
完成後,執行程式的畫面顯示如下:
45
13-2.5 版面配置元件利用“版面配置”元件可以管理視窗中各種物件的位置,將物件放置在想要呈現的地方。
46
Java 的 AWT 套件提供了下面幾種版面配置類別:
將視窗套用版面配置後,視窗中的物件會依照該版面配置的方式顯示位置與大小,所以在這裡利用函式設定物件的位置與大小是無效的。
47
FlowLayout版面配置:FlowLayout 是最簡單的版面配置方式,它會依序將物件由左至右,由上至下加入到視窗中,就好像在文件中逐行輸入資料一樣。
48
FlowLayout 類別有下面幾個常見的函式 -1:
49
FlowLayout 類別有下面幾個常見的函式 -2:
50
例如建立一個流動式版面配置,其程式碼如下:
上述程式碼第 9~11 行利用 for迴圈在視窗加入 5 個按鈕。
51
完成後,畫面顯示如下:完成後執行程式,視窗中的按鈕會逐行排列,如果改變視窗大小,則視窗中的按鈕也會跟著變動位置,畫面顯示如下:
52
BorderLayout版面配置:BorderLayout 版面配置方式會沿著視窗四周與中央位置,將物件加入視窗,也就是將視窗分為東、西、南、北、中區域放置物件,它是 Fr
ame 物件預設的版面配置方法。
53
BorderLayout 類別有下面幾個常見的函式:
54
下面指定位置的常數說明如下:利用 Frame 類別的 add 函式加入物件時,可以利用 BorderLayout 類別的常數指定物件的位置,若沒有指定位置,則會預設將物件放在中央位置,覆蓋之前位於中央位置的物件,指定位置的常數說明如下:
55
例如建立一個邊界式版面配置,其程式碼如下:
56
57
完成後,畫面顯示如下:完成後執行程式,視窗的按鈕會排列在五個區域,如果改變視窗大小,則按鈕不會跟著變動位置,而會隨著視窗而放大或縮小,畫面顯示如下:
58
GridLayout版面配置:GridLayout 版面配置方式會將視窗分割成多個格子,然後依序將物件由左至右,由上至下加入到視窗。
59
GridLayout 類別有下面幾個常見的函式 -1:
60
GridLayout 類別有下面幾個常見的函式 -2:
61
例如建立一個方格式版面配置,其程式碼如下:
62
完成後,畫面顯示如下:完成後執行程式,視窗中的按鈕會排列在 4 列
*3欄的格子中,若改變視窗大小,則視窗中的按鈕會隨著視窗大小而放大或縮小,畫面顯示如下:
63
64
CardLayout版面配置:CardLayout 版面配置方式會將視窗中的物件都重疊在一起,每次加入的物件都會一層一層的放在上一個物件的下面。
65
CardLayout 類別有下面幾個常見的函式:
66
在 CardLayout 版面配置下加入物件時,須在 add函式中輸入兩個參數,其語法如下:在 CardLayout 版面配置下加入物件時,必須在 add 函式中輸入兩個參數(加入的物件與該物件的名稱),其語法如下:
67
例如下面的程式碼:
68
完成後,畫面顯示如下:完成後執行程式,會先顯示 B5 按鈕,然後經過 1秒後,再顯示 B1 按鈕,如此一直循環顯示,畫面顯示如下:
69
70
71
72
13-2.6 其他元件除了上面介紹的元件以外, AWT 套件中還有相當豐富的元件,其他元件的用法與之前教的元件都大同小異,說明如下。
73
Component類別的元件 -1:
74
Component類別的元件 -2:
75
Component類別的元件 -3:
76
Component類別的元件 -4:
77
Component類別的元件 -5:
78
Component類別的元件 -6:
79
Component類別的元件 -7:
80
81
下面舉例 Component 類別元件的程式碼:
82
83
84
完成後,執行程式的畫面顯示如下:
85
Window類別的對話方塊元件 Dialog:利用 Dialog 元件可以自訂輸入視窗、訊息視窗與確定視窗等對話方塊,它與 Frame 類別都是繼承自 Window 類別,而對話方塊必須配合後面介紹的事件處理才會產生效果。
86
下面為 Dialog類別的繼承圖:
87
有控制權和無控制權:對話方塊分為“有控制權”與“無控制權”兩種,當對話方塊為有控制權狀態時,就是對主程式有控制權,表示必須要執行完對話方塊後,才能繼續執行所有者的視窗或對話方塊;而當對話方塊為無控制權狀態,就對主程式沒有控制權,沒有強制要先執行對話方塊。
88
Dialog類別有下面幾個常見的函式 -1:
89
Dialog類別有下面幾個常見的函式 -2:
90
Dialog類別有下面幾個常見的函式 -3:
91
MenuComponent類別的功能表元件:功能表是應用程式中常見的組成元素,它是應用程式中所有功能的集合。MenuComponent 類別衍生的 MenuBar 、 Menu
Item 與 Menu 類別可以產生功能表,功能表必須配合後面介紹的事件處理才會產生效果。
92
下面為功能表類別的繼承圖:
上面三個類別說明如下:1. Menubar :建立功能表列。2. Menu :建立功能表列上面的功能選項。3. MenuItem :建立功能表選單中的選項。
93
下面為這三種元件在功能表中代表的位置:
94
功能表類別有下面幾個常見的函式 -1:
95
功能表類別有下面幾個常見的函式 -2:
96
功能表類別有下面幾個常見的函式 -3:
97
例如下面的程式碼:
98
完成後,畫面顯示如下:完成後執行程式,功能表中的選項變成設定的樣式,但是選擇選項後不會有反應,這是因為尚未做事件處理,畫面顯示如下:
99
13-3 AWT的事件處理 13-3.1 物件、事件與事件程式 13-3.2 事件處理的類別 13-3.3 處理 ActionEvent 事件 13-3.4 處理 AdjustmentEvent 事件 13-3.5 處理 ItemEvent 事件 13-3.6 處理 TextEvent 事件 13-3.7 處理 WindowEvent 事件 13-3.8 處理 KeyEvent 事件 13-3.9 處理 MouseEvent 事件
100
前言:在 Windows 環境中,當按下滑鼠鍵、在鍵盤上按下按鍵等動作時,作業系統會根據這些事件去做一些處理動作,這種運作的模式就稱為事件驅動,在 Java 中,可以設定當發生某些事件時,要回應事件所執行的程式碼。
101
13-3.1 物件、事件與事件程式 在程式中,構成事件驅動程式的要素有三,分別為物件、事件與事件程式。 什麼是物件?什麼是事件?什麼又是事件程式?先舉一個生活上的例子來說明吧! 「學生一聽到上課鐘響,馬上進教室,拿出課本,預習功課,等待老師來上課。」 上段描述中,“學生”就是物件,“上課鐘響”就是事件,而“馬上進教室,拿出課本,預習功課,等待老師來上課。 ” 就是發生鐘響事件時要執行的事件程式。“上課鐘響”會驅動“學生”的“上課程序”(也就是“馬上進教室,拿出課本,預習功課,等待老師來上課。”),如此一來,就構成了事件驅動程式的工作模式。 在 Java 中,也可以利用同樣的概念來處理事件,例如:當按一下
Button 按鈕,則 Label 的文字會顯示“這就是事件驅動程式!”。
102
13-3.2 事件處理的類別 Java 利用 AWTEvent 類別來處理 AWT 介面產生的事件,主要可以分為下列兩種:
1. 語意事件:跟物件有關的事件,直接繼承 AWTEvent 的類別所產生的事件都屬於語意事件,例如: ActionEvent 與 ItemEvent 等。
2. 低階事件:跟滑鼠、鍵盤或視窗有關的事件,ComponentEvent衍生的類別產生的事件都是屬於低階事件,例如: MouseEvent 與 KeyEvent 。
103
AWTEvent事件類別:下面為 AWTEvent 事件類別的繼承圖:
104
下面為每一種事件類別的說明,以及會產生這些事件的元件:
105
傾聽者介面與傾聽者介面的事件處理函式:每一種事件類別都會對應一個傾聽者介面,傾聽者( Listener )的任務是加入傾聽者物件到元件中,當該元件發生事件情況時,就會產生對應事件類別的物件,然後將該事件物件傳遞給傾聽者,此時傾聽者會將發生的事件物件傳送給事件處理的函式,由該函式做這個事件對應的動作。
106
下面圖示說明事件處理的運作過程:
每個傾聽者介面中都有對應的事件處理函式,可以在類別中覆載,並自行撰寫事件處理的內容。另外,各種元件中也提供對應的函式以加入傾聽者物件。
107
常見事件及其傾聽者介面的說明如下 -1 :
108
常見事件及其傾聽者介面的說明如下 -2 :
109
轉接器類別: WindowEvent 、 KeyEvent 與 MouseEvent 等低階事件有多個事件處理函式,因為實作傾聽者介面時必須要實作所有的事件函式,這樣當只想要處理某一項事件函式時,還要撰寫多餘的函式,非常麻煩。 所以它們除了使用傾聽者傳遞事件物件,也可以使用轉接器類別來傳遞事件物件,轉接器類別實作傾聽者介面,它的成員函式內容其實是空的,所以可在程式中繼承轉接器類別,然後覆載想要處理的事件函式,下面舉一個 KeyAdapter 類別的程式碼為例,發現轉接器類別中的成員函式確實沒有內容:
110
下面是具有轉接器類別的事件:
111
建立事件處理的步驟可以分為下面四個部分 -1:1. 載入事件處理類別庫:載入 java.awt.event 類別庫。2. 找出要處理的事件類別,然後宣告一個傾聽者或轉接器類別:傾聽者類別要實作傾聽者介面,而轉接器類別要繼承轉接器類別,例如下面的程式碼為一個傾聽者類別。
112
建立事件處理的步驟可以分為下面四個部分 -2:3. 覆載要處理的事件函式:在傾聽者或轉接器類別中加入事件處理函式,傳遞對應的事件參數,並撰寫發生事件後,要執行的動作。
4. 加入傾聽者物件到元件中:利用 add___Listener 函式,將傾聽者物件加入要做事件處理的元件中,例如下面的程式碼。
113
ActionEvent類別的成員說明如下:這裡先舉一個處理 ActionEvent 事件的例子,當使用者執行按下按鈕、選擇功能表項目、在文字方塊按下 鍵等動作時,就會發生這個事件。
114
例如下面的程式碼:
115
116
上述程式碼分析如下:1. 第 2 行載入 java.awt.event 事件處理類別庫。2. 第 26~41 行宣告一個傾聽者類別 ActionHandler (可以自訂類別名稱),實作 ActionListener 類別,並在第 28~40 行覆寫 ActionListe
ner 類別的 actionPerformed 成員函式,傳遞的參數為 ActionEvent事件物件 e ,在 actionPerformed 函式中設定選取每一個選項時,所要對應的動作。3. 第 30 行利用 e.getSource() 取得發生 ActionEvent 事件的物件,然後利用 (MenuItem)強制轉換資料型別將 Object 物件轉換成 MenuIt
em 物件。4. 第 18~21 行利用 addActionListener 函式,將傾聽者物件分別加入 i
tem1~item4 物件,以判斷這些物件是否有發生 ActionEvent 事件。5. 因為程式中的物件在 main() 方法與 ActionHandler 類別都會使用到,所以在第 4~11 行利用關鍵字 static 將這些物件宣告為靜態成員,為程式中的類別所共用。
117
完成後,執行程式的畫面顯示如下:
118
119
120
121
122
13-3.4 處理 AdjustmentEvent 事件AdjustmentEvent 事件發生於捲動 Scrollbar 捲軸元件時,必須實作 AdjustmentListener 介面,處理這個事件的函式為 adjustmentValueChange
d ,關於此事件的成員可以參考說明文件。
123
例如下面的程式碼:
124
125
完成後,執行程式的畫面顯示如下:
126
13-3.5 處理 ItemEvent事件 ItemEvent 事件發生於選擇 Checkbox 、 Choice與 List 等選項元件時,必須實作 ItemListener介面,處理這個事件的函式為 itemStateChange
d ,關於此事件的成員可以參考說明文件。
127
例如下面的程式碼:
128
129 上述程式的 List 與 Checbox 元件都要處理 itemStateChanged 事件函式,所以第 29~35 行與第 37~53 行撰寫兩個傾聽者類別,處理兩種元件的事件。
130
完成後,執行程式的畫面顯示如下:
131
13-3.6 處理 TextEvent事件TextEvent 事件發生於改變 TextField 與 TextAre
a 元件的內部文字時,必須實作 TextListener 介面,處理這個事件的函式為 textValueChanged ,關於此事件的成員可以參考說明文件。
132
例如下面的程式碼:
133
134
135
完成後,執行程式的畫面顯示如下:
136
13-3.7 處理WindowEvent事件WindowEvent 視窗事件發生於放大、縮小與關閉視窗時,可以透過實作 WindowListener 介面或繼承 WindowAdapter 類別的方式來處理事件,關於此事件的成員可以參考說明文件。
137
實作WindowListener介面:WindowEvent 事件的 WindowListener 介面提供下面的事件處理函式:
138
下面舉例建立傾聽者類別來實作傾聽者介面,其程式碼如下: 如果要建立傾聽者類別來實作傾聽者介面,則必須在類別中實作上面所有的函式才可以編譯成功,例如下面的程式碼:
139
140
上述程式碼分析如下:1. 第 14~25 行建立一個傾聽者類別 WindowHandler ,實作 WindowListener 介面,在此類別中必須實作 Wi
ndowListener 介面的所有成員函式,所以即使沒有要做事件處理的函式(例如:第 20 與 22~24 行),仍然要撰寫一個空的函式。2. 第 15~18 行的 windowClosing 函式可以處理點選視窗的 關閉鈕時,程式做的回應,第 16 行的 dispose是 Window 類別的函式,會釋放視窗以及視窗中所有元件的記憶體資源,並結束視窗,所以第 17 行可省略。
141
完成後,執行程式的畫面顯示如下:
142
繼承WindowAdapter類別: 利用轉接器類別來繼承 WindowAdapter 類別,就可以改善上面範例的缺點,只要撰寫想做事件處理的函式即可。請修改範例檔 ch13_03_07a 第 14~25 行如下,只要修改粗體字部分,並且將不要處理的函式內容刪除,則執行結果相同:
143
13-3.8 處理 KeyEvent事件KeyEvent 鍵盤事件發生在鍵盤上按下任何鍵時,可以透過實作 KeyListener 介面或繼承 Ke
yAdapter 類別的方式來處理事件。
144
KeyEvent類別的成員說明如下:
145
KeyEvent 事件的 KeyListener 介面提供下面的事件處理函式:
146
下面的程式碼利用實作 KeyListener 介面的方式建立事件處理:
147
148
完成後,執行程式的畫面顯示如下:
如果要利用轉接器類別來繼承 KeyAdapter 類別,只需要修改程式碼第 19 行的粗體字部分為“ extends KeyAdapter” 就可以了,其執行結果相同,請參考範例檔 ch13_03_08b 。
149
150
13-3.9 處理MouseEvent事件MouseEvent 滑鼠事件是程式中常常會使用的事件命令,常見的滑鼠事件有滑鼠指標的移動、按一下滑鼠鍵、快按兩下滑鼠鍵、滑鼠指標移至或移開……等,善用滑鼠事件,可以產生各式各樣的互動效果。MouseEvent 有 MouseListener 與 MouseMotion
Listener 兩種傾聽者介面,可以透過實作傾聽者或繼承轉接器的方式來處理。
151
MouseEvent類別的成員說明如下:
除了 MouseEvent 類別的成員以外,也可以利用 InputEvent 父類別中的常數判斷按下滑鼠的右鍵或左鍵, getModifiers 函式可以傳回此常數值:
152
MouseListener介面的函式:MouseEvent 事件的 MouseListener 介面提供下面的事件處理函式:
153
下面的程式碼利用實作 MouseListener介面的方式建立事件處理:
154
155
156
完成後,執行程式的畫面顯示如下:
如果要利用轉接器類別來繼承 MouseAdapter類別,只需要修改程式碼第 20 行的粗體字部分為“ extends MouseAdapter” 就可以了,其執行結果相同,請參考範例檔 ch13_03_09b 。
157
MouseMotionListener介面的函式:MouseEvent 事件的 MouseMotionListener 介面提供下面的事件處理函式:
158
下面的程式碼利用實作MouseMotionListener介面的方式建立事件處理:
159
160
完成後,執行程式的畫面顯示如下:
如果要利用轉接器類別來繼承 MouseMotionAdapter 類別,只需要修改程式碼第 20 行的粗體字部份為“ extends MouseMotionAdapter” 就可以了,其執行結果相同,請參考範例檔 ch13_03_09d 。
161
162
13-4 AWT的繪圖13-4.1 利用 Graphics 類別繪圖13-4.2 利用 Graphics2D 類別繪圖
163
前言:透過圖形的表達方式,可以勝過許多文字的說明,因此在 Java 中也可以利用程式來繪製圖形,本節將介紹一些基本的繪圖方法。
164
13-4.1 利用 Graphics類別繪圖在 AWT 套件提供了 Graphics 類別來建立畫布物件,利用 Component 類別的 getGraphics 函式可以建立 Graphics 物件,其語法如下:例如:建立一個 Graphics 物件,以視窗 f 當作畫布,則可以撰寫程式碼 Graphics g=f.getGrap
hics(); 。
165
Graphics類別的函式:利用 Graphics 類別的函式可在畫布上描繪各種線條或圖形,其函式說明如下( x 、 y 為圖形的左上角起點座標, w 、 h 為圖形的寬度與高度)。
166
以下是 Graphics類別函式的說明 -1:
167
以下是 Graphics類別函式的說明 -2:
168
以下是 Graphics類別函式的說明 -3:
169
以下是 Graphics類別函式的說明 -4:
170
Component類別的 paint與 repaint函式:在畫布中可以配合之前教的事件處理來繪製圖形,例如點選按鈕後繪製圖形,或是拖移滑鼠繪製圖形。利用 Frame 視窗做為畫布時,可以覆載 Compo
nent 類別的 paint 函式,將繪圖程式碼撰寫在 paint 函式中。
171
下面是 Component 類別在繪圖時常用的函式:
172
下面建立一個繼承 Frame 的類別,其語法如下:因為要在 Component 類別的衍生類別才可覆載
paint 函式,所以繪圖時要建立一個繼承 Frame的類別,然後直接利用此類別名稱定義 Frame物件,就可以使用 Frame 物件,其語法如下:
173
下面舉例以不同按鈕表示各種繪圖功能,其程式碼如下: 下面以不同按鈕表示各種繪圖功能,當點選按鈕時,就可以在視窗中按下滑鼠鍵繪製該圖形,若拖移滑鼠鍵,則繪製出來的圖形為粉紅色:
174
175
176
177
上述以不同按鈕表示各種繪圖功能的程式碼分析如下 -1:1.第 3 行建立 ch13_04_01 類別,此類別繼承 Frame 類別,則第 4 行定義的物件 f 就可以視為 Frame 物件。2.繪圖程式以類別產生的物件當作傾聽者,所以不用宣告傾聽者類別,必須在第 3 行實作傾聽者介面,而第
13 、 16 、 17 行以 f 物件為傾聽者。3.第 5 行宣告按鈕陣列,然後在第 12 行建立 Button 物件,並且在第 14 行將 Button 物件都放到面板 p 中。4.第 24 行宣告布林變數 isclick ,初始值為 false ,當執行程式後發生點選按鈕的事件,就在第 27 行設定 iscl
ick 的值為 true ,表示已經點選按鈕。
178
上述以不同按鈕表示各種繪圖功能的程式碼分析如下 -2:5. 第 28~30 行判斷點選的按鈕是哪一個,並設定變數
button 為 0~6 的值。6. 第 35~40 行的 mouseClicked 函式處理點選滑鼠的事件,而第 32 行表示若點選 鈕,就將背景顏色填滿,重新繪圖。7. 第 46~52 行的 mouseDragged 函式處理拖移滑鼠的事件,其中第 48 行設定當拖移滑鼠時,繪製的圖形為粉紅色。8. 第 54~74 行宣告繪圖函式 paint ,首先在第 55 行先判斷是否已經點選功能按鈕,才進入第 56~72 行的判斷式,分別繪製按鈕對應的圖形。9. 第 71 行繪製圖片之前,必須先在第 70 行建立圖片物件,指定顯示的圖片為 ch13_04_01.gif 。
179
完成後,畫面顯示如下: 完成後執行程式,因為會自動呼叫 paint 函式,所以調整視窗大小後,視窗的圖形並不會消失;但是本例使用了滑鼠拖移的事件,則當放大 /縮小視窗或蓋住視窗後,視窗只會留下最後一個繪製的圖形,畫面顯示如下:
180
13-4.2 利用 Graphics2D類別繪圖 Graphics2D 是一個繼承自 Graphics 類別的抽象類別,將此類別配合其他 AWT 套件提供的類別,就具有旋轉圖形、控制顏色、填充漸層顏色與轉移座標等功能,提供比 Graphics 類別更多元的繪圖技巧。 因為 Graphics2D 繼承自 Graphics 類別,可以透過已經建立好的 Graphics 物件來建立 Graphics2D 物件,只要利用強制轉換型別功能將 Graphics 物件轉換成 G
raphics2D 物件即可,其語法如下: 例如:已經建立一個 Graphics 物件 g ,若要建立 Gra
phics2D 物件,則可以撰寫程式碼 Graphics2D g2=(Graphics2D)g; 。
181
Graphics2D類別的函式說明如下:
182
例如下面的程式碼:
183
184
185
186
完成後,執行程式的畫面顯示如下 -1:
187
完成後,執行程式的畫面顯示如下 -2:
188
189
190
191
溫故知新 -1:
192
溫故知新 -2:
193
溫故知新 -3:
194
溫故知新 -4:
195
溫故知新 -5:
196
溫故知新 -6:
197
溫故知新 -7:
198
溫故知新 -8:
199
溫故知新 -9:
200
自我突破習題 -選擇題:
201
自我突破習題 -選擇題:
202
自我突破習題 -實作題:
203
自我突破習題 -實作題: