###### 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)