---
# System prepended metadata

title: Java自學紀錄 - 視窗程式設計 AWT
tags: [AWT, Java]

---

###### tags: `Java` `AWT`
# Java自學紀錄 - 視窗程式設計 AWT
# 表單與表單控制項
==import java.awt.*==
## 表單
視窗設計的第一步就是要有表單,AWT的視窗表單就是*java.awt.Frame*類別。
以下程式示範Frame類別
```java=
package learning.AWT;

import java.awt.*;
public class Java_13_Form {
    public static void main(String[] args) {
        Frame frm = new Frame("Form"); //標題
        frm.setBackground(Color.yellow); //背景顏色
        frm.setSize(500,500); //標單寬度,長度
        frm.setVisible(true); //顯示表單
    }
}
```
>顯示結果

![](https://i.imgur.com/k68dIRp.png)
接著你會發現表單關不起來,那是因為我們還沒實作與註冊事件。
在後面會教。

## 元件
* Label
Lable通常當作輸出結果或輸入提示。
```java=
package learning.AWT;

import java.awt.*;
public class Java_13_Form extends Frame { //繼承
    public Java_13_Form(){
        this.setLocation(100,50); //位置
        this.setTitle("First Form"); //標題
        this.setSize(500,500); //標單寬度,長度
        this.setVisible(true); //顯示表單
        this.setLayout(null); //自行定義版面設置
    }
    public static void main(String[] args) {
         Frame frm = new Java_13_Form();
         Font font = new Font(Font.DIALOG_INPUT, Font.PLAIN, 35); //設定字型大小和字型
         Label lab = new Label();
         frm.setBackground(Color.BLACK);
         lab.setLocation(50,225);
         lab.setSize(400,50);
         lab.setBackground(Color.yellow);
         lab.setFont(font);
         lab.setText("Hello I'm lucas !");
         frm.add(lab); //將lab加入frm
    }
}
```
>顯示結果

![](https://i.imgur.com/OYNOKOw.png)

* TextField
通常用來輸入文字與數字。

```java=
TextField txf = new TextField(字串);
```

* Button
按鈕建通常用來執行一個指令。

```java=
package learning.AWT;

import java.awt.*;

public class Java_13_2Form extends Frame {
    Java_13_2Form(){
        setLocation(100,50);
        setTitle("Add Button");
        setSize(500,500);
        setVisible(true);
        setLayout(null);
    }
    public static void main(String[] args) {
        Frame frm = new Java_13_2Form();
        Button btn = new Button(); //宣告Button
        btn.setLabel("Button");
        btn.setBounds(30,60,120,140); //(x,y,width,height)
        btn.setBackground(Color.blue);
        frm.add(btn); //add Button
    }
}
```
> 顯示結果

![](https://i.imgur.com/nqxBtIq.png)

# 滑鼠動作事件
==實作== : 做一個可以計算按壓次數的Button
```java=
package learning.AWT;

import java.awt.*;
import java.awt.event.*;

public class Java_13_mouse extends Frame implements ActionListener {
    static int i = 0;
    Button btn = new Button(); //在這裡宣告Button,actionPerformed才可以用
    //安排表單內容與註冊事件
    public Java_13_mouse(){
        this.setLocation(100,50); //位置
        this.setTitle("Click"); //標題
        this.setSize(500,500); //標單寬度,長度
        this.setVisible(true); //顯示表單
        this.setLayout(null); //自行定義版面設置

        btn.setLabel("Press Me!");
        btn.setBounds(200,200,100,100);
        btn.setBackground(Color.blue);
        this.add(btn); //add Button
        //加入ActionListener介面,以便感受滑鼠事件
        btn.addActionListener(this); //委派Java_13_mouse處理方式
    }

    public static void main(String[] args) {
        Java_13_mouse frm = new Java_13_mouse();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        i++;
        btn.setLabel(String.valueOf(i));
    }
}
```
>顯示結果
>
![](https://i.imgur.com/QZlpJ1o.png)
>點擊10下後
>
![](https://i.imgur.com/0HLiz2B.png)

==實作== : 做一個+1,-1的按鈕,並計算其結果
```java=
package learning.AWT;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Java_13_mouse_2 extends Frame implements ActionListener {
    static int i = 0;
    Button btnAdd = new Button();
    Button btnSub = new Button();
    Button btnExit = new Button();

    public Java_13_mouse_2(){
        this.setLocation(100,50); //位置
        this.setTitle("Click"); //標題
        this.setSize(500,500); //標單寬度,長度
        this.setVisible(true); //顯示表單
        this.setLayout(null); //自行定義版面設置

        btnAdd.setLabel("Add 1");
        btnAdd.setBounds(30,50,60,40);
        btnAdd.setBackground(Color.blue);

        btnSub.setLabel("Sub 1");
        btnSub.setBounds(120,50,60,40);
        btnSub.setBackground(Color.blue);
        
        btnExit.setLabel("Exit");
        btnExit.setBounds(30,100,150,40);

        this.add(btnAdd);
        this.add(btnSub);
        this.add(btnExit);
        //加入事件處理
        btnAdd.addActionListener(this);
        btnSub.addActionListener(this);
        btnExit.addActionListener(this);
    }
    public static void main(String[] args) {
        Java_13_mouse_2 frm = new Java_13_mouse_2();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == btnAdd) i++;
        else if(e.getSource() == btnSub) i--;
        else System.exit(0);
        this.setTitle(String.valueOf(i));
    }
}
```
>顯示結果

![](https://i.imgur.com/yLDQoQU.png)
>錄影錄不出來視窗,我也不知道為甚麼QQ

{%youtube b9wVKdUc6Qk %}
# 視窗事件
前面所設計的視窗,不管你怎麼按右上角的關閉視窗都沒有反應,那是因為我們沒有**委派**這些視窗事件。而視窗右上角的**叉叉**是被定義在java.awt.event.WindowListener介面。

==實作== : 做一個可以被關掉的視窗。
```java=
package learning.AWT;

import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class Java_13_Form_shutdown extends Frame implements WindowListener{
    Java_13_Form_shutdown(){
        //super("WindowListener");
        this.setSize(300,150);
        this.addWindowListener(this); //加入感應視窗的事件
        this.setVisible(true);
    }

    public static void main(String[] args) {
        Java_13_Form_shutdown frm = new Java_13_Form_shutdown();
    }
    //有7種事件*必須*實作
    @Override
    public void windowOpened(WindowEvent e) {

    }
    @Override
    public void windowClosing(WindowEvent e) {

    }
    @Override
    public void windowClosed(WindowEvent e) {
        System.exit(0);
    }
    @Override
    public void windowIconified(WindowEvent e) {
    }
    @Override
    public void windowDeiconified(WindowEvent e) {

    }
    @Override
    public void windowActivated(WindowEvent e) {

    }
    @Override
    public void windowDeactivated(WindowEvent e) {

    }
}
```
:warning: 這種方法的壞處是七種方法都必須實做才能達到關閉視窗。所以有另外一個類別
java.awt.event.WindowAdaper,只需要時實作所需方法即可。

:point_down:此時按叉叉即可關閉視窗。
```java=
package learning.AWT;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Java_13_Form_shutdown_2 extends Frame {
    Java_13_Form_shutdown_2(){
        super("內部類別");
        this.setSize(500,500);
        this.addWindowListener(new wap()); //將內部類別註冊關於視窗的事件
    }
    public static void main(String[] args) {
        Java_13_Form_shutdown_2 frm = new Java_13_Form_shutdown_2();
        frm.setVisible(true);
    }
    class wap extends WindowAdapter{
        public void windowClosing(WindowEvent e){
            System.exit(0);
        }
    }
}
```

# 滑鼠事件
## 常用方法
* getButton 回傳1,2,3 分別代表左鍵,中鍵,右鍵。
* getPoint 回傳點擊座標
* getX 回傳點擊X座標
* getY 回傳點擊Y座標

==實作== 做一個視窗,與使用者點擊處標示一個黑點。
```java=
package learning.AWT;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Java_13_MouseEvent extends Frame implements MouseListener {
    Java_13_MouseEvent(){
        this.setLocation(100,50);
        this.setTitle("Mouse Clicker");
        this.setSize(500,500);
        this.setVisible(true);
        this.setLayout(null);
        this.addWindowListener(new WindowAdapter() { //此處是使用內嵌類別委任視窗事件
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        this.addMouseListener(this);
    }

    public static void main(String[] args) {
        Java_13_MouseEvent frm = new Java_13_MouseEvent();
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        int x,y;
        Graphics g;
        g = getGraphics(); //取得繪圖物件
        x = e.getX();
        y = e.getY();
        g.fillRect(x,y,10,10); //設定點擊位置的方塊大小
        System.out.println(e.getButton()); //可取得點擊鍵
    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }
}
```
>顯示結果

![](https://i.imgur.com/i1c7si9.png)

可藉由內嵌縮短程式碼
```java=
package learning.AWT;

import java.awt.*;
import java.awt.event.*;

public class Java_13_MouseEvent extends Frame{
    Java_13_MouseEvent(){
        this.setLocation(100,50);
        this.setTitle("Mouse Clicker");
        this.setSize(500,500);
        this.setVisible(true);
        this.setLayout(null);
        this.addWindowListener(new WindowAdapter() { //此處是使用內嵌類別委任視窗事件
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        this.addMouseListener(new MouseAdapter() { //此處是使用內嵌類別委任滑鼠事件
            public void mouseClicked(MouseEvent e) {
                int x, y;
                Graphics g;
                g = getGraphics(); //取得繪圖物件
                x = e.getX();
                y = e.getY();
                g.fillRect(x, y, 10, 10); //設定點擊位置的方塊大小
                System.out.println(e.getButton()); //可取得點擊鍵
            }
        });
    }

    public static void main(String[] args) {
        Java_13_MouseEvent frm = new Java_13_MouseEvent();
    }
}
```
# 滑鼠滾輪事件
==實作== : 做一視窗,記錄使用者點擊和移動滑鼠軌跡

```java=
package learning.AWT;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Java_13_MouseMotion extends Frame {
    Java_13_MouseMotion(){
        this.setLocation(100,50);
        this.setTitle("Mouse Motion");
        this.setSize(500,500);
        this.setVisible(true);
        this.setLayout(null);
        this.addWindowListener(new WindowAdapter() { //此處是使用內嵌類別委任視窗事件
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    public static void main(String[] args) {
        Java_13_MouseMotion frm = new Java_13_MouseMotion();
        frm.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent e) {
                int x,y;
                Graphics g;
                x=e.getX();
                y=e.getY();
                g=frm.getGraphics();
                g.fillRect(x,y,2,2);
                frm.setTitle("x="+x+"y="+y);
            }
            public void mouseMoved(MouseEvent e){
                Point p; //取得座標,美觀用
                p=e.getPoint();
                frm.setTitle(p.toString());
            }
        });
    }
}
```
>顯示結果

![](https://i.imgur.com/c6MrKtC.png)

# 鍵盤事件
## 常用方法
* getKetCode() 回傳按鍵的Unicode值
* getKeyChar() 回傳按鍵字符
* isAltDown() 判斷是否按下Alt
* isShiftDown() 判斷是否按下Shift
* isControlDown() 判斷是否按下Ctrl

==實作== : 寫一程式,使鍵盤的上下左右可以移動物件,使用Pgup,Pgdn放大與縮小元件
```java=
package learning.AWT;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Java_13_Key extends Frame implements ActionListener , KeyListener {
    Button btn = new Button("Exit");
    Java_13_Key(){
        this.setLocation(100,50);
        this.setTitle("Key");
        this.setSize(500,500);
        this.setVisible(true);
        this.setLayout(null);
        btn.setLocation(250,250);
        btn.setSize(50,50);
        this.add(btn);
        btn.addActionListener(this);
        btn.addKeyListener(this);
    }

    public static void main(String[] args) {
        Java_13_Key frm = new Java_13_Key();
    }
    public void actionPerformed(ActionEvent e) {
        System.exit(0); //btn Action
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        System.out.println("KeyCode:"+e.getKeyCode());
        System.out.println("KeyChar:"+e.getKeyChar());

        int x,y,w,h;
        x = btn.getX();
        y = btn.getY();
        w = btn.getWidth();
        h = btn.getHeight();
        if(e.getKeyCode() == KeyEvent.VK_RIGHT){
            x+=10;
        }
        else if(e.getKeyCode() == KeyEvent.VK_LEFT){
            x-=10;
        }
        else if(e.getKeyCode() == KeyEvent.VK_UP){ //座標Y與一班座標系相反
            y-=10;
        }
        else if(e.getKeyCode() == KeyEvent.VK_DOWN){
            y+=10;
        }
        else if(e.getKeyCode() == KeyEvent.VK_PAGE_UP){
            w+=10;
            h+=10;
        }
        else if(e.getKeyCode() == KeyEvent.VK_PAGE_DOWN){
            w-=10;
            h-=10;
        }
        btn.setBounds(x,y,w,h); //重設位置大小
    }

    public void keyReleased(KeyEvent e) {
    }
}
```
> 顯示結果

![](https://i.imgur.com/oOy2rdu.png)
-
![](https://i.imgur.com/8oIbm66.png)