Java基礎學習總結(23)——GUI編程

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

一、AWT介紹

  

  所有的可以顯示出來的圖形元素都稱為ComponentComponent代表了所有的可見的圖形元素,Component里面有一種比較特殊的圖形元素叫ContainerContainer(容器)在圖形界面里面是一種可以容納其它Component元素的一種容器,Container本身也是一種Component的,Container里面也可以容納別的Container

  Container里面又分為WindowPannelWindow是可以獨立顯示出來的,平時我們看到的各種各樣的應用程序的窗口都可以稱為WindowWindow作為一個應用程序窗口獨立顯示出來,Pannel也可以容納其它的圖形元素,但一般看不見PannelPannel不能作為應用程序的獨立窗口顯示出來,Pannel要想顯示出來就必須得把自己裝入到Window里面才能顯示出來。

  Pannel應用比較典型的就是Applet(JAVA的頁面小應用程序),現在基本上已經不用了,AJAXJAVASCRIPT完全取代了它的應用。

  Window本身又可以分為FrameDialogFrame就是我們平時看到的一般的窗口,而Dialog則是那些需要用戶進行了某些操作(如點擊某個下拉菜單的項)才出現的對話框,這種對話框就是Dialog

二、組件和容器(ComponentContainer)

  

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里面,因此通過FramePanel的嵌套就可以實現比較復雜的布局

實現代碼:

復制代碼
 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 }
復制代碼

內部類帶來的巨大好處是:

  1. 可以很方便地訪問外部類定義的成員變量和方法
  2. 當某一個類不需要其他類訪問的時候就把這個類聲明為內部類。

四、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 */
復制代碼

轉載于:https://my.oschina.net/zhanghaiyang/blog/594979

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/279360.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/279360.shtml
英文地址,請注明出處:http://en.pswp.cn/news/279360.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

spring-使用配置文件完成JdbcTemplate操作數據庫

一、創建spring項目項目名稱&#xff1a;spring101302二、在項目上添加jar包1.在項目中創建lib目錄/lib2.在lib目錄下添加spring支持commons-logging.jarjunit-4.10.jarlog4j.jarmysql-connector-java-5.1.18-bin.jarspring-beans-3.2.0.RELEASE.jarspring-context-3.2.0.RELEA…

瓦片經緯度及行列號轉換_Slippy map tilenames(瓦片和經緯度換算)

Slippy map tilenames(瓦片和經緯度換算)This article describes the file naming conventions for theSlippy Map application.Tiles are 256 256 pixel PNG filesEachzoom level is a directory, each column is a subdirectory, andeach tile in that column is a fileFilen…

在Windows 7或Vista(或Windows 8.x,Sorta)上禁用Aero

The Windows Aero Glass interface for Windows 7 or Vista requires a decent video card, you won’t be able to use it on an old clunker computer. For those worried about performance, sometimes squeezing every last drop requires disabling Aero. Windows 7或Vist…

一個簡單的JDBC通用工具

支持多種數據庫&#xff0c;統一方式產生連接&#xff0c;最優化、最簡單方式釋放資源。歡迎拍磚&#xff01;import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.sql.*; import java.util.List; import java.util.Properties…

sfm點云代碼_VisualSFM使用方法與心得

關于VisualSfM的更多內容組合多個模型(What if VisualSFM produces multiple models?)&#xff1a;按照上述步驟進行稀疏重建后&#xff0c;理論上可以得到很好的模型。如果結果產生了多個模型&#xff0c;要想把多個模型合成成一個&#xff0c;點擊菜單中的“SfM->More Fu…

macos mojave_使Ubuntu看起來像macOS Mojave的黑暗模式

macos mojaveIf you’re a Linux user who likes the look of the dark mode coming in macOS Mojave, you’re in luck: there’s a GTK theme just for you. 如果您是Linux用戶&#xff0c;并且喜歡macOS Mojave中的黑暗模式外觀&#xff0c;那么您很幸運&#xff1a;這里有一…

html的列表標簽

列表一般應用在布局中的新聞標題列表和文章標題列表以及網頁菜單等。 例如這個就是一個列表&#xff1a; 列表標簽有幾種&#xff0c;分別是有序列表&#xff0c;無序列表&#xff0c;定義列表。 有序列表<!DOCTYPE html> <html lang"en"> <head>&…

撬鎖錘怎么用_安全錘是啥?消防蜀黍教你怎么選?如何快速破拆逃生?

逃生錘又叫安全錘&#xff0c;生活中很多地方都可以看到&#xff0c;公交車、地鐵窗邊都少不了它們的身影它的款式也是五花八門&#xff0c;那么問題來了當遇到突發狀況被困車內時&#xff0c;哪種破窗工具最有效&#xff1f;又該如何快速逃生自救&#xff1f;近日&#xff0c;…

WSUS技術概覽

WSUS新功能展示: 支持更多微軟產品更新-->Windows Office MS SQL Server Exchange ......基于產品及分類篩選下載更新的能力更多語言支持定位更新目標計算機或計算機組的能力-->分發前,測試更新; 保護運行特定應用程序的計算機; 靈活使用Deadline; ...... 見下…

Java基礎學習總結(16)——Java制作證書的工具keytool用法總結

2019獨角獸企業重金招聘Python工程師標準>>> 一、keytool的概念 keytool 是個密鑰和證書管理工具。它使用戶能夠管理自己的公鑰/私鑰對及相關證書&#xff0c;用于&#xff08;通過數字簽名&#xff09;自我認證&#xff08;用戶向別的用戶/服務認證自己&#xff09…

什么是文件擴展名?

A file extension, or filename extension, is a suffix at the end of a computer file. It comes after the period, and is usually two-four characters long. If you’ve ever opened a document or viewed a picture, you’ve probably noticed these letters at the end…

變量與常量

什么是變量/常量&#xff1f; 變量是計算機內存中的一塊區域&#xff0c;變量可以存儲規定范圍內的值&#xff0c;而且值可以改變。基于變量的數據類型&#xff0c;解釋器會分配指定內存&#xff0c;并決定什么數據可以被存儲在內存中。常量是一塊只讀的內存區域&#xff0c;常…

python藍牙編程_藍牙編程經典程序!

文檔從網絡中收集&#xff0c;已重新整理排版.word版本可編輯.歡迎下載支持.1word版本可編輯.歡迎下載支持.L2CAP socketsExample 4-4. l2cap-server.c#include #include #include #include #include int main(int argc, char **argv){struct sockaddr_l2 loc_addr { 0 }, rem…

[項目總結]在ios中使用soundtouch庫實現變聲

這篇文章是項目總結了。 做了段時間的項目&#xff0c;過程中也遇到了很多麻煩&#xff0c;但是好在終于都解決了&#xff0c;這里是這里是項目之后憑著記憶總結出來&#xff0c;大家有遇到同樣的問題&#xff0c;希望能參考了&#xff0c;但是我記憶可能不太好了&#xff0c;要…

Myeclipse優化配置

2019獨角獸企業重金招聘Python工程師標準>>> 作為企業級開發最流行的工具&#xff0c;用Myeclipse開發java web程序無疑是最合適的&#xff0c;java web前端采用jsp來顯示&#xff0c;myeclipse默認打開jsp的視圖有卡頓的現象&#xff0c;那么如何更改jsp默認的打開…

Java多線程之靜態代理

1 package org.study2.javabase.ThreadsDemo.staticproxy;2 3 /**4 * Date:2018-09-18 靜態代理 設計模式5 * 1、真實角色6 * 2、代理角色&#xff1a;持有真實角色的引用7 * 3、二者實現相同的接口8 * 舉例說明&#xff1a;Couple類和Company類都實現了Marry&#xff0c;…

Google在Android P中隱藏了真棒的按應用自動旋轉功能

Historically, when you turn your phone on its side, the screen rotates. To keep this from happening, you can lock the orientation. But with Android P, Google included a way to have to the best of both worlds. 從歷史上看&#xff0c;當您將手機側放時&#xff…

python 位置參數、默認參數、可變參數位置關系_python的位置參數、默認參數、關鍵字參數、可變參數區別...

一、位置參數調用函數時根據函數定義的參數位置來傳遞參數#!/usr/bin/env python#codingutf-8defprint_hello(name, sex):sex_dict {1: u先生, 2: u女士}print hello %s %s, welcome to python world! %(name, sex_dict.get(sex, u先生))#兩個參數的順序必須一一對應&#xff0…

2015年終總結

2019獨角獸企業重金招聘Python工程師標準>>> 2015年終總結 用勇氣改變可以改變的事情&#xff0c;用胸懷接受不可以改變的事情&#xff0c;然后用智慧分辨兩者的不同&#xff01; 短信平臺sms 影像系統fastfile 統一信任中心uts(單點登錄&#xff09; 簡歷增加 總結…

筆記本本地連接顯示電纜拔出_沒有安全電纜槽的筆記本電腦如何固定?

筆記本本地連接顯示電纜拔出Historically laptops included a slot in the side for attaching security cables–as seen in the photo here–but increasingly more slender laptops like ultrabooks are omitting the lock-slot from their case design. How do you properl…