之前的學習當中,咱們都使用的是命令交互方式:java
例如:在DOS命令行中經過javac java命令啓動程序.程序員
軟件的交互的方式:編程
1. 命令交互方式 app
圖書管理系統框架
2. 圖形交互方式ide
ava提供了專業的API用於開發圖形用戶界面函數
GUI--> Graphic User Interface工具
將要了解GUI API的框架結構,以及GUI組件以及組件之間的關係,容器和佈局管理器,顏色,字體等.佈局
Java1.0版本的圖形用戶界面庫,設計目標是幫助程序員編寫在全部平臺上都能良好表現的GUI程序。爲了實現這個目標Java1.0提供了抽象窗口工具集(AWT),可是這個目標並無達到。AWT在全部的系統上表現都很差。由於:最第一版本的AWT是在一個月內構思,設計和實現的(Think in Java )。學習
Abstract Window Toolkit 抽象窗口工具集
Java將圖形用戶界面相關的類捆綁在了一塊兒,放在了一個稱之爲抽象窗口工具集的庫中.AWT適合開發簡單的圖形用戶界面,並不適合開發複雜的GUI項目.
位於: java.awt.* 中,定義了不少的組件類,開發者能夠直接建立對象加以使用
缺點: 全部的圖形界面都依賴於底層的操做系統,容易發生於特定平臺相關的故障.
AWT調用本地系統資源生成圖形化界面, 依賴本地平臺. 1.0
SUN公司對AWT進行了升級,基於AWT,推出了一種更穩定,更通用和更靈活的庫.稱之爲Swing組件庫(Swing component)。
既然都是用於GUI設計的組件庫,那麼爲了區分Swing組件類和對應的AWT組件類,Swing組件類都已字母J爲前綴.位於:javax.swing.* 中,提供了和AWT中等同的全部的組件類,可是類名的前面多加了一個J.
SWING能夠跨平臺. 1.2
咱們主要學習Swing GUI組件.
GUI API包含的類分爲三個部分:組件類(component class) 容器類(container class),和輔助類(helper class)
在圖形用戶界面程序中當咱們想要建立按鈕、複選框和滾動條等這些能夠顯示在屏幕上的對象,該如何建立。其實這些都屬於一類叫作組件類。
AWT中的組件根類
類 Component
java.lang.Object
java.awt.Component
Swing中的組件根類
javax.swing
類 JComponent
java.lang.Object
java.awt.Component
java.awt.Container
javax.swing.JComponent
組件類的實例能夠顯示在屏幕上.Component類是包括容器類的全部用戶界面類的根類是java.awt中的類,對應的Swing中的是Jcomponent.瞭解了Component和JComponent都是抽象類.因此不能使用new關鍵字建立對象.因此須要使用它們的具體的實現類來建立對象.
在AWT中典型圖形用戶界面中的按鈕(Button)、複選框(Checkbox)和滾動條(Scrollbar)都是組件類,都是Component類的子類.
在Swing中的GUI組件,有對應的JButton,JCheckBox,JscrollBar
繼承關係圖(AWT)
容器(Container),是一個特殊的組件,該組件能夠經過add()添加其餘組件。
容器類適用於盛裝其餘GUI組件的GUI組件.例如 Panel Frame Dialog都是AWT組件的容器類.
對應的Swing組件的容器類是JPanel JFrame JDialog
用來描述GUI組件的屬性,例如圖像的顏色,字體等. 注意:輔助類是在java.awt中的
在JDK的bin目錄中有javaw.exe .javaw.exe是java在window中專門用於執行GUI程序.
import javax.swing.JFrame; import javax.swing.JOptionPane; public class Demo { public static void main(String[] args) { // 建立JFrame JFrame frame = new JFrame("hello,world"); // 設置尺寸 frame.setSize(200, 100); // JFrame在屏幕居中 frame.setLocationRelativeTo(null); // JFrame關閉時的操做 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 顯示JFrame frame.setVisible(true); } }
JFrame(框架)是一個容器
建立一個用戶界面須要建立一個JFrame來存放用戶界面組件.例如存放按鈕,文本框。
javax.swing
類 JFrame
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
javax.swing.JFrame
public class Demo1 { public static void main(String[] args) { // 建立JFrame JFrame frame = new JFrame("個人frame"); // 顯示JFrame frame.setVisible(true); } }
注意:須要調用setVisible(true)方法後纔會顯示框架
運行程序會在窗口的左上角顯示一個窗口,可是隻能顯示標題欄,並且關閉JFrame時,程序程序沒有中止.
因此須要完成以下需求:
1: 設置Jframe的寬度和高度
2: 讓Jframe顯示在屏幕中間
3: 關閉Jframe時,程序會中止
java.awt.Window.setSize(int width, int height)
查找API文檔,查看 setSize方法,能夠指定框架的寬度和高度.參數類型是int,注意是以像素爲單位,普通的筆記本的屏幕分辨率爲1280*800或者1366*768.注意:分辨率表示每平方英寸的像素數.屏幕分辨率越高,屏幕的像素越多.因此分辨率越高看到的細節就越多.
setSize方法被定義在java.awt.Component類中,被Component 的子類java.awt.Window 重寫.而Jframe以繼承了Windiws類因此也具有該方法.
setLocationRelativeTo()方法
java.awt.Window.setLocationRelativeTo(Component c) 設置窗口相對於指定組件的位置。 若是 c 爲 null,則此窗口將置於屏幕的中央。
setLocationRelativeTo(null)方法能夠在屏幕上居中顯示框架.
若是不想要設置在中間,可使用
setLocation(200, 100);
setDefaultCloseOperation(int operation)方法
javax.swing.JFrame.setDefaultCloseOperation(int operation)
該方法告訴程序,當框架關閉時結束程序.方法的參數是JFrame 的常量EXIT_ON_CLOSE
添加完畢
public class Demo1 { public static void main(String[] args) { // 建立JFrame JFrame frame = new JFrame("個人frame"); // 設置尺寸 frame.setSize(200, 100); // JFrame在屏幕居中 frame.setLocationRelativeTo(null); // JFrame關閉時的操做 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 顯示JFrame frame.setVisible(true); } }
上述案例中的框架是空的.能夠經過add方法在框架中添加組件
java.awt.Container.add(Component comp)
代碼:
public static void main(String[] args) { // 建立JFrame JFrame frame = new JFrame("個人frame"); // 建立按鈕 JButton button = new JButton("OK"); // 向frame中添加一個按鈕 frame.add(button); // 設置尺寸 frame.setSize(200, 100); // JFrame在屏幕居中 frame.setLocationRelativeTo(null); // JFrame關閉時的操做 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 顯示JFrame frame.setVisible(true); }
運行程序,會顯示上圖所示窗口.調整窗口的大小,按鈕都是顯示在窗口的中央,而且佔滿整個框架.
這是由於組件(本例就是按鈕)是被佈局管理器放到框架中的.默認佈局管理器就是將按鈕放到中央.
備註: 能夠經過f.setVisible(false); 隱藏窗體f.dispose();關閉窗口
設置圖片:
setIconImage(Toolkit.getDefaultToolkit().createImage("png-0015.png"));
顯示一個帶有OK 按鈕的模態對話框。
下面是幾個使用showMessageDialog 的例子:
Java代碼
JOptionPane.showMessageDialog(null, "錯誤信息提示", "標題", JOptionPane.INFORMATION_MESSAGE);
效果以下:
Java代碼
JOptionPane.showMessageDialog(jPanel, "提示消息", "標題",JOptionPane.WARNING_MESSAGE);
Java代碼
JOptionPane.showMessageDialog(null, "提示消息.", "標題",JOptionPane.ERROR_MESSAGE);
Java代碼
JOptionPane.showMessageDialog(null, "提示消息.", "標題",JOptionPane.PLAIN_MESSAGE);
1.2 showOptionDialog
這個函數能夠改變顯示在按鈕上的文字。你還能夠執行更多的個性化操做。
常規的消息框:
Java代碼
int n = JOptionPane.showConfirmDialog(null, "你高興嗎?", "標題",JOptionPane.YES_NO_OPTION);//i=0/1
輸入框 :
String inputValue = JOptionPane.showInputDialog("請輸入你給我金額");
面板也是一個容器的組件,能夠在上面添加
注意:面板不能單獨使用,必須在頂層窗口中使用。
一些經常使用的組件例如:
JLabel,
JButton ,
JTextField
JPassworldField
JRadioButton
JCheckBox
JTextArea
JList
JMenuBar
JMenu
JMenultem
Java中的Swing提供了常規按鈕,單選按鈕,複選按鈕和菜單按鈕
按鈕Button是點擊時觸發動做事件的組件.
單選按鈕,可讓用戶從一組選項中選擇一個單一條目.例如性別.
使用單選按鈕時注意將,單選按鈕放在一組,須要使用java.swing.ButtonGroup. 的add方法,添加到一個組中,位於同一個組的單選按鈕就是互斥的. 若是沒有將單選按鈕放在一個組中,就是獨立的..咱們讓然須要把按鈕添加在容器中.由於ButtonGroup添加到容器中..
多選
例如: String[] data = { "one", "two", "three" };
JList list = new JList(data);
p1.add(list);
JMenu菜單
JMenultem菜單項
菜單條(MenuBar)中包含菜單(Menu),菜單中中包含菜單項(MenuItem)
注意添加的順序。例如:記事本的菜單條中包含文件、編輯、格式、查看、幫助菜單。其中文件菜單中包含新建、打開、保存、另存爲等菜單項
案例綜合。
public class CommonComponent extends JFrame { public CommonComponent() { // 面板 JPanel p1 = new JPanel(); add(p1); // 標籤 JLabel name = new JLabel("用戶名:"); p1.add(name); // 文本域 JTextField field = new JTextField(8); p1.add(field); // 標籤 JLabel passwd = new JLabel("密碼"); p1.add(passwd); // 密碼域 JPasswordField pass = new JPasswordField(8); p1.add(pass); // 單選按鈕 JLabel gender = new JLabel("性別"); p1.add(gender); JRadioButton male = new JRadioButton("男"); JRadioButton female = new JRadioButton("女"); // 單選按鈕組,同一個單選按鈕組的互斥. ButtonGroup group = new ButtonGroup(); group.add(male); group.add(female); // 注意,單選按鈕組不能添加進容器 p1.add(male); p1.add(female); // 複選框 JLabel like = new JLabel("愛好:"); p1.add(like); JCheckBox eat = new JCheckBox("吃飯"); JCheckBox movie = new JCheckBox("看電影"); JCheckBox sleep = new JCheckBox("睡覺"); p1.add(eat); p1.add(movie); p1.add(sleep); // 文本域 JLabel info = new JLabel("我的簡介"); p1.add(info); JTextArea area = new JTextArea(20, 20); p1.add(area); // 列表 String[] data = { "one", "two", "three" }; JList list = new JList(data); p1.add(list); // 普通按鈕 JButton button = new JButton("註冊"); p1.add(button); // 菜單條 JMenuBar bar = new JMenuBar(); // 菜單 JMenu menu = new JMenu("文件"); // 菜單選項 JMenuItem myNew = new JMenuItem("新建"); JMenuItem myOpen = new JMenuItem("打開"); bar.add(menu); menu.add(myNew); menu.add(myOpen); add(bar, BorderLayout.NORTH); } public static void main(String[] args) { CommonComponent frame = new CommonComponent(); frame.setTitle("經常使用組件"); frame.setSize(400, 400); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 自適應 frame.pack(); frame.setVisible(true); } }
由於面板默認是流式佈局.
Java的GUI組件都放置在容器中,他們的位置是由容器的佈局管理器來管理的.在前面的程序中,並無指定將OK按鈕放置在框架的什麼位置,可是,Java知道應該把它放置在哪裏,由於在後臺工做的佈局管理器可以將組件放到正確的位置.佈局管理器是使用佈局管理器類建立的.
咱們可使用setLayout() 方法在容器中設置佈局管理器.
咱們將要了解FlowLayout GridLayout BorderLayout
FlowLayout(流式佈局)是最簡單佈局管理器. Jpanel容器默認的佈局管理器
流式佈局,按照組件添加的順序,從左到到右將組件排列在容器中.當放滿一行,就開始新的一行.在FlowLayout有3個常量FlowLayout能夠指定組件的對齊方式.
LEFT 每一行組件都應該是左對齊的
RIGHT 每一行組件都應該是右對齊的
CENTER 每一行組件都應該是居中的
還能夠指定組件之間的以像素爲單位的間隔.
int getHgap() 獲取組件之間以及組件與 Container 的邊之間的水平間隙。 int getVgap() 獲取組件之間以及組件與 Container 的邊之間的垂直間隙。 void setHgap(int hgap) 設置組件之間以及組件與 Container 的邊之間的水平間隙。 void setVgap(int vgap) 設置組件之間以及組件與 Container 的邊之間的垂直間隙。
這個佈局管理器的對其方式默認值是CENTER
這個佈局管理器的水平間隔默認值是 5個像素
這個佈局管理器的垂直間隔默認是是5個像素
建立該佈局管理器
FlowLayout() 構造一個新的 FlowLayout,它是居中對齊的,默認的水平和垂直間隙是 5 個單位。 FlowLayout(int align) 構造一個新的 FlowLayout,它具備指定的對齊方式,默認的水平和垂直間隙是 5 個單位。 FlowLayout(int align, int hgap, int vgap) 建立一個新的流佈局管理器,它具備指定的對齊方式以及指定的水平和垂直間隙。
案例:建立框架,使用流失佈局管理器.向該框架添加三個標籤和文本域.
public class ShowFlowLayout extends JFrame { public ShowFlowLayout() { super.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 20)); add(new JLabel("姓名:")); add(new JTextField(8)); add(new JLabel("郵箱:")); add(new JTextField(8)); add(new JLabel("電話:")); add(new JTextField(8)); } public static void main(String[] args) { ShowFlowLayout frame = new ShowFlowLayout(); frame.setTitle("FlowLayout"); frame.setSize(500, 200); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
該案例在本類main方法中建立了一個本類對象. 該類的構造函數中建立而且添加組件.
該案例使用了FlowLayout管理器在框架放置組件.若是改變框架的大小.組建會自動的從新排列,以適應框架.
若是將同一個按鈕在框架中添加10次,那麼該框架只會出現一次,將一個按鈕向容器中添加多以和一次是同樣的.
GridLyaout是以網格形式管理組件的.組件按照他們添加的順序從左到右排列,顯示第一行,接着是第二行,一次類推.
Gridlayout能夠指定網格中的行數和列數
規則以下:
行數和列數能夠是0可是不能二者都爲0.
若是一個爲0另一個不爲0,那麼不爲0的行或列的大小就是固定的,爲0的行或者列有佈局管理器動態決定.
例如:若是指定一個網格有0行3列10個組件,GirdLayout會建立3個固定的列和行,最後一行只有一個組件.若是指定一個網格有3行0列10個組件,GridLayout就會建立3行4列,最後一行包含2個組件.
若是行數和列數都不爲0,那麼以行數爲依據.因此行數是固定的,佈局管理器會動態的計算列數.例如,若是指定一個網格有3行3列10個組件,GridLayout會建立3個固定的行和4列,最後一行包含2個組件.
構造方法
GridLayout() 建立具備默認值的網格佈局,即每一個組件佔據一行一列。 GridLayout(int rows, int cols) 建立具備指定行數和列數的網格佈局。 GridLayout(int rows, int cols, int hgap, int vgap) 建立具備指定行數和列數,水平間隔,垂直間隔的網格佈局。
方法:
int getRows() 獲取此佈局中的行數。 默認值是1 int getColumns() 獲取此佈局中的列數。 默認值是1 int getHgap() 獲取組件之間的水平間距。 默認值是0 int getVgap() 獲取組件之間的垂直間距。默認值是0 設置 void setRows(int rows) 將此佈局中的行數設置爲指定值。默認值是1 void setColumns(int cols) 將此佈局中的列數設置爲指定值。 默認值是1 void setHgap(int hgap) 將組件之間的水平間距設置爲指定值。 默認值是0 void setVgap(int vgap) 將組件之間的垂直間距設置爲指定值。默認值是0
案例:該案例依然添加3個標籤和3個文本域,只不過佈局管理器是GrigLayout
public class ShowGridLayout extends JFrame { public ShowGridLayout() { setLayout(new GridLayout(3, 2, 5, 5)); add(new JLabel("姓名:")); add(new JTextField(8)); add(new JLabel("郵箱:")); add(new JTextField(8)); add(new JLabel("電話:")); add(new JTextField(8)); } public static void main(String[] args) { ShowGridLayout frame = new ShowGridLayout(); frame.setTitle("GridLayout"); frame.setSize(200, 125); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
若是使用setLayout(new GridLayout(3,10))替換setlayout語句,仍是會獲得3行2列,由於行的參數非零,因此列的參數會被忽略.列的實際參數是由佈局管理器計算出來的.
邊框佈局,JFrame 容器默認的佈局管理器是邊框佈局.該管理器將容器非爲東西南北中5個區域.
咱們使用add(Component,index)方法能夠將組件添加進到BorderLayout中,index是一個常量,有5個值
EAST
東區域的佈局約束(容器右邊)。
WEST
西區域的佈局約束(容器左邊)。
SOUTH
南區域的佈局約束(容器底部)。
NORTH
北區域的佈局約束(容器頂部)。
CENTER
中間區域的佈局約束(容器中央)。
構造函數
BorderLayout() 構造一個組件之間沒有間距的新邊框佈局。 BorderLayout(int hgap, int vgap) 構造一個具備指定組件間距的邊框佈局。
方法:
int getHgap() 返回組件之間的水平間距。 int getVgap() 返回組件之間的垂直間距。 void setHgap(int hgap) 設置組件之間的水平間距。 默認值是0 void setVgap(int vgap) 設置組件之間的垂直間距。默認值是0
組件會根據他們最合適的尺寸和在容器中的位置來放置,南北組件能夠水平拉伸,東西組件能夠垂直拉伸,中央組件既能夠水平拉伸也能夠垂直拉伸.
案例:演示邊框佈局管理器
public class ShowBorderLayout extends JFrame { public ShowBorderLayout() { setLayout(new BorderLayout(5, 10)); add(new JButton("東"), BorderLayout.WEST); add(new JButton("西"), BorderLayout.EAST); add(new JButton("南"), BorderLayout.SOUTH); add(new JButton("北"), BorderLayout.NORTH); add(new JButton("中"), BorderLayout.CENTER); } public static void main(String[] args) { ShowBorderLayout frame = new ShowBorderLayout(); frame.setTitle("BorderLayout"); frame.setSize(300, 200); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
注意: 若是佈局管理器爲Border管理器,調用add方法,沒有說明組件的位置(東西南北中)默認是center.
因此
add(new JButton("ok"))和add(new JButton("ok"), BorderLayout.CENTER )
效果是同樣的.
若是在Border容器中添加2個組件,都沒有指定位置,那麼只會顯示最後一個組件
add(new JButton("ok1"))和add(new JButton("ok2")) 只會顯示ok2
使用佈局管理器
代碼:
public class CommonComponent extends JFrame { public CommonComponent() { // 菜單條 JMenuBar bar = new JMenuBar(); // 菜單 JMenu menu = new JMenu("文件"); // 菜單選項 JMenuItem myNew = new JMenuItem("新建"); JMenuItem myOpen = new JMenuItem("打開"); bar.add(menu); menu.add(myNew); menu.add(myOpen); add(bar, BorderLayout.NORTH); // 面板 JPanel p1 = new JPanel(); p1.setLayout(new GridLayout(2, 2, 5, 5)); add(p1); // 標籤 JLabel name = new JLabel("用戶名:"); p1.add(name); // 文本域 JTextField field = new JTextField(8); p1.add(field); // 標籤 JLabel passwd = new JLabel("密碼"); p1.add(passwd); // 密碼域 JPasswordField pass = new JPasswordField(8); p1.add(pass); JPanel p2 = new JPanel(); // 單選按鈕 JLabel gender = new JLabel("性別"); p2.add(gender); JRadioButton male = new JRadioButton("男"); JRadioButton female = new JRadioButton("女"); // 單選按鈕組,同一個單選按鈕組的互斥. ButtonGroup group = new ButtonGroup(); group.add(male); group.add(female); // 注意,單選按鈕組不能添加進容器 p2.add(male); p2.add(female); JPanel p3 = new JPanel(); // 複選框 JLabel like = new JLabel("愛好:"); p3.add(like); JCheckBox eat = new JCheckBox("吃飯"); JCheckBox movie = new JCheckBox("看電影"); JCheckBox sleep = new JCheckBox("睡覺"); p3.add(eat); p3.add(movie); p3.add(sleep); JPanel p4 = new JPanel(new GridLayout(1, 0, 5, 5)); // 文本域 JLabel info = new JLabel("我的簡介:"); p4.add(info); JTextArea area = new JTextArea(50, 10); p4.add(area); JPanel p5 = new JPanel(new BorderLayout()); // 列表 String[] data = { "one", "two", "three" }; JList list = new JList(data); p5.add(list, BorderLayout.WEST); JPanel p6 = new JPanel(); // 普通按鈕 JButton button = new JButton("註冊"); p6.add(button); JButton button2 = new JButton("取消"); p6.add(button2); setLayout(new GridLayout(7, 1, 5, 5)); add(p1); add(p2); add(p3); add(p4); add(p5); add(p6); } public static void main(String[] args) { CommonComponent frame = new CommonComponent(); frame.setTitle("經常使用組件"); frame.setSize(400, 600); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 自適應 // frame.pack(); frame.setVisible(true); } }
public class TestPanel extends JFrame { public TestPanel() { // 建立面板,默認是流式佈局 JPanel p1 = new JPanel(); // 指定爲網格佈局,4行3列 p1.setLayout(new GridLayout(4, 3)); for (int i = 1; i <=9; i++) { p1.add(new JButton("" + i)); } p1.add(new JButton("0")); p1.add(new JButton("OK")); p1.add(new JButton("EXIT")); // 建立面板,指定邊框佈局 JPanel p2 = new JPanel(new BorderLayout()); // 面板添加文本域,邊框北部 p2.add(new JTextField("我在這裏啊!!!"), BorderLayout.NORTH); // 面板添加其餘面板,邊框中部. p2.add(p1, BorderLayout.CENTER); // 框架添加面板,框架的佈局默認就是邊框佈局,面板指定位於框架西部 add(p2, BorderLayout.EAST); // 框架添加按鈕,位於框架總部. add(new JButton("哈哈"), BorderLayout.CENTER); } public static void main(String[] args) { TestPanel frame = new TestPanel(); frame.setTitle("JPanel"); frame.setSize(400, 260); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
注意: 面板容器是一個輕量級的容器,該容器不能單獨的使用,必須依賴與外層的頂層容器(JFrame)
在上述的程序中,其中菜單條,菜單 項,按鈕等都是對象,當咱們單擊對象時,應該可以完成一些任務.例如在程序中經過鼠標操做時,單擊,雙擊,鼠標移入,鼠標移出.可以執行一些任務,在 Java中咱們可使用事件監聽機制,在Java的事件監聽機制中 ,當事件發生時(點擊按鈕,移動鼠標等,關閉窗口)會被一類對象發現並處理.
在運行java圖形用戶界面程序時,用戶與程序交互,用戶執行了某些操做時,會發生一些事情, 那麼事件(event)能夠定義爲程序發生了某些事情的信號.典型用戶操做就是用戶移動鼠標,點擊按鈕,敲擊鍵盤等.程序能夠選擇相應事件或者忽略事件。
可以建立一個事件並觸發該事件的組件稱爲源對象。例如因爲按鈕可以點擊, 那麼按鈕就是一個源對象,按鈕被點擊就是一個事件。
一個事件是事件類的實例對象。事件類的根類是java.util.EventObject。
事件對象包含事件相關的屬性,可使用EventObject類中的實例方法getSource得到事件的源對象。
EventObject類的子類能夠描述特定類型的事件
用戶動做 |
源對象 |
觸發的事件類型 |
點擊按鈕 |
JButton |
ActionEvent |
文本域按回車 |
JTextField |
ActionEvent |
窗口打開,關閉,最小化,關閉 |
Window |
WindowEvent |
單擊,雙擊,移動,鼠標 |
Component |
MouseEvent |
點擊單選框 |
JradioButton |
ItemEvent ActionEvent |
點擊複選框 |
JcheckBox |
ItemEvent ActionEvent |
當源對象觸發了一個事件,誰來處理這個事件?在Java中對此感興趣的對象會處理它。對此感興趣的對象稱之爲監聽器(Listener)。
舉例來講當咱們點擊一個按鈕,想要按鈕執行一些動做,須要一個對象來監控按鈕,當點擊按鈕的事件發生時,該對象就會監聽到按鈕事件。進而能夠執行一些動做。
例如:
Java中,對象表示的每一個事件都是由java.util中EventObject類的子類,
例如: MouseEvent: 表示鼠標的動做,例如移動光標,單擊,雙擊
KeyEvent: 表示鍵盤上的按鍵.
ActionEvent表示用戶採起的用戶界面操做,例如點擊屏幕上的按鈕.
Java對組件都有對應的事件監聽器,和添加事件監聽器方法。
例如: 按鈕: 源對象,會觸發
體驗:當用戶點擊按鈕時,按鈕上的信息會發生變化
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; public class ShowButton extends JFrame { public ShowButton() { JButton button = new JButton("點我"); add(button); // 添加鼠標監聽事件 button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("按鈕被點擊"); Object source = e.getSource(); JButton button = (JButton) source; String text = button.getText(); if ("按鈕被點擊".equals(text)) { button.setText("點我"); } else { button.setText("按鈕被點擊"); } } }); } public static void main(String[] args) { ShowButton frame = new ShowButton(); frame.setTitle("個人框架"); frame.setSize(400, 200); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
Window類
java.awt 類 Window java.lang.Object java.awt.Component java.awt.Container java.awt.Window
Window
對象是一個頂層窗口。窗口(Window)對應的事件叫作窗口事件(WindowEvent),任何窗口(Window)以及窗口的子類均可能觸發窗口事件: 打開窗口,正在關閉窗口,激活窗口,變成非活動窗口,最小化窗口和還原窗口。
Window添加窗口事件(WindowEvent)監聽器的方法
void addWindowListener(WindowListener l) 添加指定的窗口偵聽器,以今後窗口接收窗口事件
監聽Window窗口事件(WindowEvent)的監聽器:WindowListener
java.awt.event 接口 WindowListener 用於接收窗口事件的偵聽器接口。當經過打開、關閉、激活或停用、圖標化或取消圖標化而改變了窗口狀態時,將調用該偵聽器對象中的相關方法
WindowListener接口中定義的方法
抽象方法: void windowActivated(WindowEvent e) 激活窗口 void windowClosed(WindowEvent e) 關閉窗口 void windowClosing(WindowEvent e) 正在關閉窗口 void windowDeactivated(WindowEvent e) 變爲非活動窗口 void windowDeiconified(WindowEvent e) 還原窗口 void windowIconified(WindowEvent e) 最小化窗口 void windowOpened(WindowEvent e) 打開窗口
案例: 框架的事件監聽處理
javax.swing
類 JFrame
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
javax.swing.JFrame
建立JFrame,Jfame是一個框架,屬於窗體(Window)體系中的一員,也能夠實現窗口的最大化,最小化,關閉,點擊窗體,等一系列的操做。那麼在用戶觸發這些事件發生時可以作一些工做,就須要註冊事件監聽器。
JFrame 是經過addWindowListener 方法就註冊窗體事件監聽器,該方法須要接受一個監聽器(WindowListener)對象。查找API文檔,發現WindowListener是一個接口,
咱們須要窗口監聽器(WindowListener)的實例對象,因此須要實現該接口,重寫WindowListener接口的抽象方法。而後建立該實現類對象,做爲參數傳遞給addWindowListener .
例如: 當像激活窗口這樣的窗口事件發生時,windowActivated 方法就會觸發。
代碼以下:
import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.JFrame; public class WindowEventDemo extends JFrame { WindowEventDemo() { // this對象時JFrame的子類,而JFrame 類是Window體系中的一員因此具有添加窗口事件的方法 this.addWindowListener(new MyWindow()); } public static void main(String[] args) { WindowEventDemo frame = new WindowEventDemo(); frame.setTitle("個人框架"); frame.setSize(400, 200); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } } // 實現WindowListener class MyWindow implements WindowListener { // 激活窗口 public void windowActivated(WindowEvent e) { System.out.println("激活窗口"); } // 關閉窗口 public void windowClosed(WindowEvent e) { System.out.println("關閉窗口"); } // 正在關閉窗口 public void windowClosing(WindowEvent e) { System.out.println("正在關閉窗口"); } // 變爲非活動窗口 public void windowDeactivated(WindowEvent e) { System.out.println("變爲非活動窗口"); } // 還原窗口 public void windowDeiconified(WindowEvent e) { System.out.println("還原窗口"); } // 最小化窗口 public void windowIconified(WindowEvent e) { System.out.println(" 最小化窗口"); } // 打開窗口 public void windowOpened(WindowEvent e) { System.out.println("打開窗口"); } }
總結:Window類或者Window類的任何子類均可能會觸發WindowEvent。由於JFrame是Window的子類。因此也能夠觸發WindowEvent。
由於WindowListener接口中的方法都是抽象的,因此即便程序中不想關注某些事件,可是仍是要實現因此的方法,比較麻煩,爲了方便起見,Java提供了一個針對WindowListener接口的實現類,該類中把WindowListener接口中的方法所有實現,只不過方法體都爲空。
例如: 加入咱們只對激活窗口感興趣,那麼只須要繼承該實現類重寫激活窗口的方法便可。簡化了代碼。
import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; public class AdapterDemo extends JFrame { AdapterDemo() { addWindowListener(new MyAdapter()); } public static void main(String[] args) { AdapterDemo frame = new AdapterDemo(); frame.setTitle("個人框架"); frame.setSize(400, 200); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } class MyAdapter extends WindowAdapter { public void windowActivated(WindowEvent e) { System.out.println("windowActivated...."); } } }
那麼這個WindowAdapter類就叫作適配器類,是爲了簡化代碼的書寫而出現的。
適配器 接口
WindowAdapter WindowListener
MouserAdapter MouserListener
KeyAdapter KeyListener
當在一個組件上按下,釋放,點擊,移動,或者拖動鼠標時,就會產生鼠標事件。MouseEvent對象捕獲這個事件。
MouseEvent
java.awt.event.MouseEvent
Java對鼠標事件提供了MouseListener 監聽器接口,能夠監聽鼠標的按下,釋放,輸入,退出和點擊動做。
MouseListener
用於接收組件上「感興趣」的鼠標事件(按下、釋放、單擊、進入或離開)的偵聽器接口
方法:
void mouseClicked(MouseEvent e) 鼠標按鍵在組件上單擊(按下並釋放)時調用。 void mouseEntered(MouseEvent e) 鼠標進入到組件上時調用。 void mouseExited(MouseEvent e) 鼠標離開組件時調用。 void mousePressed(MouseEvent e) 鼠標按鍵在組件上按下時調用。 void mouseReleased(MouseEvent e) 鼠標按鈕在組件上釋放時調用。
按鍵事件能夠利用鍵盤來控制和執行一些動做,若是按下、釋放一個鍵就會觸發按鍵事件。KeyEvent對象能夠捕獲按鍵的按下放開和敲擊。KeyEvent提供了getkeyChar 來獲取按鍵對應的字符。
java.awt.event.KeyEvent char getKeyChar() 返回與此事件中的鍵關聯的字符。
Java提供了KeyListener監聽器接口來監聽按鍵事件。
KeyListener接口
用於接收鍵盤事件(擊鍵)的偵聽器接口。
void keyPressed(KeyEvent e) 按下某個鍵時調用此方法。 void keyReleased(KeyEvent e) 釋放某個鍵時調用此方法。 void keyTyped(KeyEvent e) 鍵入某個鍵時調用此方法。
public class MouseEventDemo extends JFrame { MouseEventDemo() { JButton button = new JButton("ok"); JTextArea text = new JTextArea(); add(button, BorderLayout.NORTH); add(text, BorderLayout.CENTER); button.addMouseListener(new MouseListener() { // 鼠標按鈕在組件上釋放時調用。 public void mouseReleased(MouseEvent e) { System.out.println("鼠標釋放"); } // 鼠標按鍵在組件上按下時調用。 public void mousePressed(MouseEvent e) { System.out.println("鼠標按下組件"); } // 鼠標離開組件時調用。 public void mouseExited(MouseEvent e) { System.out.println("鼠標離開組件"); } // 鼠標進入到組件上時調用。 public void mouseEntered(MouseEvent e) { // 鼠標進入 System.out.println("鼠標進入組件"); } // 鼠標按鍵在組件上單擊(按下並釋放)時調用。 public void mouseClicked(MouseEvent e) { System.out.println("鼠標單擊組件"); } }); text.addKeyListener(new KeyListener() { // 鍵入某個鍵時調用此方法。 public void keyTyped(KeyEvent e) { System.out.println("鍵入某個鍵"); if (e.getKeyChar() == 'q') { System.exit(0); } } // 釋放某個鍵時調用此方法。 public void keyReleased(KeyEvent e) { System.out.println("按鍵釋放"); } // 按下某個鍵時調用此方法。 public void keyPressed(KeyEvent e) { System.out.println("鍵盤按下"); } }); } public static void main(String[] args) { MouseEventDemo frame = new MouseEventDemo(); frame.setTitle("鼠標事件"); frame.setSize(400, 200); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
一:肯定事件源(容器或組件)
二:註冊監聽器
經過事件源對象的addXXXListener()方法將監聽器對象註冊到該事件源上。
三:監聽器對象
註冊監聽器時,須要指定監聽器對象。
以參數的形式進監聽器對象傳遞給addXXXListener()
監聽器對象是XXXListener的子類對象或者XXXAdapter的子類對象。
監聽器對象通常用匿名內部類來表示。(簡化書寫)
在覆蓋方法的時候,方法的參數通常是XXXEvent類型的變量接收。
事件觸發後會把事件打包成對象傳遞給該變量。(其中包括事件源對象。經過getSource()或者getComponent()獲取。)
四:常見的事件監聽器
WindowListener 主要用於監聽窗口
ActionListener 主要用於用監聽組件對象的單擊動做
MouseListener 鼠標監聽器
KeyListener 監聽鍵盤
…….
五:常見的事件適配器
WindowAdapter
MouseAdapter
KeyAdapter