死磕Java系列之GUI 元件和事件監聽
當我們搭建好圖形介面窗體的時候,需要向窗體中加入各種元件,便於使用者操作,使用者在窗體中都會有哪些操作呢?窗體是程式與使用者可互動的介面,比如說登入介面,使用者可以輸入姓名和密碼,點選登入按鈕,登入到另一個介面,在下一個介面有更多的操作,比如說有多個選擇組成的選單,需要輸入文字的文字框,用來標記的標籤等。綜上,一個窗體中有多個元件,元件有文字元件,按鈕元件,標籤元件和列表元件。當然了,一個窗體中有元件是不夠的,還需要在窗體中加入監聽事件,監聽事件也就是說當用戶點選相應的元件的時候,程式作出的響應反應,比如說登入介面點選登入按鈕以後,監聽器事件就是檢測密碼是否正確,然後選擇跳入到另一個介面,這樣的話,如何在窗體中加入元件呢?監聽器事件有哪些型別,如何定義呢?
(一)元件
在窗體中加入各種元件便於使用者操作,元件有文字元件,按鈕元件,標籤元件和列表元件。
具體的元件設計方式可見Java Swing 圖形介面開發(目錄)
1. 文字元件
-
JTextField 是一個輕量級元件,它允許編輯單行文字。
JavaSwing_2.6: JTextField(文字框)
-
JPasswordField 是一個輕量級元件,允許編輯單行文字,其檢視指示鍵入內容,但不顯示原始字元,顯示為密碼框。
JavaSwing_2.7: JPasswordField(密碼框)
-
JTextArea 是一個顯示純文字的多行區域。
JavaSwing_2.8: JTextArea(文字區域)
示例程式碼:
package VideoTest; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextArea; import javax.swing.JTextField; public class TEST02 extends JFrame { public TEST02() { super("SwingDemo");//定義名稱 JPanel root = new JPanel();//例項化容器 root.add(new JTextField("我是JTextField"));//加入文字框 root.add(new JPasswordField("我是JPasswordField"));//加入密碼框 root.add(new JTextArea("我是JTextArea"));//加入文字域 add(root); //定義窗體相關引數 setSize(400, 300); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new TEST02(); } }
執行結果:
2. 按鈕元件
- JButton 其表現形式為一個按鈕。
- JToggleButton有兩個狀態:按下和彈起。
JavaSwing_2.5: JToggleButton(開關按鈕)
-單選按鈕(JRadioButton), 實現一個單選按鈕,此按鈕項可被選擇或取消選擇,並可為使用者顯示其狀態。與 ButtonGroup 物件配合使用可建立一組按鈕,一次只能選擇其中的一個按鈕。
JavaSwing_2.3: JRadioButton(單選按鈕)
3. 標籤元件
- 標籤 ,使用JComponent的子類JLabel類建立標籤,標籤為使用者提供資訊提示。
JavaSwing_2.1: JLabel(標籤)
4. 列表元件
視窗中的選單條、選單、選單項是我們所熟悉的元件,選單放在選單條裡,選單項放在選單中選單條 。選單條,選單,選單項的關係是:選單項是選單的具體名稱,選單加入到選單條中,選單條加入容器中,選單條是將選單放入窗體的方法,具體而言,飯店的選單上,選單條就是大飯店的選單本,選單就是飯店選單的選單頁, 選單項就是具體的某一個菜的名稱。 - JMenubar 是一個選單條,JFrame類用一個把選單條放到視窗的方法:
setJMenuBar( JMenuBar bar);
該方法將選單條新增到視窗的頂端,需要注意的是,只能向視窗新增一個選單條。
JavaSwing_4.5: JMenuBar(選單欄)
- 選單 JMenu負責建立選單。
- 選單項 JMenuItem負責建立選單項
JMenuItem(String text, Icon icon)
package VideoTest;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
/**
* 選單條,選單,選單項的關係是:選單項是選單的具體名稱,選單加入到選單條中,選單條加入容器中,
* 選單條是將選單放入窗體的方法,具體而言,飯店的選單上,選單條就是大飯店的選單本,選單就是飯店選單的選單頁
* 選單項就是具體的某一個菜的名稱。
*/
public class TEST02 extends JFrame {
JMenuBar menubar;//例項化 選單條
JMenu menu, subMenu;//例項化選單
JMenuItem item1, item2;//例項化選單項
public static void main(String[] args) {
TEST02 win = new TEST02("帶視窗的選單", 20, 30, 400, 500);
}
public TEST02() {
}
//定義方法設定窗體的引數,輸入窗體的大小,名稱,和位置
public TEST02(String s, int x, int y, int w, int h) {
init(s);
setLocation(x, y);
setSize(w, h);
setVisible(true);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
void init(String s) {
setTitle(s);
menubar = new JMenuBar();
menu = new JMenu("選單"); // JMnud的例項就是一個選單
/**
* 一級選單項
*/
subMenu = new JMenu("軟體專案"); // 子選單
item1 = new JMenuItem("Java話題"); // 建立選單項
//使用JMenuItem的構造方法設定圖示
item2 = new JMenuItem("動畫話題" );
item1.setAccelerator(KeyStroke.getKeyStroke('A'));
item2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
//選單項加入選單中。
menu.add(item1);
menu.addSeparator();
menu.add(item2);
menu.add(subMenu);
/**
* 新增二級選單項
*/
subMenu.add(new JMenuItem("汽車銷售系統" ));
subMenu.add(new JMenuItem("農場資訊系統" ));
menubar.add(menu); // 選單條中加入選單
setJMenuBar(menubar); // 新增一個選單條
}
}
執行結果:
常見元件組合的例項:
import java.awt.FlowLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/*
* 這個裡最包含了JavaGUI中的多個元件,
*/
public class TEST02 extends JFrame {
JTextField text;//例項化文字
JButton button;//例項化按鈕
JCheckBox checkBox1, checkBox2, checkBox3;
JRadioButton radio1, radio2;//例項化單選按鈕
ButtonGroup group;//例項化按鈕元件
JComboBox<Object> comBox;
JTextArea area;//定義文字域
JPasswordField password;//定義密碼框
public static void main(String[] args) {
TEST02 win = new TEST02();
win.setBounds(100, 100, 520, 510);
win.setTitle("常用元件");
}
public TEST02() {
init();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
setLayout(new FlowLayout()); // 設定佈局
//定義文字框及其相關引數
add(new JLabel("文字框:"));
text = new JTextField(10);
add(text);
//定義按鈕及其相關引數
add(new JLabel("按鈕:"));
button = new JButton("確認");
add(button);
//定義密碼框及其相關引數
add(new JLabel("密碼框:"));
password = new JPasswordField(10);
add(password);
//定義按鈕標籤及其相關引數
add(new JLabel("按鈕:"));
button = new JButton("確認");
add(button);
//定義 選擇框及其相關引數
add(new JLabel("選擇框:"));
checkBox1 = new JCheckBox("喜歡音樂");
checkBox2 = new JCheckBox("喜歡旅遊");
checkBox3 = new JCheckBox("喜歡籃球");
add(checkBox1);
add(checkBox2);
add(checkBox3);
//定義單選按鈕及其相關引數
add(new JLabel("單選按鈕:"));
group = new ButtonGroup();
radio1 = new JRadioButton("男");
radio2 = new JRadioButton("女");
group.add(radio1);
group.add(radio2);
add(radio1);
add(radio2);
//定義 下拉列表及其相關引數
add(new JLabel("下拉列表:"));
comBox = new JComboBox<>();
comBox.addItem("音樂天地");
comBox.addItem("武術天地");
comBox.addItem("象棋樂園");
add(comBox);
//定義文字區及其相關引數
add(new JLabel("文字區"));
area = new JTextArea(6, 13);// 文字區設定行數和列數
add(new JScrollPane(area));
}
}
執行結果:
在元件的設計中,樹和表格是比較少用的,
-
JTree,樹。將分層資料顯示為樹狀輪廓的元件
JavaSwing_4.9: JTree(樹) -
JTable,表格。JTable 是用來顯示和編輯常規二維單元表。
JavaSwing_4.8: JTable(表格)
(二)監聽器事件
任何支援GUI的操作環境都需要不斷地監聽按鍵或者點選滑鼠這樣的事件,操作環境將這些事件報告給正在執行的程式,如果事件發生,每個程式將決定如何對他們做出反應,當事件發生時,事件源將事件物件傳遞給註冊的監聽器物件,監聽器物件將利用事件的資訊決定如何對事件做出反應。
Java監聽器事件主要有事件源,事件監聽器和事件組成。
1.事件物件:
一般繼承自java.util.EventObject物件,由開發者自行定義.
2.事件源:
就是觸發事件的源頭,註冊監聽器物件,併發送事件物件,不同的事件源會觸發不同的事件型別.
3.事件監聽器:
事件監聽器負責監聽事件源發出的事件.一個事件監聽器通常實現java.util.EventListener這個標識介面.
監聽器事件的處理流程: 事件源可以註冊事件監聽器物件,並可以向事件監聽器物件傳送事件物件.事件發生後,事件源將事件物件發給已經註冊的所有事件監聽器.
監聽器物件隨後會根據事件物件內的相應方法響應這個事件.換句話來說,事件監聽器監聽到事件源的發生以後,執行事件的行為。
常見的監聽器型別有:
基於滑鼠的監聽器事件:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* 這段程式的作用在於在窗體中加入三個按鈕,點選不同的按鈕,窗體的顏色會發生變化。
*/
public class Test01 extends JFrame{
private JPanel buttonPanel;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
//定義窗體
Test01 frame = new Test01();
frame.setTitle("ButtonTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
public Test01()
{
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// create buttons
JButton yellowButton = new JButton("Yellow");
JButton blueButton = new JButton("Blue");
JButton redButton = new JButton("Red");
buttonPanel = new JPanel();
// add buttons to panel
buttonPanel.add(yellowButton);
buttonPanel.add(blueButton);
buttonPanel.add(redButton);
// add panel to frame
add(buttonPanel);
// create button actions
ColorAction yellowAction = new ColorAction(Color.YELLOW);
ColorAction blueAction = new ColorAction(Color.BLUE);
ColorAction redAction = new ColorAction(Color.RED);
// associate actions with buttons
yellowButton.addActionListener(yellowAction);
blueButton.addActionListener(blueAction);
redButton.addActionListener(redAction);
}
/**
* An action listener that sets the panel's background color.
*/
private class ColorAction implements ActionListener
{
private Color backgroundColor;
public ColorAction(Color c)
{
backgroundColor = c;
}
public void actionPerformed(ActionEvent event)
{
buttonPanel.setBackground(backgroundColor);
}
}
}
執行結果:
基於滑鼠的監聽器事件:
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.*;
/*
*這個程式定義一個窗體,然後窗體監聽滑鼠事件,當鼠標出現在窗體中時,通過監聽滑鼠事件
*點選窗體,則顯示滑鼠所在的位置,以及點選次數等
**/
public class Test01 extends JFrame{
My_Panel mp = null;
public Test01() {
mp = new My_Panel();
this.add(mp);
// 註冊監聽
this.addMouseListener(mp); // 監聽滑鼠
this.addKeyListener(mp); // 監聽鍵盤
this.addMouseMotionListener(mp); // 監聽滑鼠移動
//定義窗體的相關引數
this.setSize(300, 300); // 設定框體大小
this.setLocation(400,150); //設定框體顯示的位置
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 設定框體退出
this.setVisible(true); // 顯示框體
}
public static void main(String[] args) {
Test01 d = new Test01();
}
}
class My_Panel extends JPanel implements MouseListener,KeyListener,MouseMotionListener{
public void paint(Graphics g){
super.paint(g);
}
//滑鼠點選
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("滑鼠點選");
System.out.println("滑鼠位置 x = "+e.getX()+" y = "+e.getY());
System.out.println("滑鼠鍵 = "+e.getButton() + " 點選次數 "+e.getClickCount()); // 輸出1是左鍵,2是中鍵,3是右鍵
}
//滑鼠移動到My_Panel
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
// System.out.println("滑鼠移動到My_Panel");
}
//滑鼠離開My_Panel
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
// System.out.println("滑鼠離開My_Panel");
}
//滑鼠按下
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
// System.out.println("滑鼠按下");
}
//滑鼠鬆開
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
// System.out.println("滑鼠鬆開");
}
//鍵按下
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
System.out.println("鍵 = "+e.getKeyChar());
}
//鍵鬆開
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
//鍵輸入
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
//滑鼠按鍵在元件上按下並拖動時呼叫
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
// System.out.println("滑鼠按鍵在元件上按下並拖動時呼叫");
}
//滑鼠游標移動到元件上但無按鍵按下時呼叫
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
// System.out.println("滑鼠游標移動到元件上但無按鍵按下時呼叫");
}
}
執行效果如圖: