Trong ph n trờn đó bàn v cỏch s d ng cỏc exception đ b t cỏc l i khụng đầ ề ử ụ ể ắ ỗ ược ki mể soỏt. Trong ph n này chỳng ta s xem cỏch s d ng ngo i l đ qu n lý cỏc tỡnh hu ng cú thầ ẽ ử ụ ạ ệ ể ả ố ể ki m soỏt để ược.
Cỏc ngo i l d ng này đạ ệ ạ ược khai bỏo ph n đ u cỏc phở ầ ầ ương th c. Vớ d trongứ ụ phương th c kh i t o sau:ứ ở ạ
public FileInputStream(String name) throws FileNotFoundException
đõy ph ng th c nh n m t tham s ki u String nh là tờn file, tuy nhiờn r t cú th
Ở ươ ứ ậ ộ ố ể ư ấ ể
file khụng t m t i ho c là m t file r ng và khụng cú gỡ đ đ c. Khi g p l i nh v y, chồ ạ ặ ộ ỗ ể ọ ặ ỗ ư ậ ương trỡnh s tỡm t i v trớ đ nh nghĩa đ qu n lý l i này.ẽ ớ ị ị ể ả ỗ
M t v n đ là l p trỡnh viờn khụng bi t throws ra ngo i l nào ho c khụng th khaiộ ấ ề ậ ế ạ ệ ặ ể bỏo h t t t c cỏc ngo i l . Tuy nhiờn, cú 4 tỡnh hu ng đ đ a ra ngo i l :ế ấ ả ạ ệ ố ể ư ạ ệ
• Khi g i m t phọ ộ ương th c cú throw m t ngo i l , ch ng h n nhứ ộ ạ ệ ẳ ạ ư FileInputStream.
• Khi ta xỏc đ nh đị ược m t l i và throws m t exception b ng m t l nh throwộ ỗ ộ ằ ộ ệ • Khi vi t m t chế ộ ương trỡnh b l i, ch ng h n a[-1] = 0, s d n đ n vi c kớchị ỗ ẳ ạ ẽ ẫ ế ệ
ho t m t ngo i l , ch ng h n đõy là ArrayIndexOutOfBoundsException.ạ ộ ạ ệ ẳ ạ ở • Khi m t l i bờn trong h th ng nh trong JVM ho c cỏc th vi n đ ng.ộ ỗ ệ ố ư ặ ư ệ ộ M t phộ ương th c c n khai bỏo ngo i l phự h p:ứ ầ ạ ệ ợ
class MyAnimation {
. . .
public Image loadImage(String s) throws IOException {
. . . } }
Phương th c cú th throws nhi u ngo i l n u c n:ứ ể ề ạ ệ ế ầ class MyAnimation
{ . . .
public Image loadImage(String s) throws EOFException, MalformedURLException {
. . . } }
Cỏc ngo i l b t l i n i b c a Java thạ ệ ắ ỗ ộ ộ ủ ường khụng nờn được khai bỏo, đú là cỏc ngo iạ l k th a t l p Error vỡ chỳng vệ ế ừ ừ ớ ượt kh i t m ki m soỏt c a chỳng ta. Đ i v i cỏc ngo i lỏ ầ ể ủ ố ớ ạ ệ khụng được ki m soỏt, chỳng k th a t l p RuntimeException cũng v y, ta khụng nờn khaiể ế ừ ừ ớ ậ bỏo chỳng. Vớ d :ụ
class MyAnimation {
. . .
void drawImage(int i) throws ArrayIndexOutOfBoundsException // Khụng phự h pợ {
. . . } }
Đ i v i cỏc ngo i l d ng RuntimeException, n u chỳng ta cú k ho ch đ khai bỏo núố ớ ạ ệ ạ ế ế ạ ể thỡ t t nh t là tỡm cỏch đ kh c ph c khụng cho chỳng x y ra.ố ấ ể ắ ụ ả
V. Xõy d ng m t ngo i lự ộ ạ ệ
Chỳng ta cú th t xõy d ng m t ngo i l đ throws trong nh ng trể ự ự ộ ạ ệ ể ữ ường h p c th .ợ ụ ể Cỏc class ngo i l này đạ ệ ược k th a t l p Exception ho c l p con c a nú nh IOExceptionế ừ ừ ớ ặ ớ ủ ư ch ng h n. Vớ d :ẳ ạ ụ
class FileFormatException extends IOException {
public FileFormatException() {}
public FileFormatException(String gripe) {
super(gripe); }
}
Sau đú, ta cú th s d ng ngo i l này trong chể ử ụ ạ ệ ương trỡnh: String readData(BufferedReader in) throws FileFormatException { . . . while (. . .) { if (ch = = -1) // Đi m cu i fileể ố { if (n < len)
throw new FileFormatException(); } . . . } return s; } VI. Bài t pậ
1. Vi t chế ương trỡnh đ c m t file trờn đĩa và in ra màn hỡnh. Chỳ ý dựng cỏc ngo i lọ ộ ổ ạ ệ đ ki m soỏt t t c cỏc tỡnh hu ng cú th .ể ể ấ ả ố ể
2. Khai bỏo m t l p ngo i l đ ki m soỏt tỡnh hu ng đi m m t sinh viờn vộ ớ ạ ệ ể ể ố ể ộ ượt quỏ 10 hay tu i c a sinh viờn vổ ủ ượt quỏ 100 trong ng d ng qu n lý sinh viờn đ tài “L p trỡnhứ ụ ả ở ề ậ hướng đ i tố ượng trong Java”.
3. Vi t chế ương trỡnh nh p m t s nguyờn t bàn phớm. B t ngo i l khi ngậ ộ ố ừ ắ ạ ệ ười dựng nh p vào ký t ho c s th c cú ph n th p phõn.ậ ự ặ ố ự ầ ậ
Đ tài 8. X lý cỏc s ki n trong Javaề ử ự ệ I. Khỏi ni m và c s x lý s ki nệ ơ ở ử ự ệ
B t kỳ chấ ương trỡnh cú giao di n đ h a nào thệ ồ ọ ường h tr vi c kớch ho t cỏc s ki nỗ ợ ệ ạ ự ệ t con chu t ho c bàn phớm. Mụi trừ ộ ặ ường đi u hành s g i cỏc s ki n này t i chề ẽ ử ự ệ ớ ương trỡnh đang ch y. L p trỡnh viờn đạ ậ ược hoàn toàn quy t đ nh đi u gỡ s x y ra khi cỏc s ki n nàyế ị ề ẽ ả ự ệ được kớch ho t.ạ
Trong Java s d ng m t cỏch ti p c n d a trờn cỏc khỏi ni m:ử ụ ộ ế ậ ự ệ - Cỏc ngu n c a s ki n (event source)ồ ủ ự ệ
- Cỏc b l ng nghe s ki n (event listener)ộ ắ ự ệ
Cỏc ngu n s ki n chớnh là cỏc đ i tồ ự ệ ố ượng đi u khi n, chỳng cú cỏc phề ể ương th c đứ ể l p trỡnh viờn đăng ký cỏc b l ng nghe cho chỳng. Khi m t s ki n x y ra đ i v i m t ngu nậ ộ ắ ộ ự ệ ả ố ớ ộ ồ s ki n, nú s g i thụng bỏo này t i t t c cỏc b l ng nghe s ki n đự ệ ẽ ử ớ ấ ả ộ ắ ự ệ ược đăng ký cho sự ki n đú.ệ
Đ i v i m t ngụn ng OOP nh Java thỡ toàn b thụng tin v s ki n đố ớ ộ ữ ư ộ ề ự ệ ược đúng gúi trong m t l p event. T t c cỏc l p event đ u d n xu t t l p java.util.EventObject. M i lo iộ ớ ấ ả ớ ề ẫ ấ ừ ớ ỗ ạ s ki n tự ệ ương ng v i m t l p d n xu t, ch ng h n nh ActionEvent và WindowEvent. Sauứ ớ ộ ớ ẫ ấ ẳ ạ ư đõy là cõy phõn c p ch s k th a gi a cỏc l p s ki n trong Java:ấ ỉ ự ế ừ ữ ớ ự ệ
Cỏc s ki n trờn đự ệ ược g i cho cỏc đ i tử ố ượng l ng nghe tắ ương ng nh : ActionListenerứ ư MouseMotionListener AdjustmentListener MouseWheelListener FocusListener WindowListener ItemListener WindowFocusListener KeyListener WindowStateListener MouseListener
Cỏc ngu n s ki n khỏc nhau cú th phỏt sinh cỏc s ki n khỏc nhau. Vớ d m t buttonồ ự ệ ể ự ệ ụ ộ (nỳt b m) thỡ phỏt sinh s ki n ActionEvent trong khi m t c a s l i phỏt sinh s ki nấ ự ệ ộ ử ổ ạ ự ệ WindowEvent.
Túm l i, m t s ki n đạ ộ ự ệ ược qu n lý d a trờn cỏc khỏi ni m:ả ự ệ
1. M t đ i tộ ố ượng l ng nghe là m t bi u hi n c a m t l p cú cài đ t giao di nắ ộ ể ệ ủ ộ ớ ặ ệ l ng nghe s ki nắ ự ệ
2. M t ngu n s ki n là m t đ i tộ ồ ự ệ ộ ố ượng mà cú th đăng ký cỏc đ i tể ố ượng l ngắ nghe và g i cho chỳng cỏc đ i tử ố ượng s ki n.ự ệ
3. Ngu n s ki n g i đ i tồ ự ệ ử ố ượng s ki n t i t t c cỏc đ i tự ệ ớ ấ ả ố ượng l ng nghe đắ ược đăng ký cho s ki n đú.ự ệ
4. Đ i tố ượng l ng nghe s s d ng thụng tin trong cỏc đ i tắ ẽ ử ụ ố ượng s ki n đ ph nự ệ ể ả ng v i cỏc s ki n đú.
ứ ớ ự ệ
Cỳ phỏp đ đăng ký cỏc đ i tể ố ượng l ng nghe cho cỏc ngu n s ki n theo cỳ phỏp sau:ắ ồ ự ệ <ngu n s ki n>.add<s ki n>Listener(<ồ ự ệ ự ệ đ i tố ượng l ng nghe s ki nắ ự ệ >)
Vớ d :ụ
ActionListener listener = . . .; // đ i tố ượng l ng ngheắ JButton button = new JButton("Ok"); // Ngu n s ki nồ ự ệ
button.addActionListener(listener); // đăng ký đ i tố ượng l ng nghe s ki nắ ự ệ
Trong đo n code trờn, v n đ cũn l i là đ i tạ ấ ề ạ ố ượng l ng nghe s ki n ph i cú m tắ ự ệ ả ộ phương th c đ nh n v s ki n t ngu n s ki n đăng ký nú và x lý. ứ ể ậ ề ự ệ ừ ồ ự ệ ử Ở đõy, đ i tố ượng listener ph i thu c m t l p cú cài đ t giao di n ActionListener. Trong giao di n này cú khaiả ộ ộ ớ ặ ệ ệ bỏo m t phộ ương th c actionPerformed đ nh n v m t s ki n ActionEvent:ứ ể ậ ề ộ ự ệ
class MyListener implements ActionListener {
. . .
public void actionPerformed(ActionEvent event) {
// Đo n mó x ký s ki n đ t đõyạ ử ự ệ ặ ở . . .
} }
B t c khi nào ngấ ứ ười dựng click chu t vào đ i tộ ố ượng Jbutton trờn màn hỡnh, m t sộ ự ki n ActionEvent đệ ược phỏt sinh và g i cho đ i tử ố ượng l ng nghe listener. Đ i tắ ố ượng này cú cài đ t m t phặ ộ ương th c đ x lý s ki n là actionPerformed, l y đ i s là đ i tứ ể ử ự ệ ấ ố ố ố ượng ActionEvent nh n đậ ược.
Cú th cú nhi u b l ng nghe để ề ộ ắ ược đăng ký cho m t ngu n s ki n, khi đú s ki nộ ồ ự ệ ự ệ cũng được g i t i t t c cỏc b l ng nghe và t i phử ớ ấ ả ộ ắ ớ ương th c actionPerformed c a chỳng.ứ ủ
S đ sequence cho đo n code trờn nh sau:ơ ồ ạ ư
Sau đõy là m t vớ d v x lý s ki n click cho 3 đ i tộ ụ ề ử ự ệ ố ượng Jbutton:
M t Button độ ượ ạc t o ra nh sau b ng cỏch g i constructor c a JButton v i m t chu iư ằ ọ ủ ớ ộ ỗ nhón ho c m t nh hay c hai:ặ ộ ả ả
JButton yellowButton = new JButton("Yellow");
JButton blueButton = new JButton(new ImageIcon("blue-ball.gif")); Thờm 3 Button vào 1 panel nh sau:ư
Class ButtonPanel extends JPanel {
public ButtonPanel() {
JButton yellowButton = new JButton("Yellow"); JButton blueButton = new JButton("Blue");
JButton redButton = new JButton("Red"); add(yellowButton); add(blueButton); add(redButton); } }
Bõy gi chỳng ta đ nh nghĩacỏc b l ng nghe cho cỏc Button này g i là ColorAction nhờ ị ộ ắ ọ ư sau:
public class ColorAction implements ActionListener {
public ColorAction(Color c) {
backgroundColor =c; }
public void actionPerformed(ActionEvent e) {
setBackground(backgroundColor); // Thay đ i màu n n c a panel khi Button đổ ề ủ ược click
}
private Color backgroundColor; }
M i đ i tỗ ố ượng Button được đăng ký cho b l ng nghe này:ộ ắ Class ButtonPanel extends JPanel
{
public ButtonPanel() {
JButton yellowButton = new JButton("Yellow"); JButton blueButton = new JButton("Blue"); JButton redButton = new JButton("Red"); add(yellowButton);
add(blueButton); add(redButton);
ColorAction yellowAction = new ColorAction(Color.Yellow); ColorAction blueAction = new ColorAction(Color.Blue); ColorAction redAction = new ColorAction(Color.Red); yellowButton.addActionListener(yellowAction); blueButton.addActionListener(blueAction); redButton.addActionListener(redAction); }
}
M t v n đ đ t ra là phộ ấ ề ặ ương th c setBackground() khụng đứ ược đ nh nghĩa trong l pị ớ ColorAction mà ch đỉ ược đ nh nghĩa cho l p Panel. Gi i phỏp đõy là đ a l p ColorActionị ớ ả ở ư ớ
thành l p n i c a l p ButtonPanel, khi đú trong l p ColorAction, ta cú th truy c p cỏcớ ộ ủ ớ ớ ể ậ phương th c c a l p Panel (đứ ủ ớ ược ButtonPanel k th a) nh setBackground ch ng h n.ế ừ ư ẳ ạ
Class ButtonPanel extends JPanel {
public ButtonPanel() {
JButton yellowButton = new JButton("Yellow"); JButton blueButton = new JButton("Blue"); JButton redButton = new JButton("Red"); add(yellowButton);
add(blueButton); add(redButton);
ColorAction yellowAction = new ColorAction(Color.Yellow); ColorAction blueAction = new ColorAction(Color.Blue); ColorAction redAction = new ColorAction(Color.Red);
yellowButton.addActionListener(yellowAction); // Đăng ký b l ng nghe s ki nộ ắ ự ệ blueButton.addActionListener(blueAction);
redButton.addActionListener(redAction); }
private class ColorAction implements ActionListener {
public ColorAction(Color c) {
backgroundColor =c; }
public void actionPerformed(ActionEvent e) {
setBackground(backgroundColor); // Thay đ i màu n n c a panel khi Button đổ ề ủ ược click
}
private Color backgroundColor; }
}
Chương trỡnh sau đõy ki m tra s th c hi n đỏp ng cỏc s ki n v a thi t k trờn:ể ự ự ệ ứ ự ệ ừ ế ế ở import javax.swing.JFrame;
public class testPanel extends JFrame {
public testPanel() {
ButtonPanel pn = new ButtonPanel(); this.add(pn);
public static void main(String[] argvs) {
testPanel p = new testPanel(); p.setSize(300,400);
p.setVisible(true); }
}
Thụng thường, cỏc l p l ng nghe s ki n cú th đớ ắ ự ệ ể ược cài đ t ngay trong phặ ương th cứ addActionListener nh sau:ư
yellowButton.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent event) {
setBackground(Color.YELLOW); }
});
Làm nh v y ta khụng c n thi t k riờng m t l p ColorAction.ư ậ ầ ế ế ộ ớ
II. Truy c p thụng tin s ki nậ ự ệ
M t phộ ương phỏp khỏc đ l p trỡnh s ki n đú là gỏn cho t t c cỏc đ i tể ậ ự ệ ấ ả ố ượng ngu nồ s ki n chung m t đ i tự ệ ộ ố ượng l ng nghe. Tựy theo thụng tin v s ki n nh n đắ ề ự ệ ậ ược, phương th c actionPerformed s cú s hành x khỏc nhau. Mu n v y, l p ch a cỏc ngu n s ki nứ ẽ ự ử ố ậ ớ ứ ồ ự ệ ph i cài đ t giao di n ActionListener.ả ặ ệ
import javax.swing.*; import java.awt.event.*;
public class ButtonPanel extends JPanel implements ActionListener { JButton yellowButton;
JButton blueButton; JButton redButton; public ButtonPanel() {
yellowButton = new JButton("Yellow"); blueButton = new JButton("Blue"); redButton = new JButton("Red"); add(yellowButton); add(blueButton); add(redButton); yellowButton.addActionListener(this); blueButton.addActionListener(this); redButton.addActionListener(this); }
public void actionPerformed(ActionEvent event) {
if (event.getSource()==yellowButton) setBackground(Color.YELLOW);
if (event.getSource()==redButton) setBackground(Color.RED); if (event.getSource()==blueButton) setBackground(Color.BLUE); }
}
Trong vớ d trờn, b n thõn l p component ButtonPanel đúng vai trũ là l p l ng nghe sụ ả ớ ớ ắ ự ki n vỡ nú cú cài đ t giao di n ActionListener. Do đú, khi đăng ký đ i tệ ặ ệ ố ượng l ng nghe cho cỏcắ Button, ta ch vi c s d ng bi n this, đ i di n cho đ i tỉ ệ ử ụ ế ạ ệ ố ượng ng m đ nh c a chớnh l pầ ị ủ ớ ButtonPanel. Cỏc đ i tố ượng Button bõy gi cũng ph i khai bỏo là bi n thành ph n c a l p vỡờ ả ế ầ ủ ớ chỳng được truy c p trong 2 phậ ương th c khỏc nhau.ứ Tuy nhiờn phương phỏp này s tr nờnẽ ở khú dựng khi trờn panel cú nhi u đ i tề ố ượng ngu n s ki n.ồ ự ệ
III. X lý cỏc s ki n trờn windowử ự ệ
Ph n trờn đó cho th y cỏch th c chỳng ta làm vi c v i cỏc ngu n s ki n là cỏc đ iầ ấ ứ ệ ớ ồ ự ệ ố tượng n m trong m t window. Ph n này ta s xem xột cỏc s ki n x y ra đ i v i b n thõnằ ộ ầ ẽ ự ệ ả ố ớ ả m t window.ộ
Mu n b t cỏc s ki n c a window, ta cũng qua cỏc bố ắ ự ệ ủ ước căn b n sau:ả WindowListener listener = new ...
frame.addWindowListener(listener);
Trong đú frame là m t đ i tộ ố ượng c a l p JFrame, là đ i tủ ớ ố ượng ngu n s ki n phỏt sinhồ ự ệ cỏc s ki n WindowEvent. Đ i tự ệ ố ượng listener b t bu c ph i thu c m t l p cú cài đ t giaoắ ộ ả ộ ộ ớ ặ di n WindowListener. C u trỳc c a giao di n này nh sau:ệ ấ ủ ệ ư
public interface WindowListener {
void windowOpened(WindowEvent e); void windowClosing(WindowEvent e); void windowClosed(WindowEvent e);
void windowIconified(WindowEvent e); // thu nh c a sỏ ủ ổ void windowDeiconified(WindowEvent e);
void windowActivated(WindowEvent e); void windowDeactivated(WindowEvent e); }
Do đú cỏc l p cài đ t giao di n này ph i khai bỏo đ nh nghĩa t t c cỏc phớ ặ ệ ả ị ấ ả ương th cứ trờn. Tuy nhiờn, ta ch vi t code cho phỉ ế ương th c nào ta x lý mà thụi, vớ d :ứ ử ụ
class Terminator implements WindowListener {
public void windowClosing(WindowEvent e) {
System.exit(0); }
public void windowOpened(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {} }
IV. Cỏc l p thớch nghiớ
Ta th y r ng vi c khai bỏo đ y đ 7 phấ ằ ệ ầ ủ ương th c, cú nh ng phứ ữ ương th c khụng x lýứ ử gỡ c làm cho chả ương trỡnh khụng đượ ố ưc t i u. Gi i phỏp đõy s là đ nh nghĩa m t l p trungả ở ẽ ị ộ ớ gian, khai bỏo cài đ t giao di n WindowListener v i đ y đ 7 phặ ệ ớ ầ ủ ương th c nh ng cỏc phứ ư ương th c này cũng khụng làm gỡ c . Cỏc l p mu n cài đ t n i dung cho m t s ki n ch vi c khaiứ ả ớ ố ặ ộ ộ ự ệ ỉ ệ bỏo k th a l p này và đ nh nghĩa ch ng phế ừ ớ ị ồ ương th c c n thi t. Cỏc l p cú vai trũ trung gianứ ầ ế ớ nh v y g i là cỏc l p thớch nghi. V i m i giao di n l ng nghe, ta cú m t l p thớch nghi tư ậ ọ ớ ớ ỗ ệ ắ ộ ớ ương ng. Vớ d : WindowListener cú l p thớch nghi WindowAdapter, MouseListener cú
ứ ụ ớ
MouseAdapter. Cỏc l p thớch nghi thớ ường dựng là: FocusAdapter MouseMotionAdapter KeyAdapter WindowAdapter MouseAdapter
class Terminator extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0); }
}
V n đ là cỏc l p ấ ề ớ window thường ph i khai bỏo k th a t JFrame r i nờn khụng thả ế ừ ừ ồ ể khai bỏo k th a thờm l p WindowAdapter. Lỳc này, k thu t đ nh nghĩa l p n i n c danhế ừ ớ ỹ ậ ị ớ ộ ặ được phỏt huy:
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
System.exit(0);
}
public void windowIconified(WindowEvent e) {System.exit(0);} } );
Đo n code này th c hi n cỏc cụng vi c sau:ạ ự ệ ệ
1. Đ nh nghĩa m t class n c danh k th a l p WindowAdapterị ộ ặ ế ừ ớ
2. Thờm 2 phương th c windowClosing và windowIconified cho l p n c danh đúứ ớ ặ 3. K th a 5 phế ừ ương th c cũn l i t WindowAdapterứ ạ ừ
4. T o ra m t đ i tạ ộ ố ượng c a l p đú, đ i tủ ớ ố ượng cũng khụng cú tờn 5. G i đ i tử ố ượng này cho phương th c addWindowListenerứ
Ta cú th đ nh nghĩa ch ng nhi u h n m t phể ị ồ ề ơ ộ ương th c c a WindowAdapter. ứ ủ
T t nhiờn là khụng ph i khi nào ta cũng ph i s d ng l p n i n c danh. M t cỏch làmấ ả ả ử ụ ớ ộ ặ ộ khỏc là khai bỏo m t l p (thộ ớ ường là l p n i) d ng nh class Terminator trờn, sau đú đăng kýớ ộ ạ ư ở l ng nghe s ki n cho frame mà khụng c n m t đ i tắ ự ệ ầ ộ ố ượng cú tờn rừ ràng c a Terminator:ủ
frame.addWindowListener(new Terminator());
Đ k t thỳc đ tài này ta li t kờ cỏc phể ế ề ệ ương th c x lý s ki n nh b ng sau:ứ ử ự ệ ư ả