《Head First Java 2nd Edition》 摘錄
JFrame 代表屏幕上的一個窗口,可以把 buttons, checkboxes, test fields 等等界面相關的東西置于其上。它可以有一個有菜單項的菜單條。無論在哪個平臺上,都有窗口圖標,最小化、最大化和關閉窗口的按鈕。
JFrame 在不同平臺上的外觀是不一樣的。
可以把 javax.swing 包下的許多部件添加到 JFrame 中,最常用的控件是:
- JButton
- JRadioButton
- JCheckBox
- JLabel
- JList
- JScrollPane
- JSlider
- JTextArea
- JTextField
- JTable
大多數都易于使用,只有某些比較復雜(例如 JTable)。
創建一個GUI非常簡單
第一步:新建一個JFrame
JFrame frame = new JFrame();
第二步:新建一個小部件
JButton button = new JButton("點擊我呀");
第三步:把小部件添加到JFrame 中
frame.getContentPane().add(button);
第四步:顯示窗體
frame.setSize(300, 300);
frame.setVisible(true);
一個最簡GUI示例
package ch12;import javax.swing.*;import java.awt.event.*; // 監聽事件public class SimpleGUI01 implements ActionListener{JButton button;int count = 0;public static void main(String[] args) {SimpleGUI01 gui = new SimpleGUI01();gui.go();}public void go(){JFrame frame = new JFrame("最簡GUI");button= new JButton("點擊我呀");// 添加事件監聽器才能響應事件button.addActionListener(this);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.getContentPane().add(button); // 從這里把 JButton 添加到 JFrameframe.setSize(300, 300);frame.setVisible(true); // 這一步是必須的,不然看到GUI }@Overridepublic void actionPerformed(ActionEvent e) {count ++;button.setText("點擊我了" + count);}}
響應事件
單擊按鈕如何讓按鈕響應事件?
我們需要準備兩樣東西:
- 一個method,特殊事件發生時調用它,比如單擊按鈕
- 一個方式,讓我們知道何時會觸發上面的方法
得到用戶事件
想像一下,你希望單擊按鈕之后按鈕上的文字由click me變成I've been clicked,首先我們可以寫一個方法來改變按鈕的文字:
public void changeIt(){button.setText("I've been clicked!");
}
但是,現在怎么辦?我們怎么知道按鈕何時被單擊了。
在 Java 中,獲取和處理用戶事件的過程被稱作 event-handling,在Java中有許多不同的事件類型,幾乎絕大部分和GUI用戶動作相關。如果用戶單擊按鈕,這就是一個事件。這個事件表明用戶期望的按鈕的事件發生了。如果這是一個Slow Tempo按鈕,用戶期望slow tempo事件發生。如果是聊天客戶端上的發送按鈕,用戶期望的發送我的消息的事件發生了。所以最直截了當的事件是用戶單擊按鈕,表明他們期望一個動作發生。
對于按鈕,你通常都不會考慮中間狀態,例如按鈕按下了或者按鈕釋放了。你對按鈕的期望是:不管用戶是怎么單擊、雙擊按鈕的,不管鼠標按住了多長時間,不管用戶在釋放按鈕之前想法發生了什么變化,僅僅通知我用戶是何時發生了動作。
1、按鈕需要知道我們代碼關注它的狀態
2、當事件發生時按鈕需要以某種方式告知我們
以上兩個問題的解決辦法就是 listener interface,它是一座溝通listener(你)和 event source(按鈕)的橋梁。
Swing GUI 組件都是event sources (事件源),在Java語言中,事件源就是一個能把用戶動作(單擊鼠標,敲擊按鍵,關閉窗口)轉變成事件的對象。就像在Java語言中事實上所有的事物都可以用對象來代表。是某種event class的對象。如果你瀏覽API中的java.awt.event包,可以看見許許多多的事件類(顯而易見,它們的名字中都有Event)。你可以看到MouseEvent, KeyEvent, WindowEvent, ActionEvent 還有許許多多的。
當用戶做出某種動作的時候,source(事件源,比如按鈕)就會創建一個event object(事件對象)。你的絕大部分代碼都是接收事件而不是創建事件。換一句話說,你花費幾乎所有的時間都在作為一個事件監聽器(event listener),而不是事件源(event source)。
每一個事件類型都有與之對應的監聽器接口(listener interface)。如果你期待MouseEvent,就實現MouseListener interface。期待WindowEvents,就實現 WindowListener。明白了否?另外需要謹記實現接口的規則:實現一個你要聲明實現的接口,就需要實現這個接口里面所有的方法。
有的接口有不止一個方法,因為這個接口有多重作用。舉例說明,如果你要實現MouseListener,你就要實現mousePressed, mouseReleased, mouseMoved 等等。盡管它們都來自 MouseEvent,但它們有不同的實現方法。如果你實現MouseListener,當用戶按下鼠標的時候會調用方法mousePressed()。當用戶釋放鼠標的時候,會調用mouseReleased()方法。對于鼠標事件,只有一個事件對象 MouseEvent,但是對于不同的鼠標事件類型,會調用不同的方法。
監聽器和事件源是如何溝通的
Listener
如果你的類想要知道按鈕的 ActionEvents,就需要實現 ActionListener 接口。按鈕也需要知道你對它感興趣,你需要在按鈕上注冊,在按鈕上調用 addActionListener(this) 并且傳遞 ActionListener 引用給它(在當前情況下,你是 ActionListener,所以可以通過 this 傳遞)。按鈕需要在事件發生的時候以某個方式通知你,所以它調用監聽器接口的方法。作為一個監聽器,你必須要實現這個接口的唯一的一個方法 actionPerformed()。
Event Source
按鈕是 ActionEvents 的事件源,所以它必須知道哪一個對象是感興趣的監聽者。按鈕有一個方法 addActionListener() ,可以把感興趣的監聽者作為參數傳遞給這個按鈕。當按鈕的 addActioinListener() 方法運行時,它會把參數存到一個列表中。當用戶點擊按鈕時,按鈕在列表中的每一個監聽器上調用 actionPerformed() 方法發出這個事件。
3種添加事物到GUI的方法
- 添加小部件到 JFrame 上
frame.getContentPane().add(myButton);
- 在小部件上繪畫 2D 圖形
graphics.fillOval(70, 70, 100, 100);
- 在小部件上顯示圖片
graphics.drawImage(myPic, 10, 10, this);
創建自己的繪圖小部件
可以設置小部件,移動,動畫,改變顏色等等屬性。
默認情況下,一個frame有5個區域留給你添加小部件。