事件表示程式和使用者之間的互動,例如在文本框中輸入,在清單框或組合框中選擇,選中複選框和單選框,單擊按鈕等。事件處理表示程式對事件的響應,對使用者的互動或者說對事件的處理是事件處理程式完成的。
當事件發生時,系統會自動捕捉這一事件,建立表示動作的事件對象并把它們分派給程式内的事件處理程式代碼。這種代碼确定了如何處理此事件以使使用者得到相應的回答。
文章目錄
-
-
-
- 事件處理模型
- 動作事件監聽器
- 焦點事件監聽器
- 監聽清單項選擇事件
-
-
事件處理模型
前面我們講解了如何放置各種元件,使圖形界面更加豐富多彩,但是還不能響應使用者的任何操作。若使圖形界面能夠接收使用者的操作,必須給各個元件加上事件處理機制。在事件處理的過程中,主要涉及三類對象。
- Event(事件):使用者對元件的一次操作稱為一個事件,以類的形式出現。例如,鍵盤操作對應的事件類是 KeyEvent。
- Event Source(事件源):事件發生的場所,通常就是各個元件,例如按鈕 Button。
- Event Handler(事件處理者):接收事件對象并對其進行處理的對象事件處理器,通常就是某個 Java 類中負責處理事件的成員方法。
例如,如果滑鼠單擊了按鈕對象 Button,則該按鈕 Button 就是事件源,而 Java 運作時系統會生成 ActionEvent 類的對象 ActionEvent,該對象中描述了單擊事件發生時的一些資訊。之後,事件處理者對象将接收由 Java 運作時系統傳遞過來的事件對象 ActionEvent,并進行相應的處理。事件處理模型如圖 1 所示。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL5gDO1UjMwUTMzEzMwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
由于同一個事件源上可能發生多種事件,是以,Java 采取了授權模型(Delegation Model),事件源可以把在其自身上所有可能發生的事件分别授權給不同的事件處理者來處理。例如,在 Panel 對象上既可能發生滑鼠事件,也可能發生鍵盤事件,該 Panel 對象可以授權給事件處理者 a 來處理滑鼠事件,同時授權給事件處理者 b 來處理鍵盤事件。
有時也将事件處理者稱為監聽器,主要原因在于監聽器時刻監聽事件源上所有發生的事件類型,一旦該事件類型與自己所負責處理的事件類型一緻,就馬上進行處理。授權模型把事件的處理委托給外部的處理實體進行處理,實作了将事件源和監聽器分開的機制。
事件處理者(監聽器)通常是一個類,該類如果能夠處理某種類型的事件,就必須實作與該事件類型相對的接口。例如,一個 ButtonHandler 類之是以能夠處理 ActionEvent 事件,原因在于它實作了與 ActionEvent 事件對應的接口 ActionListener。每個事件類都有一個與之相對應的接口。
動作事件監聽器
動作事件監聽器是 Swing 中比較常用的事件監聽器,很多元件的動作都會使用它監聽,像按鈕被裡擊、清單框中選擇一項等。與動作事件監聽器有關的資訊如下。
- 事件名稱:ActionEvent。
- 事件監聽接口: ActionListener。
- 事件相關方法:addActionListener() 添加監聽,removeActionListener() 删除監聽。
- 涉及事件源:JButton、JList、JTextField 等。
例 1
下面以按鈕的單擊事件為例來說明動作單擊事件監聽器的應用。在此案例中統計了視窗内按鈕被單擊的次數。
本案例的核心代碼如下:
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class ActionListenerDemo extends JFrame
{
JList list;
JLabel label;
JButton button1;
int clicks=0;
public ActionListenerDemo()
{
setTitle("動作事件監聽器示例");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,400,200);
JPanel contentPane=new JPanel();
contentPane.setBorder(new EmptyBorder(5,5,5,5));
contentPane.setLayout(new BorderLayout(0,0));
setContentPane(contentPane);
label=new JLabel(" ");
label.setFont(new Font("楷體",Font.BOLD,16)); //修改字型樣式
contentPane.add(label, BorderLayout.SOUTH);
button1=new JButton("我是普通按鈕"); //建立JButton對象
button1.setFont(new Font("黑體",Font.BOLD,16)); //修改字型樣式
button1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
label.setText("按鈕被單擊了 "+(clicks++)+" 次");
}
});
contentPane.add(button1);
}
//處理按鈕單擊事件的匿名内部類
class button1ActionListener implements ActionListener
{
@Override
public void actionPerformed(ActionEvent e)
{
label.setText("按鈕被單擊了 "+(clicks++)+" 次");
}
}
public static void main(String[] args)
{
ActionListenerDemo frame=new ActionListenerDemo();
frame.setVisible(true);
}
}
上述代碼調用 addActionListener() 方法為 button1 添加了單擊動作的事件監聽器,該監聽器由 button1ActionListener 類來實作。button1ActionListener 類必須繼承 ActionListener 類,并重寫父類的 actionPerformed() 方法。在 actionPerformed() 方法内編寫按鈕被單擊後執行的功能。
圖 2 所示為程式運作後,沒有單擊和單擊後的效果。
在本例中使用的是内部類形式,當然也可以寫成如下形式的代碼:
//為按鈕buttonl添加ActionEvent事件的處理程式
buttonl.addActionListener(new ActionListener()
{
public void action Performed(Action Event e)
{
//具體代碼編寫在這裡
label.setTextC 按鈕被單擊了 "+(ciicks++)+1 次");
}
}
焦點事件監聽器
除了單擊事件外,焦點事件監聽器在實際項目中應用也比較廣泛,例如将光标離開文本框時彈出對話框,或者将焦點傳回給文本框等。
與焦點事件監聽器有關的資訊如下。
- 事件名稱:FocusEvent。
- 事件監聽接口: FocusListener。
- 事件相關方法:addFocusListener() 添加監聽,removeFocusListener() 删除監聽。
- 涉及事件源:Component 以及派生類。
FocusEvent 接口定義了兩個方法,分别為 focusGained() 方法和 focusLost() 方法,其中 focusGained() 方法是在元件獲得焦點時執行,focusLost() 方法是在元件失去焦點時執行。
例 2
下面以文本框的焦點事件為例來說明焦點單擊事件監聽器的應用。本案例的核心代碼如下:
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class FocusListenerDemo extends JFrame
{
JList list;
JLabel label;
JButton button1;
JTextField txtfield1;
public FocusListenerDemo()
{
setTitle("焦點事件監聽器示例");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,400,200);
JPanel contentPane=new JPanel();
contentPane.setBorder(new EmptyBorder(5,5,5,5));
contentPane.setLayout(new BorderLayout(0,0));
setContentPane(contentPane);
label=new JLabel(" ");
label.setFont(new Font("楷體",Font.BOLD,16)); //修改字型樣式
contentPane.add(label, BorderLayout.SOUTH);
txtfield1=new JTextField(); //建立文本框
txtfield1.setFont(new Font("黑體", Font.BOLD, 16)); //修改字型樣式
txtfield1.addFocusListener(new FocusListener()
{
@Override
public void focusGained(FocusEvent arg0)
{
// 擷取焦點時執行此方法
label.setText("文本框獲得焦點,正在輸入内容");
}
@Override
public void focusLost(FocusEvent arg0)
{
// 失去焦點時執行此方法
label.setText("文本框失去焦點,内容輸入完成");
}
});
contentPane.add(txtfield1);
}
public static void main(String[] args)
{
FocusListenerDemo frame=new FocusListenerDemo();
frame.setVisible(true);
}
}
上述代碼為 txtfield1 元件調用 addFocusListener() 方法添加了焦點事件監聽器,并且監聽器使用匿名的實作方式。在實作 FocusListener 接口的代碼中編寫 focusGained() 方法和 focusLost() 方法的代碼。最終程式運作效果如圖 3 所示。
監聽清單項選擇事件
清單框控件 JList 會顯示很多項供使用者選擇,通常在使用時會根據使用者選擇的清單項完成不同的操作。
本案例将介紹如何監聽清單項的選擇事件,以及事件監聽器的處理方法,實作過程如下。
(1) 建立一個繼承自 JFrame 的 JListDemo2 類。
(2) 在 JListDemo2 類中添加 JList 元件和 JLabel 元件的聲明,并建立空的構造方法,代碼如下所示。
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class JListDemo2 extends JFrame
{
JList list;
JLabel label;
public JListDemo2(){};
public static void main(String[] args)
{
JListDemo2 frame=new JListDemo2();
frame.setVisible(true);
}
}
(3) 在構造方法中為清單框填充資料源,主要代碼如下:
public JListDemo2()
{
setTitle("監聽清單項選擇事件");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,400,200);
JPanel contentPane=new JPanel();
contentPane.setBorder(new EmptyBorder(5,5,5,5));
contentPane.setLayout(new BorderLayout(0,0));
setContentPane(contentPane);
label=new JLabel(" ");
contentPane.add(label,BorderLayout.SOUTH);
JScrollPane scrollPane=new JScrollPane();
contentPane.add(scrollPane,BorderLayout.CENTER);
list=new JList();
scrollPane.setViewportView(list);
String[] listData=new String[7];
listData[0]="《一點就通學Java》";
listData[1]="《一點就通學PHP》";
listData[2]="《一點就通學Visual Basic)》";
listData[3]="《一點就通學Visual C++)》";
listData[4]="《Java程式設計詞典》";
listData[5]="《PHP程式設計詞典》";
listData[6]="《C++程式設計詞典》";
list.setListData(listData);
}
(4) 為清單框元件 list 添加選擇事件監聽,代碼如下所示。
list.addListSelectionListener(new ListSelectionListener()
{
public void valueChanged(ListSelectionEvent e)
{
do_list_valueChanged(e);
}
});
如上述代碼所示,list 元件綁定了 ListSelectionListener 事件監聽器,在觸發該事件後又會調用 do_list_valueChanged() 方法進行實際的業務邏輯處理。
(5) 建立 do_liSt_ValueChanged() 方法将使用者選擇的列顯示到标簽中,具體代碼如下:
protected void do_list_valueChanged(ListSelectionEvent e)
{
label.setText("感謝您購買:"+list.getSelectedValue());
}
(6) 運作程式,清單框選擇前後的效果如圖 4 所示。
謝謝觀看