# Java AWT 教學 ![image](https://hackmd.io/_uploads/HJ6I_ACgR.png) Component 物件功能可以參考 https://yowlab.idv.tw/javadocs/java/awt/class-use/Component.html ### I. Java AWT Basic 說明視窗程式的物件建立,包含視窗、按鈕等物件的建立,以及版面配置的部分。 #### 建立視窗 (Frame) ![image](https://hackmd.io/_uploads/SJ0x8ARe0.png) - main class 必須繼承 `Frame`類別 - 在沒有寫任何事件的情況下,所以按鈕都不會生效 (包含視窗關閉按鈕) ```java Frame frame = new Frame("The Title of Frame"); ``` | Frame class 常用方法: | | -------------------------------------------- | | `void setBackground(Color color)` | | `void setBounds(int x, int y, int w, int h)` | | `void setSize(int w, int h)` | | `void setLocation(int x, int y)` | | `void setVisible(boolean v)` | | `void setEnabled(boolean v)` | #### 建立按鈕 (Button)、核取方塊 (Checkbox)、標籤 (Label) | Button | Checkbox | Label | | -------- | -------- | -------- | | ![image](https://hackmd.io/_uploads/HJUrI0RlR.png) | ![image](https://hackmd.io/_uploads/Bkiv9RRe0.png) | ![image](https://hackmd.io/_uploads/HyYkjCRxA.png) | - 必須事先建立 Frame 物件 (不然沒有地方可以放 button/label/checkbox) - **取消 Java 預設的版面配置** (不然整個按鈕會占滿視窗) - 在沒有寫任何事件的情況下,所以動作都不會生效 (包含視窗關閉按鈕) ```java Frame frame = new Frame("The Title of Frame"); Button btn = new Button("Push me"); Checkbox check = new Checkbox("Epson 5900L"); Label lab = new Label("Hello World!"); frame.setLayout(null); // 取消版面配置 frame.add(btn); // 把按鈕加入視窗中 frame.add(check); frame.add(lab); frame.setVisible(true); ``` *僅供單選的核取方塊請參照 `Checkbox2.java`* #### 建立文字輸入物件(TextField)、文字方塊(TextArea) | TextField | TextArea | | -------- | -------- | | ![image](https://hackmd.io/_uploads/SksuhARx0.png)| ![image](https://hackmd.io/_uploads/Bkq52ACxR.png)| * `TextField` 用來處理單行文字 * `TextArea` 用來處理多行文字 (可以設定卷軸 #### 版面配置 (Layout) | BorderLayout | CardLayout | FlowLayout | GridLayout | | -------- | -------- | -------- | -------- | | ![image](https://hackmd.io/_uploads/B1nARA0xR.png) | ![image](https://hackmd.io/_uploads/r1H-1y1WR.png) | ![image](https://hackmd.io/_uploads/rJ781JkbC.png) | ![image](https://hackmd.io/_uploads/ryFwJyJbA.png)| ```java // 加入 Frame 的方法 void add(Component comp, Object constraints); ``` ### II. Java Event 委派事件的處理流程: ![image](https://hackmd.io/_uploads/B1yn-J1bA.png) 以 "按下按鈕" 為例: 1. Listener Object **Register** Event Source 事件傾聽者向 event source 按鈕 btn 註冊 2. Event Source **Creates** Event Object 按下按鈕後,Java 會產生一個 "事件的物件" 3. Event Object **Invokes** Listener Object 按鈕 event source 會把這個 "事件的物件" 再傳回去給事件傾聽者 4. Listener Object **Implements** Listener Interface 事件傾聽者會根據這個 "事件的物件" 的種類把工作分派下去給事件處理者 程式碼設計邏輯(以按鈕為例): 1. 實作 Listener 介面:設計觸發事件時,會設定 listener 和 event source,**通常會設定 "包含事件來源者的物件(frame)" 為 listener** ```java // button 為 event source,frame 為 listener public class Button1 extends Frame implements ActionListener ``` 2. 註冊物件 ```java // 傾聽者 frame 向事件來源者 button 註冊 button.addActionListener(frame); ``` 3. 撰寫事件處理的程式碼:改寫介面中的 abstract function (ActionListener) ```java public void actionPerformed(ActionEvent e) { frame.setBackground(Color.yellow); } ``` 也有另一種寫法,直接把實作介面的類別定義在主類別裡面,自己成為它的內部類別(`Button2.java`)。 事件處理類別眾多,以下為 AWT 物件可能產生的事件對應關係表: | 事件來源者 | 產生事件的類別型態 | | -------- | -------- | | Button | ActionEvent | | CheckBox | ActionEvent, ItemEvent | | Component | ComponentEvent, FocusEvent, KeyEvent, MouseEvent| | MenuItem | ActionEvent | | Scrollbar | AdjustmentEvent | | TextArea | TextEvent, AreaEvent | | Window | WindowEvent | #### ActionEvent 類別 | interface | event handler | | -------- | -------- | | `ActionListener` | `void actionPerformed(ActionEvent e)` | * Button: 按下按鈕 * List: 選擇表單物件 * MenuItem: 選擇功能選單 * TextField: 輸入文字後按下 ENTER * TextArea: 輸入文字後按下 ENTER #### ItemEvent 類別 | interface | event handler | | -------- | -------- | | `ItemListener` | `void itemStateChanged(ItemEvent e)` | * Checkbox: 勾選核取方塊 * List: 選擇表單選項 * Choice: 選取單選選項 #### TextEvent 類別 | interface | event handler | | -------- | -------- | | `TextListener` | `void textValueChanged(TextEvent e)` | * TextArea: 文字改變時 * TextField: 文字改變時 #### KeyEvent 類別 | interface | event handler | | -------- | -------- | | `KeyListener` | `void keyTyped(TextEvent e)` | | | `void keyPressed(KeyEvent e)`| | | `void keyReleased(KeyEvent e)` | * Component: 按下鍵盤按鍵 #### MouseEvent 類別 | interface | event handler | | -------- | -------- | | `MouseListener` | `void mouseClicked(MouseEvent e)` | | | `void mouseEntered(MouseEvent e)`| | | `void mouseExisted(MouseEvent e)` | | | `void mousePressed(MouseEvent e)` | | | `void mouseReleased(MouseEvent e)` | | `MouseMotionListener` | `void mouseDraged(MouseEvent e)` | | | `void mouseMoved(MouseEvent e)` | * Component: 滑鼠移動 or 滑鼠按鍵 or 滑鼠拖曳 #### WindowEvent 類別 | interface | event handler | | -------- | -------- | | `WindowListener` | `void windowActivated(WindowEvent e)` | | | `void windowClosed(WindowEvent e)`| | | `void windowClosing(WindowEvent e)` | | | `void windowDeactivated(WindowEvent e)` | | | `void windowDeiconified(WindowEvent e)` | | | `void windowIconified(WindowEvent e)` | | | `void windowOpened(WindowEvent e)` | * Window: 視窗建立、縮小至工具列、關閉等 * 視窗關閉的另一種寫法:`System.exit(0);` ### III. 範例程式碼(Eclipse 開啟方式) 1. 先建立一個空的 java project ![image](https://hackmd.io/_uploads/SJbI1gk-C.png) 2. 對專案右鍵,選取 import ![image](https://hackmd.io/_uploads/HJOYkeJZA.png) 3. General > File System ![image](https://hackmd.io/_uploads/HJE2ylJ-A.png) 4. 選取專案資料夾(FinalProjects),勾選裡面的資料夾如下圖 ![image](https://hackmd.io/_uploads/By_xely-C.png) 5. 選取 "Yes To All" ![image](https://hackmd.io/_uploads/H1JSee1ZC.png) 6. 範例程式碼如下圖所示 ![image](https://hackmd.io/_uploads/S1l_xl1-C.png)