一、事件監聽
測試代碼一:
package cn.javastudy.summary;import java.awt.*;import java.awt.event.*;public class TestTextField { public static void main(String args[]) { new MyFrameTextField(); }}class MyFrameTextField extends Frame { MyFrameTextField() { TextField tf = new TextField(); add(tf); tf.addActionListener(new Monitor3()); tf.setEchoChar('*'); /* * 這個setEchoChar()方法是設置文本框輸入時顯示的字符,這裡設置為*, * 這樣輸入任何內容就都以*顯示出來,不過打印出來時依然可以看到輸入的內容*/ setVisible(true); pack(); }}class Monitor3 implements ActionListener { /* * 接口裡面的所有方法都是public(公共的) * 所以從API文檔複製void actionPerformed(ActionEvent e)時要在void前面加上public */ public void actionPerformed(ActionEvent e) { /* 事件的相關信息都封裝在了對象e裡面,通過對象e的相關方法就可以獲取事件的相關信息*/ TextField tf = (TextField) e.getSource(); /* * getSource()方法是拿到事件源,注意:拿到這個事件源的時候, * 是把它當作TextField的父類來對待* getSource()方法的定義是:“public Object getSource()”返回值是一個Object對象, * 所以要強制轉換成TextField類型的對象* 在一個類裡面想訪問另外一個類的事件源對象可以通過getSource()方法*/ System.out.println(tf.getText());// tf.getText()是取得文本框裡面的內容tf.setText("");// 把文本框裡面的內容清空}}測試代碼二:
package cn.javastudy.summary;import java.awt.*;import java.awt.event.*;public class TestActionEvent2{ public static void main(String args[]){ Frame f = new Frame("TestActionEvent"); Button btn1 = new Button("start"); Button btn2 = new Button("stop"); Monitor2 m2 = new Monitor2();//創建監聽對象btn1.addActionListener(m2); /*一個監聽對象同時監聽兩個按鈕的動作*/ btn2.addActionListener(m2); btn2.setActionCommand("GameOver");//設置btn2的執行單擊命令後的返回信息f.add(btn1,BorderLayout.NORTH); f.add(btn2,BorderLayout.CENTER); f.pack(); f.setVisible(true); }}class Monitor2 implements ActionListener{ public void actionPerformed(ActionEvent e){ System.out.println("a button has been pressed,"+"the relative info is:/n"+e.getActionCommand()); /*使用返回的監聽對象e調用getActionCommand()方法獲取兩個按鈕執行單擊命令後的返回信息根據返回信息的不同區分開當前操作的是哪一個按鈕,btn1沒有使用setActionCommand()方法設置則btn1返回的信息就是按鈕上顯示的文本*/ }}二、TextField事件監聽
測試代碼:
package cn.javastudy.summary;import java.awt.*;import java.awt.event.*;public class TestTextField { public static void main(String args[]) { new MyFrameTextField(); }}class MyFrameTextField extends Frame { MyFrameTextField() { TextField tf = new TextField(); add(tf); tf.addActionListener(new Monitor3()); tf.setEchoChar('*'); /* * 這個setEchoChar()方法是設置文本框輸入時顯示的字符,這裡設置為*, * 這樣輸入任何內容就都以*顯示出來,不過打印出來時依然可以看到輸入的內容*/ setVisible(true); pack(); }}class Monitor3 implements ActionListener { /* * 接口裡面的所有方法都是public(公共的) * 所以從API文檔複製void actionPerformed(ActionEvent e)時要在void前面加上public */ public void actionPerformed(ActionEvent e) { /* 事件的相關信息都封裝在了對象e裡面,通過對象e的相關方法就可以獲取事件的相關信息*/ TextField tf = (TextField) e.getSource(); /* * getSource()方法是拿到事件源,注意:拿到這個事件源的時候, * 是把它當作TextField的父類來對待* getSource()方法的定義是:“public Object getSource()”返回值是一個Object對象, * 所以要強制轉換成TextField類型的對象* 在一個類裡面想訪問另外一個類的事件源對象可以通過getSource()方法*/ System.out.println(tf.getText());// tf.getText()是取得文本框裡面的內容tf.setText("");// 把文本框裡面的內容清空}}使用TextField類實現簡單的計算器
package cn.javastudy.summary;import java.awt.*;import java.awt.event.*;public class TestMath { public static void main(String args[]) { new TFFrame(); }}/* 這裡主要是完成計算器元素的佈局*/class TFFrame extends Frame { TFFrame() { /* * 創建3個文本框,並指定其初始大小分別為10個字符和15個字符的大小這裡使用的是TextField類的另外一種構造方法public TextField(int columns) */ TextField num1 = new TextField(10); TextField num2 = new TextField(10); TextField num3 = new TextField(15); /* 創建等號按鈕*/ Button btnEqual = new Button("="); btnEqual.addActionListener(new MyMonitor(num1, num2, num3)); /* 給等號按鈕加上監聽,讓點擊按鈕後有響應事件發生*/ Label lblPlus = new Label("+"); /* “+”是一個靜態文本,所以使用Label類創建一個靜態文本對象*/ setLayout(new FlowLayout()); /* 把Frame默認的BorderLayout佈局改成FlowLayout佈局*/ add(num1); add(lblPlus); add(num2); add(btnEqual); add(num3); pack(); setVisible(true); }}class MyMonitor implements ActionListener { TextField num1, num2, num3; /* * 為了使對按鈕的監聽能夠對文本框也起作用, * 所以在自定義類MyMonitor裡面定義三個TextField類型的對象num1,num2,num3, * 並且定義了MyMonitor類的一個構造方法這個構造方法帶有三個TextField類型的參數, * 用於接收從TFFrame類裡面傳遞過來的三個TextField類型的參數* 然後把接收到的三個TextField類型的參數賦值給在本類中聲明的三個TextField類型的參數num1,num2,num3 然後再在actionPerformed()方法裡面處理num1,num2,num3 */ public MyMonitor(TextField num1, TextField num2, TextField num3) { this.num1 = num1; this.num2 = num2; this.num3 = num3; } public void actionPerformed(ActionEvent e) { /* 事件的相關信息都封裝在了對象e裡面,通過對象e的相關方法就可以獲取事件的相關信息*/ int n1 = Integer.parseInt(num1.getText());/* num1對象調用getText()方法取得自己顯示的文本字符串*/ int n2 = Integer.parseInt(num2.getText());/* num2對象調用getText()方法取得自己顯示的文本字符串*/ num3.setText("" + (n1 + n2));/* num3對象調用setText()方法設置自己的顯示文本*/ num1.setText(""); /* 計算結束後清空num1,num2文本框裡面的內容*/ num2.setText(""); // num3.setText(String.valueOf((n1+n2))); /* 字符串與任意類型的數據使用“+”連接時得到的一定是字符串, * 這裡使用一個空字符串與int類型的數連接,這樣就可以直接把(n1+n2)得到的int類型的數隱式地轉換成字符串了, * 這是一種把別的基礎數據類型轉換成字符串的一個小技巧。 * 也可以使用“String.valueOf((n1+n2))”把(n1+n2)的和轉換成字符串*/ }} JAVA裡面的經典用法:在一個類裡面持有另外一個類的引用
package cn.javastudy.summary;import java.awt.*;import java.awt.event.*;public class TestMath1 { public static void main(String args[]) { new TTMyFrame().launchFrame(); /* 創建出TTMyFrame對像後調用lauchFrame()方法把計算器窗體顯示出來*/ }}/* 做好計算器的窗體界面*/class TTMyFrame extends Frame { /* 把設計計算器窗體的代碼封裝成一個方法*/ TextField num1, num2, num3; public void launchFrame() { num1 = new TextField(10); num2 = new TextField(15); num3 = new TextField(15); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); btnEqual.addActionListener(new MyMonitorbtnEqual(this)); setLayout(new FlowLayout()); add(num1); add(lblPlus); add(num2); add(btnEqual); add(num3); pack(); setVisible(true); }}/* * 這里通過取得TTMyFrame類的引用,然後使用這個引用去訪問TTMyFrame類裡面的成員變量* 這種做法比上一種直接去訪問TTMyFrame類裡面的成員變量要好得多, * 因為現在不需要知道TTMyFrame類裡面有哪些成員變量了, * 現在要訪問TTMyFrame類裡面的成員變量,直接使用TTMyFrame類對象的引用去訪問即可, * 這個TTMyFrame類的對象好比是一個大管家, 而我告訴大管家,我要訪問TTMyFrame類裡面的那些成員變量, * 大管家的引用就會去幫我找,不再需要我自己去找了。 * 這種在一個類裡面持有另一個類的引用的用法是一種非常典型的用法* 使用獲取到的引用就可以在一個類裡面訪問另一個類的所有成員了*/class MyMonitorbtnEqual implements ActionListener { TTMyFrame ttmf = null; public MyMonitorbtnEqual(TTMyFrame ttmf) { this.ttmf = ttmf; } public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(ttmf.num1.getText()); int n2 = Integer.parseInt(ttmf.num2.getText()); ttmf.num3.setText("" + (n1 + n2)); ttmf.num1.setText(""); ttmf.num2.setText(""); }}運行結果如下:
三、內部類
內部類的使用範例:
package cn.javastudy.summary;import java.awt.*;import java.awt.event.*;public class TestMath3 { public static void main(String args[]) { new MyMathFrame().launchFrame(); }}class MyMathFrame extends Frame { TextField num1, num2, num3; public void launchFrame() { num1 = new TextField(10); num2 = new TextField(15); num3 = new TextField(15); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); btnEqual.addActionListener(new MyMonitor()); setLayout(new FlowLayout()); add(num1); add(lblPlus); add(num2); add(btnEqual); add(num3); pack(); setVisible(true); } /* * 這個MyMonitor類是內部類,它在MyFrame類裡面定義MyFrame類稱為MyMonitor類的包裝類*/ /* * 使用內部類的好處: * 第一個巨大的好處就是可以暢通無阻地訪問外部類(即內部類的包裝類)的所有成員變量和方法* 如這裡的在MyFrame類(外部類)定義的三個成員變量num1,num2,num3, * 在MyMonitor(內部類)裡面就可以直接訪問* 這相當於在創建外部類對象時內部類對象默認就擁有了一個外部類對象的引用*/ private class MyMonitor implements ActionListener { public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(num1.getText()); int n2 = Integer.parseInt(num2.getText()); num3.setText("" + (n1 + n2)); num1.setText(""); num2.setText(""); } }}內部類帶來的巨大好處是:
四、Graphics 類
測試代碼:
package cn.javastudy.summary;import java.awt.*;public class TestPaint{ public static void main(String args[]){ new MyPaint().launchFrame(); /*在main()方法裡面並沒有顯示調用paint(Graphics g)方法可是當創建出Frame窗體後卻可以看到Frame窗體上畫出了圓和矩形,這是因為paint()方法是一個比較特殊的方法在創建Frame窗體時會自動隱式調用當我們把Frame窗體最小化又再次打開時,又會再次調用paint()方法重新把圓和矩形在Frame窗體上畫出來即每次需要重畫Frame窗體的時候就會自動調用paint()方法*/ }}class MyPaint extends Frame{ public void launchFrame(){ setBounds(200,200,640,480); setVisible(true); } public void paint(Graphics g){ /*paint(Graphics g)方法有一個Graphics類型的參數g 我們可以把這個g當作是一個畫家,這個畫家手裡拿著一隻畫筆我們通過設置畫筆的顏色與形狀來畫出我們想要的各種各樣的圖像*/ /*設置畫筆的顏色*/ g.setColor(Color.red); g.fillOval(100,100,100,100);/*畫一個實心橢圓*/ g.setColor(Color.green); g.fillRect(150,200,200,200);/*畫一個實心矩形*/ /*這下面的兩行代碼是為了寫程序的良好編程習慣而寫的前面設置了畫筆的顏色,現在就應該把畫筆的初始顏色恢復過來就相當於是畫家用完畫筆之後把畫筆上的顏色清理掉一樣*/ Color c = g.getColor(); g.setColor(c); }}運行結果:
五、鼠標事件適配器
測試代碼:
package cn.galc.test;import java.awt.*;import java.awt.event.*;import java.util.*;public class MyMouseAdapter{ public static void main(String args[]) { new MyFrame("drawing..."); }}class MyFrame extends Frame { ArrayList points = null; MyFrame(String s) { super(s); points = new ArrayList(); setLayout(null); setBounds(300,300,400,300); this.setBackground(new Color(204,204,255)); setVisible(true); this.addMouseListener(new Monitor()); } public void paint(Graphics g) { Iterator i = points.iterator(); while(i.hasNext()){ Point p = (Point)i.next(); g.setColor(Color.BLUE); g.fillOval(px,py,10,10); } } public void addPoint(Point p){ points.add(p); }}class Monitor extends MouseAdapter { public void mousePressed(MouseEvent e) { MyFrame f = (MyFrame)e.getSource(); f.addPoint(new Point(e.getX(),e.getY())); f.repaint(); }}六、window事件
測試代碼:
package cn.galc.test;import java.awt.*;import java.awt.event.*;public class TestWindowClose{ public static void main(String args[]){ new WindowFrame("關閉WindowFrame"); }}class WindowFrame extends Frame{ public WindowFrame(String s){ super(s); setBounds(200,200,400,300); setLayout(null); setBackground(new Color(204,204,255)); setVisible(true); this.addWindowListener(new WindowMonitor());/*監聽本窗體的動作,把所有的動作信息封裝成一個對像傳遞到監聽類裡面*/ this.addWindowListener( /*在一個方法裡面定義一個類,這個類稱為局部類,也叫匿名的內部類, 這裡的{……代碼……}裡面的代碼很像一個類的類體,只不過這個類沒有名字,所以叫匿名類在這裡是把這個匿名類當成WindowAdapter類來使用,語法上這樣寫的本質意義是相當於這個匿名類從WindowAdapter類繼承,現在new了一個匿名類的對像出來然後把這個對象當成WindowAdapter來使用這個匿名類出了()就沒有人認識了*/ new WindowAdapter(){ public void windowClosing(WindowEvent e){ setVisible(false); System.exit(-1); } } ); } /*這裡也是將監聽類定義為內部類*/ class WindowMonitor extends WindowAdapter{ /*WindowAdapter(Window適配器)類實現了WindowListener監聽接口重寫了WindowListener接口裡面的所有方法如果直接使用自定義WindowMonitor類直接去實現WindowListener接口,那麼就得要重寫WindowListener接口裡面的所有方法,但現在只需要用到這些方法裡面的其中一個方法所以採用繼承實現WindowListener監聽接口的一個子類並重寫這個子類裡面需要用到的那個方法即可這種做法比直接實現WindowListener監聽接口要重寫很多個用不到的方法要簡潔方便得多*//*重寫需要用到的windowClosing(WindowEvent e)方法*/ public void windowClosing(WindowEvent e){ setVisible(false);/*將窗體設置為不顯示,即可實現窗體關閉*/ System.exit(0);/*正常退出*/ } }}七、鍵盤響應事件――KeyEvent
測試代碼:
package cn.galc.test;import java.awt.*;import java.awt.event.*;public class TestKeyEvent{ public static void main(String args[]){ new KeyFrame("鍵盤響應事件"); }}class KeyFrame extends Frame{ public KeyFrame(String s){ super(s); setBounds(200,200,400,300); setLayout(null); setVisible(true); addKeyListener(new KeyMonitor()); } /*把自定義的鍵盤的監聽類定義為內部類這個監聽類從鍵盤適配器KeyAdapter類繼承從KeyAdapter類繼承也是為了可以簡潔方便只需要重寫需要用到的方法即可,這種做法比直接實現KeyListener接口要簡單方便,如果直接實現KeyListener接口就要把KeyListener 接口裡面的所有方法重寫一遍,但真正用到的只有一個方法,這樣重寫其他的方法但又用不到難免會做無用功*/ class KeyMonitor extends KeyAdapter{ public void keyPressed(KeyEvent e){ int keycode = e.getKeyCode(); /*使用getKeyCode()方法獲取按鍵的虛擬碼*/ /*如果獲取到的鍵的虛擬碼等於up鍵的虛擬碼則表示當前按下的鍵是up鍵KeyEvent.VK_UP表示取得up鍵的虛擬碼鍵盤中的每一個鍵都對應有一個虛擬碼這些虛擬碼在KeyEvent類裡面都被定義為靜態常量所以可以使用“類名.靜態常量名”的形式訪問得到這些靜態常量*/ if(keycode == KeyEvent.VK_UP){ System.out.println("你按的是up鍵"); } } }}/*鍵盤的處理事件是這樣的:每一個鍵都對應著一個虛擬的碼,當按下某一個鍵時,系統就會去找這個鍵對應的虛擬的碼,以此來確定當前按下的是那個鍵*/通過這篇文章和大家一起學習了GUI編程,希望大家對GUI編程有了更全面的認識,關於GUI編程遠不止這些,還需要大家繼續學習。