2019獨角獸企業重金招聘Python工程師標準>>>
一、AWT介紹
所有的可以顯示出來的圖形元素都稱為Component,Component代表了所有的可見的圖形元素,Component里面有一種比較特殊的圖形元素叫Container,Container(容器)在圖形界面里面是一種可以容納其它Component元素的一種容器,Container本身也是一種Component的,Container里面也可以容納別的Container。
Container里面又分為Window和Pannel,Window是可以獨立顯示出來的,平時我們看到的各種各樣的應用程序的窗口都可以稱為Window,Window作為一個應用程序窗口獨立顯示出來,Pannel也可以容納其它的圖形元素,但一般看不見Pannel,Pannel不能作為應用程序的獨立窗口顯示出來,Pannel要想顯示出來就必須得把自己裝入到Window里面才能顯示出來。
Pannel應用比較典型的就是Applet(JAVA的頁面小應用程序),現在基本上已經不用了,AJAX和JAVASCRIPT完全取代了它的應用。
Window本身又可以分為Frame和Dialog,Frame就是我們平時看到的一般的窗口,而Dialog則是那些需要用戶進行了某些操作(如點擊某個下拉菜單的項)才出現的對話框,這種對話框就是Dialog。
二、組件和容器(Component和Container)
2.1.Frame
Frame范例:
1 package cn.javastudy.summary;
2
3 /**學習JAVA的GUI編程編寫的第一個圖形界面窗口*/
4 import java.awt.*;
5
6 public class TestFrame {
7 public static void main(String args[]) {
8 Frame f = new Frame("我的第一個JAVA圖形界面窗口");
9 /*
10 * 這里只是在內存里面創建了一個窗口對象 還不能真正顯示出來然我們看到
11 */
12 f.setBackground(Color.blue);// 設置窗體的背景顏色
13 // blue是Color類里面的一個靜態常量,可以使用“類名.靜態常量名”來訪問
14 f.setVisible(true);// 設置窗體是否可見
15 /*
16 * 要想看到在內存里面創建出來的窗口對象, 必須調用setVisble()方法,并且把參數true傳入才能看得見窗體 如果傳入的參數是false,那么窗體也是看不見的
17 */
18 f.setSize(400, 400);// 設置窗體的初始大小
19 f.setLocation(200, 200);// 設置窗體出現時的位置,如果不設置則默認在左上角(0,0)位置顯示
20 f.setResizable(false);
21 /*
22 * 設置窗體能否被改變大小,設置為false后表示不能改變窗體的顯示大小 這里將窗體顯示的大小設置為200X200,那么窗體的顯示只能是這個大小了,不能再使用鼠標拖大或者縮小
23 */
24 }
25 }
運行結果如下:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 public class TestMultiFrame{
5 public static void main(String args[]){
6 MyFrame f1 = new MyFrame(100,100,200,200,Color.BLUE);
7 MyFrame f2 = new MyFrame(300,100,200,200,Color.YELLOW);
8 MyFrame f3 = new MyFrame(100,300,200,200,Color.GREEN);
9 MyFrame f4 = new MyFrame(300,300,200,200,Color.MAGENTA);
10 }
11 }
12 /*自定義一個類MyFrame,并且從Frame類繼承
13 這樣MyFrame類就擁有了Frame類的一切屬性和方法
14 并且MyFrame類還可以自定義屬性和方法
15 因此使用從Frame類繼承而來的自定義類來創建圖形窗口比直接使用Frame類來創建圖形窗口要靈活
16 所以一般使用從Frame類繼承而來的自定義類創建圖形窗口界面比較好,
17 不推薦直接使用Frame類來創建圖形窗口界面
18 */
19 class MyFrame extends Frame{
20 static int id = 0;
21 //定義一個靜態成員變量id,用來記錄創建出來的窗口的數目
22 MyFrame(int x,int y,int w,int h,Color color){
23 //自定義構成方法,在構造方法體內使用super調用父類Frame的構造方法
24 super("MyFrame"+(++id));
25 setBackground(color);
26 /*使用從父類Frame繼承而來的方法設置窗體的相關屬性*/
27 setLayout(null);
28 setBounds(x,y,w,h);
29 setVisible(true);
30 }
31 }
運行結果:
2.2.Panel
Panel范例:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 public class TestPanel{
5 public static void main(String args[]){
6 Frame f = new Frame("JAVA Fram With Panel");
7 Panel p = new Panel(null);
8 f.setLayout(null);
9 f.setBounds(300,300,500,500);//這里設置的坐標(300,300)是相對于整個屏幕的
10 f.setBackground(new Color(0,0,102));//設置背景顏色時使用三基色(紅,綠,藍)的比例來調配背景色
11 p.setBounds(50,50,400,400);//這里設置的坐標(50,50)是相對于Frame窗體的
12 p.setBackground(new Color(204,204,255));
13 f.add(p);//把Panel容器裝入到Frame容器中,使其能在Frame窗口中顯示出來
14 f.setVisible(true);
15 }
16 }
運行結果如下:
三、布局管理器
3.1.第一種布局管理器——FlowLayout
測試代碼:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4
5 public class TestFlowLayout {
6 public static void main(String args[]) {
7 Frame f = new Frame("FlowLayout");
8 /*
9 * 使用Button類創建按鈕 按鈕類的其中一個構造方法:Button(String label) label為按鈕顯示的文本
10 */
11 Button btn1 = new Button("button1");
12 Button btn2 = new Button("button2");
13 Button btn3 = new Button("button3");
14 /* setLayout方法的定義:public void setLayout(LayoutManager mgr) */
15 f.setLayout(new FlowLayout());// 使用流水(Flow)線般的布局
16 /* 使用了布局管理器FlowLayout,這里的布局采用默認的水平居中模式 */
17 // f.setLayout(new FlowLayout(FlowLayout.LEFT));
18 /* 這里在布局的時候使用了FlowLayout.LEFT常量,這樣就將按鈕設置為左對齊 */
19 // f.setLayout(new FlowLayout(FlowLayout.RIGHT));
20 /* 這里在布局的時候使用了FlowLayout.RIGHT常量,這樣就將按鈕設置為右對齊 */
21 f.add(btn1);// 把創建出來的按鈕放置到Frame窗體中
22 f.add(btn2); // 這里并沒有設置按鈕的大小與位置
23 f.add(btn3); // 設置按鈕的大小與位置都是由布局管理器來做的
24 f.setVisible(true);
25 f.setSize(200, 200);
26 }
27 }
運行結果如下:
3.2.第二種布局管理器——BorderLayout
?
測試代碼:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4
5 public class TestBorderLayout {
6 public static void main(String args[]) {
7 Frame f = new Frame("BorderLayout");
8 Button btnEast = new Button("East");
9 Button btnWest = new Button("West");
10 Button btnSouth = new Button("South");
11 Button btnNorth = new Button("North");
12 Button btnCenter = new Button("Center");
13 /*
14 * 把按鈕放置到Frame窗體時按照東西南北中五個方向排列好 推薦使用這種方式去排列窗體元素,
15 * 這樣容易檢查出錯誤 因為這樣寫如果寫錯了編譯器會提示出錯
16 */
17 f.add(btnEast, BorderLayout.EAST);
18 f.add(btnWest, BorderLayout.WEST);
19 f.add(btnSouth, BorderLayout.SOUTH);
20 f.add(btnNorth, BorderLayout.NORTH);
21 f.add(btnCenter, BorderLayout.CENTER);
22 /*
23 * 也可以使用這樣的方式排列按鈕 在把按鈕放置到Frame窗體時使用方向定位的字符串指定按鈕的放置位置
24 * 這種使用方向定位的字符串指定按鈕的放置方式不推薦使用 一旦寫錯了方向字符串就不好檢查出來
25 * 因為即使是寫錯了仍然可以編譯通過
26 */
27 /*
28 * f.add(btnEast,"East");
29 * f.add(btnWest,"West");
30 * f.add(btnSouth,"South");
31 * f.add(btnNorth,"North");
32 * f.add(btnCenter,"Center");
33 */
34 f.setSize(200, 200);
35 f.setVisible(true);
36 }
37 }
運行結果:
3.3.第三種布局管理器——GridLayout(表格布局管理器)
測試代碼:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4
5 public class TestGridLayout {
6 public static void main(String args[]) {
7 Frame f = new Frame("GridLayout");
8 Button btn1 = new Button("btn1");
9 Button btn2 = new Button("btn2");
10 Button btn3 = new Button("btn3");
11 Button btn4 = new Button("btn4");
12 Button btn5 = new Button("btn5");
13 Button btn6 = new Button("bnt6");
14 f.setLayout(new GridLayout(3, 2));
15 /* 把布局劃分成3行2列的表格布局形式 */
16 f.add(btn1);
17 f.add(btn2);
18 f.add(btn3);
19 f.add(btn4);
20 f.add(btn5);
21 f.add(btn6);
22 f.pack();
23 f.setVisible(true);
24 }
25 }
運行結果:
3.4.布局練習
這幾種布局管理器可以設置在Frame里面,也可以設置在Panel里面,而Panel本身也可以加入到Frame里面,因此通過Frame與Panel的嵌套就可以實現比較復雜的布局
實現代碼:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 public class TestTenButtons{
5 public static void main(String args[]){
6 /*這里主要是對顯示窗體進行設置*/
7 Frame f = new Frame("布局管理器的嵌套使用");
8 f.setLayout(new GridLayout(2,1));//把整個窗體分成2行1列的表格布局
9 f.setLocation(300,400);
10 f.setSize(400,300);
11 f.setVisible(true);
12 f.setBackground(new Color(204,204,255));
13 /*這里主要是對Panel進行布局的設置*/
14 Panel p1 = new Panel(new BorderLayout());
15 Panel p2 = new Panel(new GridLayout(2,1));//p2使用2行1列的表格布局
16 Panel p3 = new Panel(new BorderLayout());
17 Panel p4 = new Panel(new GridLayout(2,2));//p4使用2行2列的表格布局
18 /*這里主要是把按鈕元素加入到Panel里面*/
19 p1.add(new Button("East(p1-東)"),BorderLayout.EAST);
20 p1.add(new Button("West(p1-西)"),BorderLayout.WEST);
21 p2.add(new Button("p2-Button1"));
22 p2.add(new Button("p2-Button2"));
23 /*p1里面嵌套p2,把p2里面的按鈕作為p的中間部分裝入到p1里面*/
24 p1.add(p2,BorderLayout.CENTER);//把p2作為元素加入到p1里面
25
26 p3.add(new Button("East(p3-東)"),BorderLayout.EAST);
27 p3.add(new Button("West(p3-西)"),BorderLayout.WEST);
28 for(int i=0;i<4;i++){
29 p4.add(new Button("p4-Button"+i));
30 }
31 /*p3里面嵌套p4,把p4里面的按鈕作為p的中間部分裝入到p3里面*/
32 p3.add(p4,BorderLayout.CENTER);
33
34 f.add(p1);//把Panel裝入Frame里面,以便于在Frame窗體中顯示出來
35 f.add(p3);
36
37 }
38 }
運行結果:
四、布局管理器總結
一、事件監聽
測試代碼一:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TestActionEvent {
7 public static void main(String args[]) {
8 Frame f = new Frame("TestActionEvent");
9 Button btn = new Button("Press Me");
10 Monitor m = new Monitor();/* 創建一個監聽對象 */
11 btn.addActionListener(m);
12 /*
13 * 把監聽加入到按鈕里面,監聽按鈕的動作, 當按鈕觸發打擊事件時,就會返回一個監聽對象e 然后就會自動執行actionPerformed方法
14 */
15 f.add(btn, BorderLayout.CENTER);
16 f.pack();
17 addWindowClosingEvent(f);
18 /* 調用這個方法可以自動給Frame窗體里面的子圖形元素一個合適的初始大小 */
19 f.setVisible(true);
20 }
21
22 /**
23 * 點擊窗體上的關閉按鈕關閉窗體
24 * @param f
25 */
26 private static void addWindowClosingEvent(Frame f){
27 f.addWindowListener(new WindowAdapter() {
28 @Override
29 public void windowClosing(WindowEvent arg0) {
30 System.exit(0);
31 }
32
33 });
34 }
35 }
36
37 /*
38 * 自定義Monitor(監聽)類實現事件監聽接口ActionListener 一個類要想成為監聽類,那么必須實現ActionListener接口
39 */
40 class Monitor implements ActionListener {
41 /* 重寫ActionListener接口里面的actionPerformed(ActionEvent e)方法 */
42 public void actionPerformed(ActionEvent e) {
43 System.out.println("A Button has been Pressed");
44 }
45 }
?測試代碼二:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5 public class TestActionEvent2{
6 public static void main(String args[]){
7 Frame f = new Frame("TestActionEvent");
8 Button btn1 = new Button("start");
9 Button btn2 = new Button("stop");
10 Monitor2 m2 = new Monitor2();//創建監聽對象
11 btn1.addActionListener(m2);
12 /*一個監聽對象同時監聽兩個按鈕的動作*/
13 btn2.addActionListener(m2);
14 btn2.setActionCommand("GameOver");//設置btn2的執行單擊命令后的返回信息
15 f.add(btn1,BorderLayout.NORTH);
16 f.add(btn2,BorderLayout.CENTER);
17
18 f.pack();
19 f.setVisible(true);
20 }
21 }
22
23 class Monitor2 implements ActionListener{
24 public void actionPerformed(ActionEvent e){
25 System.out.println("a button has been pressed,"+"the relative info is:\n"+e.getActionCommand());
26 /*使用返回的監聽對象e調用getActionCommand()方法獲取兩個按鈕執行單擊命令后的返回信息
27 根據返回信息的不同區分開當前操作的是哪一個按鈕,btn1沒有使用setActionCommand()方法設置
28 則btn1返回的信息就是按鈕上顯示的文本*/
29 }
30 }
二、TextField事件監聽
測試代碼:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TestTextField {
7 public static void main(String args[]) {
8 new MyFrameTextField();
9 }
10 }
11
12 class MyFrameTextField extends Frame {
13 MyFrameTextField() {
14 TextField tf = new TextField();
15 add(tf);
16 tf.addActionListener(new Monitor3());
17 tf.setEchoChar('*');
18 /*
19 * 這個setEchoChar()方法是設置文本框輸入時顯示的字符,這里設置為*,
20 * 這樣輸入任何內容就都以*顯示出來,不過打印出來時依然可以看到輸入的內容
21 */
22 setVisible(true);
23 pack();
24 }
25 }
26
27 class Monitor3 implements ActionListener {
28 /*
29 * 接口里面的所有方法都是public(公共的)
30 * 所以從API文檔復制void actionPerformed(ActionEvent e)時 要在void前面加上public
31 */
32 public void actionPerformed(ActionEvent e) {
33 /* 事件的相關信息都封裝在了對象e里面,通過對象e的相關方法就可以獲取事件的相關信息 */
34 TextField tf = (TextField) e.getSource();
35 /*
36 * getSource()方法是拿到事件源,注意:拿到這個事件源的時候,
37 * 是把它當作TextField的父類來對待
38 * getSource()方法的定義是:“public Object getSource()”返回值是一個Object對象,
39 * 所以要強制轉換成TextField類型的對象
40 * 在一個類里面想訪問另外一個類的事件源對象可以通過getSource()方法
41 */
42 System.out.println(tf.getText());// tf.getText()是取得文本框里面的內容
43 tf.setText("");// 把文本框里面的內容清空
44 }
45 }
使用TextField類實現簡單的計算器
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TestMath {
7 public static void main(String args[]) {
8 new TFFrame();
9 }
10 }
11
12 /* 這里主要是完成計算器元素的布局 */
13 class TFFrame extends Frame {
14 TFFrame() {
15 /*
16 * 創建3個文本框,并指定其初始大小分別為10個字符和15個字符的大小 這里使用的是TextField類的另外一種構造方法 public TextField(int columns)
17 */
18 TextField num1 = new TextField(10);
19 TextField num2 = new TextField(10);
20 TextField num3 = new TextField(15);
21 /* 創建等號按鈕 */
22 Button btnEqual = new Button("=");
23 btnEqual.addActionListener(new MyMonitor(num1, num2, num3));
24 /* 給等號按鈕加上監聽,讓點擊按鈕后有響應事件發生 */
25 Label lblPlus = new Label("+");
26 /* “+”是一個靜態文本,所以使用Label類創建一個靜態文本對象 */
27 setLayout(new FlowLayout());
28 /* 把Frame默認的BorderLayout布局改成FlowLayout布局 */
29 add(num1);
30 add(lblPlus);
31 add(num2);
32 add(btnEqual);
33 add(num3);
34 pack();
35 setVisible(true);
36
37 }
38 }
39
40 class MyMonitor implements ActionListener {
41 TextField num1, num2, num3;
42
43 /*
44 * 為了使對按鈕的監聽能夠對文本框也起作用,
45 * 所以在自定義類MyMonitor里面定義三個TextField類型的對象 num1,num2,num3,
46 * 并且定義了MyMonitor類的一個構造方法 這個構造方法帶有三個TextField類型的參數,
47 * 用于接收 從TFFrame類里面傳遞過來的三個TextField類型的參數
48 * 然后把接收到的三個TextField類型的參數賦值給在本類中聲明的 三個TextField類型的參數num1,num2,num3 然后再在actionPerformed()方法里面處理num1,num2,num3
49 */
50 public MyMonitor(TextField num1, TextField num2, TextField num3) {
51 this.num1 = num1;
52 this.num2 = num2;
53 this.num3 = num3;
54 }
55
56 public void actionPerformed(ActionEvent e) {
57 /* 事件的相關信息都封裝在了對象e里面,通過對象e的相關方法就可以獲取事件的相關信息 */
58 int n1 = Integer.parseInt(num1.getText());/* num1對象調用getText()方法取得自己顯示的文本字符串 */
59 int n2 = Integer.parseInt(num2.getText());/* num2對象調用getText()方法取得自己顯示的文本字符串 */
60 num3.setText("" + (n1 + n2));/* num3對象調用setText()方法設置自己的顯示文本 */
61 num1.setText("");
62 /* 計算結束后清空num1,num2文本框里面的內容 */
63 num2.setText("");
64 // num3.setText(String.valueOf((n1+n2)));
65 /* 字符串與任意類型的數據使用“+”連接時得到的一定是字符串,
66 * 這里使用一個空字符串與int類型的數連接,這樣就可以直接把(n1+n2)得到的int類型的數隱式地轉換成字符串了,
67 * 這是一種把別的基礎數據類型轉換成字符串的一個小技巧。
68 * 也可以使用“String.valueOf((n1+n2))”把(n1+n2)的和轉換成字符串
69 */
70 }
71 }
JAVA里面的經典用法:在一個類里面持有另外一個類的引用
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TestMath1 {
7 public static void main(String args[]) {
8 new TTMyFrame().launchFrame();
9 /* 創建出TTMyFrame對象后調用lauchFrame()方法把計算器窗體顯示出來 */
10 }
11 }
12
13 /* 做好計算器的窗體界面 */
14 class TTMyFrame extends Frame {
15 /* 把設計計算器窗體的代碼封裝成一個方法 */
16 TextField num1, num2, num3;
17
18 public void launchFrame() {
19 num1 = new TextField(10);
20 num2 = new TextField(15);
21 num3 = new TextField(15);
22 Label lblPlus = new Label("+");
23 Button btnEqual = new Button("=");
24 btnEqual.addActionListener(new MyMonitorbtnEqual(this));
25 setLayout(new FlowLayout());
26 add(num1);
27 add(lblPlus);
28 add(num2);
29 add(btnEqual);
30 add(num3);
31 pack();
32 setVisible(true);
33 }
34 }
35
36 /*
37 * 這里通過取得TTMyFrame類的引用,然后使用這個引用去訪問TTMyFrame類里面的成員變量
38 * 這種做法比上一種直接去訪問TTMyFrame類里面的成員變量要好得多,
39 * 因為現在不需要知道 TTMyFrame類里面有哪些成員變量了,
40 * 現在要訪問TTMyFrame類里面的成員變量,直接使用 TTMyFrame類對象的引用去訪問即可,
41 * 這個TTMyFrame類的對象好比是一個大管家, 而我告訴大管家,我要訪問TTMyFrame類里面的那些成員變量,
42 * 大管家的引用就會去幫我找,不再需要我自己去找了。
43 * 這種在一個類里面持有另一個類的引用的用法是一種非常典型的用法
44 * 使用獲取到的引用就可以在一個類里面訪問另一個類的所有成員了
45 */
46 class MyMonitorbtnEqual implements ActionListener {
47 TTMyFrame ttmf = null;
48
49 public MyMonitorbtnEqual(TTMyFrame ttmf) {
50 this.ttmf = ttmf;
51 }
52
53 public void actionPerformed(ActionEvent e) {
54 int n1 = Integer.parseInt(ttmf.num1.getText());
55 int n2 = Integer.parseInt(ttmf.num2.getText());
56 ttmf.num3.setText("" + (n1 + n2));
57 ttmf.num1.setText("");
58 ttmf.num2.setText("");
59 }
60 }
運行結果如下:
三、內部類
內部類的使用范例:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TestMath3 {
7
8 public static void main(String args[]) {
9 new MyMathFrame().launchFrame();
10 }
11 }
12
13 class MyMathFrame extends Frame {
14 TextField num1, num2, num3;
15
16 public void launchFrame() {
17 num1 = new TextField(10);
18 num2 = new TextField(15);
19 num3 = new TextField(15);
20 Label lblPlus = new Label("+");
21 Button btnEqual = new Button("=");
22 btnEqual.addActionListener(new MyMonitor());
23 setLayout(new FlowLayout());
24 add(num1);
25 add(lblPlus);
26 add(num2);
27 add(btnEqual);
28 add(num3);
29 pack();
30 setVisible(true);
31 }
32
33 /*
34 * 這個MyMonitor類是內部類,它在MyFrame類里面定義 MyFrame類稱為MyMonitor類的包裝類
35 */
36 /*
37 * 使用內部類的好處:
38 * 第一個巨大的好處就是可以暢通無阻地訪問外部類(即內部類的包裝類)的所有成員變量和方法
39 * 如這里的在MyFrame類(外部類)定義的三個成員變量num1,num2,num3,
40 * 在MyMonitor(內部類)里面就可以直接訪問
41 * 這相當于在創建外部類對象時內部類對象默認就擁有了一個外部類對象的引用
42 */
43 private class MyMonitor implements ActionListener {
44 public void actionPerformed(ActionEvent e) {
45 int n1 = Integer.parseInt(num1.getText());
46 int n2 = Integer.parseInt(num2.getText());
47 num3.setText("" + (n1 + n2));
48 num1.setText("");
49 num2.setText("");
50 }
51 }
52 }
內部類帶來的巨大好處是:
- 可以很方便地訪問外部類定義的成員變量和方法
- 當某一個類不需要其他類訪問的時候就把這個類聲明為內部類。
四、Graphics 類
?測試代碼:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 public class TestPaint{
5 public static void main(String args[]){
6 new MyPaint().launchFrame();
7 /*在main()方法里面并沒有顯示調用paint(Graphics g)方法
8 可是當創建出Frame窗體后卻可以看到Frame窗體上畫出了
9 圓和矩形,這是因為paint()方法是一個比較特殊的方法
10 在創建Frame窗體時會自動隱式調用
11 當我們把Frame窗體最小化又再次打開時,又會再次調用
12 paint()方法重新把圓和矩形在Frame窗體上畫出來
13 即每次需要重畫Frame窗體的時候就會自動調用paint()方法*/
14 }
15 }
16
17 class MyPaint extends Frame{
18 public void launchFrame(){
19 setBounds(200,200,640,480);
20 setVisible(true);
21 }
22
23 public void paint(Graphics g){
24 /*paint(Graphics g)方法有一個Graphics類型的參數g
25 我們可以把這個g當作是一個畫家,這個畫家手里拿著一只畫筆
26 我們通過設置畫筆的顏色與形狀來畫出我們想要的各種各樣的圖像*/
27 /*設置畫筆的顏色*/
28 g.setColor(Color.red);
29 g.fillOval(100,100,100,100);/*畫一個實心橢圓*/
30 g.setColor(Color.green);
31 g.fillRect(150,200,200,200);/*畫一個實心矩形*/
32 /*這下面的兩行代碼是為了寫程序的良好編程習慣而寫的
33 前面設置了畫筆的顏色,現在就應該把畫筆的初始顏色恢復過來
34 就相當于是畫家用完畫筆之后把畫筆上的顏色清理掉一樣*/
35 Color c = g.getColor();
36 g.setColor(c);
37 }
38 }
運行結果:
五、鼠標事件適配器
測試代碼:
1 package cn.galc.test;
2
3 import java.awt.*;
4 import java.awt.event.*;
5 import java.util.*;
6 public class MyMouseAdapter{
7 public static void main(String args[]) {
8 new MyFrame("drawing...");
9 }
10 }
11
12 class MyFrame extends Frame {
13 ArrayList points = null;
14 MyFrame(String s) {
15 super(s);
16 points = new ArrayList();
17 setLayout(null);
18 setBounds(300,300,400,300);
19 this.setBackground(new Color(204,204,255));
20 setVisible(true);
21 this.addMouseListener(new Monitor());
22 }
23
24 public void paint(Graphics g) {
25 Iterator i = points.iterator();
26 while(i.hasNext()){
27 Point p = (Point)i.next();
28 g.setColor(Color.BLUE);
29 g.fillOval(p.x,p.y,10,10);
30
31 }
32 }
33
34 public void addPoint(Point p){
35 points.add(p);
36 }
37 }
38
39 class Monitor extends MouseAdapter {
40 public void mousePressed(MouseEvent e) {
41 MyFrame f = (MyFrame)e.getSource();
42 f.addPoint(new Point(e.getX(),e.getY()));
43 f.repaint();
44 }
45 }
六、window事件
?測試代碼:
1 package cn.galc.test;
2
3 import java.awt.*;
4 import java.awt.event.*;
5 public class TestWindowClose{
6 public static void main(String args[]){
7 new WindowFrame("關閉WindowFrame");
8 }
9 }
10
11 class WindowFrame extends Frame{
12 public WindowFrame(String s){
13 super(s);
14 setBounds(200,200,400,300);
15 setLayout(null);
16 setBackground(new Color(204,204,255));
17 setVisible(true);
18 this.addWindowListener(new WindowMonitor());
19 /*監聽本窗體的動作,把所有的動作信息封裝成一個對象傳遞到監聽類里面*/
20
21 this.addWindowListener(
22 /*在一個方法里面定義一個類,這個類稱為局部類,也叫匿名的內部類,
23 這里的{……代碼……}里面的代碼很像一個類的類體,只不過這個類沒有名字,所以叫匿名類
24 在這里是把這個匿名類當成WindowAdapter類來使用,語法上這樣寫的本質意義是相當于這個匿名類
25 從WindowAdapter類繼承,現在new了一個匿名類的對象出來然后把這個對象當成WindowAdapter來使用
26 這個匿名類出了()就沒有人認識了*/
27 new WindowAdapter(){
28 public void windowClosing(WindowEvent e){
29 setVisible(false);
30 System.exit(-1);
31 }
32 }
33 );
34 }
35
36 /*這里也是將監聽類定義為內部類*/
37 class WindowMonitor extends WindowAdapter{
38 /*WindowAdapter(Window適配器)類實現了WindowListener監聽接口
39 重寫了WindowListener接口里面的所有方法
40 如果直接使用自定義WindowMonitor類直接去
41 實現WindowListener接口,那么就得要重寫WindowListener接口
42 里面的所有方法,但現在只需要用到這些方法里面的其中一個方法
43 所以采用繼承實現WindowListener監聽接口的一個子類
44 并重寫這個子類里面需要用到的那個方法即可
45 這種做法比直接實現WindowListener監聽接口要重寫很多個用不到的方法要簡潔方便得多*/
46 /*重寫需要用到的windowClosing(WindowEvent e)方法*/
47 public void windowClosing(WindowEvent e){
48 setVisible(false);/*將窗體設置為不顯示,即可實現窗體關閉*/
49 System.exit(0);/*正常退出*/
50 }
51 }
52 }
七、鍵盤響應事件——KeyEvent
測試代碼:
1 package cn.galc.test;
2
3 import java.awt.*;
4 import java.awt.event.*;
5 public class TestKeyEvent{
6 public static void main(String args[]){
7 new KeyFrame("鍵盤響應事件");
8 }
9 }
10
11 class KeyFrame extends Frame{
12 public KeyFrame(String s){
13 super(s);
14 setBounds(200,200,400,300);
15 setLayout(null);
16 setVisible(true);
17 addKeyListener(new KeyMonitor());
18 }
19 /*把自定義的鍵盤的監聽類定義為內部類
20 這個監聽類從鍵盤適配器KeyAdapter類繼承
21 從KeyAdapter類繼承也是為了可以簡潔方便
22 只需要重寫需要用到的方法即可,這種做法比
23 直接實現KeyListener接口要簡單方便,如果
24 直接實現KeyListener接口就要把KeyListener
25 接口里面的所有方法重寫一遍,但真正用到的
26 只有一個方法,這樣重寫其他的方法但又用不到
27 難免會做無用功*/
28 class KeyMonitor extends KeyAdapter{
29 public void keyPressed(KeyEvent e){
30 int keycode = e.getKeyCode();
31 /*使用getKeyCode()方法獲取按鍵的虛擬碼*/
32 /*如果獲取到的鍵的虛擬碼等于up鍵的虛擬碼
33 則表示當前按下的鍵是up鍵
34 KeyEvent.VK_UP表示取得up鍵的虛擬碼
35 鍵盤中的每一個鍵都對應有一個虛擬碼
36 這些虛擬碼在KeyEvent類里面都被定義為靜態常量
37 所以可以使用“類名.靜態常量名”的形式訪問得到這些靜態常量*/
38 if(keycode == KeyEvent.VK_UP){
39 System.out.println("你按的是up鍵");
40 }
41 }
42 }
43 }
44 /*鍵盤的處理事件是這樣的:每一個鍵都對應著一個虛擬的碼,
45 當按下某一個鍵時,系統就會去找這個鍵對應的虛擬的碼,以此來確定當前按下的是那個鍵
46 */