השלטת מטפלי אירועים מסוג “נוחיות” Convenience Event Handlers
- מטפלי אירועים מטיפוס “נוחיות” וסוגי האירועים המשויכים להם
- תוכנית הדגמה
- סיכום
למיטב ידיעתי, החומר בשיעור זה תואם את תיעוד ה-API של Java 1.0.2.
ניתן כעת להשיג את גירסת הביתא של JDK 1.1 לשם בדיקה, וב- Sun פורסם כי היא תכיל שינויים חשובים בנוגע ל- Abstract Windows Toolkit, ובכללם שינויים בנושא יישום אירועים וטיפול באירועים.
כאשר תצאJKD 1.1 ויהיה מידע זמין אודות שינויים אלה, יתווסף לשיעור זה שיעור נוסף שיתאר אירועים וטיפול באירועים במסגרת JDK 1.1.
באחד השיעורים הקודמים למדת כיצד לדרוס את המתודה handleEvent() של המחלקה Component על מנת להגיב לאירועים. באפשרותך לטפל בכל אירוע שהוא על-ידי דריסת המתודה handleEvent() מכיוון שהמתודה handleEvent() מופעלת באמצעות מערכת run-time בכל פעם שמתרחש אירוע כלשהו.
כאשר אתה דורס את המתודה handleEvent, כל המידע הזמין אודות האירוע נכלא באובייקט של המחלקה Event ומועבר פנימה כפרמטר. לכן, יש לך אפשרות להשתמש בכל המידע במהלך הטיפול שלך באירוע.
עם זאת, כדי לקבל גישה למידע זה, עליך להיכנס לאובייקט ולקבל גישה אל הנתונים בשדות הבודדים של האובייקט. בשיעור הקודם הוזכר גם כי בנוסף למתודה handleEvent(), המחלקה Component מספקת מספר מתודות "“נוחיות”" (convenience) שניתן לעיתים להשתמש בהן כדי לטפל באירועים מסוימים בצורה נוחה יותר.
מתודות "“נוחיות”" אלה קיימות במחלקה Component כמעטפות ריקות (empty shells) אותן באפשרותך לדרוס בתוכניתך.
אופן התפקוד של המתודה handleEvent() במצב ברירת מחדל הוא:
- לחלץ את סוג האירוע משדה ה-id של אובייקט ה- Event ו-
- לקרוא למטפל “ נוחיות” תואם, במקרים בהם מסופק מטפל אירועים תואם.
לכן, אם אתה דורס מתודת “נוחיות” אחת או יותר, המתודות הנדרסות שלך יופעלו באופן אוטומטי מבלי שתידרש תחילה לטפל בשדה ה-id של אובייקט ה- Event.
בנוסף, מידע ספציפי מסוים לגבי אירועים מחולץ מאובייקט ה- Event ומועבר כפרמטרים תוך שהוא לעיתים קרובות חוסך ממך את הצורך לטפל באופן כלשהו באובייקט ה- Event.
לדוגמה, באירועי עכבר, מועברות קואורדינטות ה-x ו- y של העכבר פנימה כפרמטרים כאשר האירוע מתרחש.
בכל המקרים, אובייקט ה- Event מועבר גם הוא פנימה כפרמטר במקרה שדרוש לך לחלץ מידע נוסף מהאובייקט.
מטפלי אירועים מטיפוס “נוחיות” וסוגי האירועים המשויכים להם
מקטע הקוד הבא, המדגים את התפקוד של handleEvent() במצב ברירת מחדל, מזהה את הסוגים השונים של מטפלי אירועים מסוג “נוחיות” ואת סוגי האירועים המשויכים להם, כפי שמצוין בשדה ה- idשל אובייקט ה- Event.
שימו לב בבקשה למקור של מקטע הקוד כפי שמצוין בהערות המופיעות בהתחלה.
כמו כן, יש לציין כי קיימים כ- 14 ערכי id אחרים המוגדרים כקבועים תוויים במחלקה Event שעבורם לא מסופקים מטפלי אירועים מסוג “נוחיות” בגירסת ברירת המחדל של handleEvent(). יש לטפל בסוגי אירועים אלה על-ידי דריסת המתודה handleEvent().
לדוגמה, תוכנית ההדגמה בשלב מאוחר יותר של שיעור זה עושה שימוש באירוע מסוג WINDOW_DESTROY כדי להעיף את התוכנית כאשר המשתמש סוגר את החלון. לא קיים שום מטפל באירועים מסוג “נוחיות” לאירוע מסוג זה.
/*File Event01.txtThis is Listing 19-12 from
Using Java, Special Editionby Joseph Weber, et al.*/public boolean handleEvent(Event evt) {
switch (evt.id) {
case Event.MOUSE_ENTER:return mouseEnter(evt, evt.x,
evt.y);
case Event.MOUSE_EXIT:return mouseExit(evt, evt.x, evt.y);
case Event.MOUSE_MOVE:return mouseMove(evt, evt.x, evt.y);
case Event.MOUSE_DOWN:return mouseDown(evt, evt.x, evt.y);
case Event.MOUSE_DRAG:return mouseDrag(evt, evt.x, evt.y);
case Event.MOUSE_UP:return mouseUp(evt, evt.x, evt.y);
case Event.KEY_PRESS:
case Event.KEY_ACTION:return keyDown(evt, evt.key);
case Event.KEY_RELEASE:
case Event.KEY_ACTION_RELEASE:return keyUp(evt, evt.key);
case Event.ACTION_EVENT:return action(evt, evt.arg);
case Event.GOT_FOCUS:return gotFocus(evt, evt.arg);
case Event.LOST_FOCUS:return lostFocus(evt, evt.arg);
} //end switch
return false;
}
תוכנית הדגמה
תוכנית ההדגמה שלהלן מדגימה את השימוש במטפל אירועים מסוג "נוחיות" על-ידי דריסת האירוע mouseDown().
שים לב כי תוכנית זו כוללת גם גירסה דרוסה של המתודה handleEvent() כדי לטפל באירוע הנוצר כאשר המשתמש סוגר את החלון (סוג אירוע WINDOW_DESTROY).
מטפל אירועים זה מעיף את התוכנית. לא קיים שום מטפל נוחיות הזמין לטיפול באירוע זה.
דיון זה יתמקד בסוגיות הקשורות באירועים וידחה סוגיות הקשורות ב-GUI לאחד השיעורים הבאים. כפי שתוכל לראות, תוכנית זו דומה מאוד לתוכנית הנקראת Event01.java המופיעה באחד השיעורים הקודמים אך יחד עם זאת,
- התוכנית ההיא עשתה שימוש בגירסה דרוסה של ()handieEvent כדי לטפל באירוע מסוג MOUSE_DOWN ו-
- מטפל האירועים הדרוס mouseDown() מופיע בהדגשה בפירוט שלהלן.
כפי שתוכל לראות, המידע הדרוש לטיפול באירוע מועבר באופן "נוח" ואין כל דרישה שמתודה הדרוסה תפצח ותפתח את אובייקט ה- Event כדי להשיג מידע נוסף (במקרה זה).
משום כך היא עשויה להיחשב כנוחה יותר לעומת דריסת handleEvent().
הקוד בגירסה הדרוסה של mouseDown() מבצע כעיקרון את אותן הפעולות כמו הקוד התואם בתוכנית הקודמת. כמו כן, הקוד שנשאר בשתי התוכניות הוא כעקרון זהה.
מכיוון שהפעלת התוכנית הדומה נידונה באופן פרטני בשיעור קודם, איו צורך בדיון מעמיק בשיעור זה.
/*File Event02.java Copyright 1997, R.G.Baldwin
Illustrates overriding of a "convenience" event handler
by overriding the mouseDown() method of the Component class.
Displays the coordinates of mouse clicks in a window.
Also overrides handleEvent() to respond to WINDOW_DESTROY
to terminate the program when the user clicks the close box.*/import java.awt.*;
//Make the controlling class extend the Frame class
// to produce a graphic window.
public class Event02 extends Frame{
String msg = "";
//save message for display here
int clickX = 0, clickY = 0;//save coordinates for
//display here
//Create and size the window
public static void main(String[] args){
Event02 displayWindow = new Event02(); //instantiate obj
//of this type
displayWindow.resize(300,200);//set window size
displayWindow.setTitle("Copyright 1997, R.G.Baldwin");
displayWindow.show();//display the window
}//end main
//Event handler overrides handleEvent()
// method in Component class to close window.
public boolean handleEvent(Event evntObj){
if(evntObj.id == Event.WINDOW_DESTROY) System.exit(0);
return super.handleEvent(evntObj);
}//end handleEvent()
//Override the mouseDown() method of Component class
public boolean mouseDown(Event evt, int x, int y){
clickX = x; //save mouse coordinates
clickY = y;
msg = "" + x + ", " + y;
//construct message for display
repaint(); //force a repaint of the window
return true;
}//end overridden mouseDown()
//Override paint method to repaint the window
public void paint(Graphics g){
g.drawString(msg, clickX, clickY);
}//end paint()
}//end class Event02
סיכום
תועלת העיקרית בהשלטת מטפלי אירועים מסוג "נוחיות" היא שבמקרים מסוימים, אין צורך לפצחולפתוח את אובייקט ה- Event כדי להשיג מידע לשם טיפול באירוע.
זה נכון לגבי אותם מקרים בהם הגירסה המשמשת כברירת מחדל של handleEvent() משיגה את כל המידע הדרוש על-מנת לטפל באירוע כראוי ומעבירה אותו. קיימים גם מקרים רבים בהם המצב שונה והם מחייבים פיצוח ופתיחת אובייקט ה- Event בתוך מטפל הנוחיות המושלט כדי לטפל באירוע כראוי. במקרים אלה יהיה עליך להיות השופט כל עוד מדובר ב "נוחיות".
זכור, אם תרצה, באפשרותך להתעלם לחלוטין מקיומם של מטפל אירועים מסוג "נוחיות" ולטפל בכל האירועים על-ידי השלטת המתודה handleEvent().