תוכנית הדגמה לטיפול באירועים
- כיצד זה פועל?
- מחלקת משנה של Component
- דריסת המתודה handleEvent()
- מתודה המטפלת באירועים ומותאמת אישית
- דריסת המתודה paint()
התוכנית הבאה היא התוכנית הפשוטה ביותר לטיפול באירועים שהייתי מסוגל ליצור.
היא לא מבצעת הרבה, אולם היא כן ממחישה מספר נקודות חשובות.
כדי ללמד אותה באופן יעיל, נצטרך להקרין כמה שקפים או להציג אותה כשהיא מורצת בפועל בכיתה. השיטה השנייה היא הצורה היעילה ביותר.
אני נמנעתי בכוונה מהשימוש במתודות הנוחיות במקרה זה ודרסתי את handleEvent() לטיפול בכל האירועים הנצרכים.
?כיצד זה פועל
התוכנית יוצרת חלון קטן על המסך. אם אתה מצביע על נקודה בתוך החלון ולוחץ על הלחצן השמאלי של העכבר, התוכנית מציגה את הקואורדינטות של מצביע העכבר בזמן ובמיקום של הלחיצה.
זה מתבצע על ידי תגובה לאירועי MOUSE_DOWN. אם תלחץ על נקודה מחוץ לחלון, התוכנית תתעלם מכך לחלוטין.
התוכנית גם מגיבה לאירועי WINDOW_DESTROY.
זה סוג האירוע המתרחש כשאתה סוגר חלון באמצעות לחיצה על לחצן ה x שבפינה הימנית העליונה של החלון, או על ידי לחיצה כפולה על תיבת הבקרה שבפינה השמאלית העליונה של החלון.
כיוון שזו התוכנית הראשונה שלנו לטיפול באירועים, נדון בה באופן פרטני למדי.
יחד עם זאת, הדיון יתמקד יותר על קוד בהקשר לאירועים מאשר על קוד בהקשר ל GUI.
/*File Event01.java Copyright 1997, R.G.Baldwin Illustrates a very simple event handler that overrides |
אנו זקוקים למחלקת משנה של Component
דבר ראשון, כדי שיהיה ביכולתנו לעבד אירועים, אנו זקוקים לאובייקט שנוצר מהמחלקה ComponentT .
אנו משיגים זאת על ידי כך שאנו גורמים למחלקה שלנו המכונה Event01 לרשת מ Frame, שיורשת מ Window, שיורשת מ Container, שיורשת מ Component.
ואז, כשאנו יוצרים מופע לאובייקט של המחלקה Event01 שלנו, אנו מקבלים אובייקט שמסוגל להגיב לכל האירועים שנתמכים על ידי Component .
מתודת ה main() הבאה:
· יוצרת מופע לאובייקט,
· מתאימה את המידה שלו,
· שמה כותרת בראש החלון, ו-
· גורמת לכך שניתן יהיה לראות אותה על המסך.
אני סמוך ובטוח שכעת אתה מבין את ההצהרה שיוצרת מופע לאובייקט. אנו נדון במתודות בעלות הזיקה ל GUI האלו יותר לעומק באחד השיעורים הבאים.
//Create and size the window |
דריסת המתודה handleEvent()
המתודה הבאה שבה נדון היא הגרסה הדרוסה של handleEvent().
כשאתה דורס את המתודה הזו, הקוד שלך יקבל כפרמטר אובייקט מסוג Event כשקוראים למתודה. בגרסה הדרוסה הזו, בנינו פקודת switch הבוחנת את שדה ה id של האובייקט הנכנס לעומת הקבועים התוויים MOUSE_DOWN ו- WINDOW_DESTROY. גרסה זו של המתודה לא מנסה לטפל באירועים אחרים כלשהם.
זה מבנה דריסה טיפוסי לגרסה דרוסה של handleEvent().
המשימה המיידית היא לקבוע אם אובייקט ה Event שעבר למתודה handleEvent() מתאר אירוע שיש לו איזו שהיא חשיבות לתוכנית.
לדוגמא, ייתכן כי לתוכנית לא יהיה כל עניין באירוע לחיצה באזור טקסט שהוגדר ל 'לקריאה-בלבד' והוא עשוי להיות סתם לחיצה מקרית מצדו של המשתמש.
לפני חזרה למערכת run-time, מתודה זו קוראת ל handleEvent() במחלקה המורישה תוך שימוש במילת המפתח super והעברת אובייקט ה Event פנימה כפרמטר.
זה נעשה כך שכל האירועים שלא מטופלים בגרסה הדרוסה של המתודה, יטופלו (בשיטת ברירת המחדל) על ידי הקוד handleEvent() ברמה גבוהה יותר בהיררכית ההורשה.
למקרה שבו ה id של האירוע תואם ל WINDOW_DESTROY התוכנית שלנו פשוט מסיימת את התוכנית על ידי קריאה ל System.exit(0).
במקרה זה, אין צורך לקרוא למתודה handleEvent() במחלקה המורישה. זה מתרחש כשהמשתמש סוגר את האירוע על ידי לחיצה על לחצן ה x בפינה הימנית העליונה של החלון.
למקרה שבו הid של האירוע תואם ל MOUSE_DOWN אנחנו מעבדים למעשה את האירוע על ידי קריאה למתודה מטפלת-אירועים שאנחנו בנינו.
שים לב שהמטפל באירועים המותאם אישית הוא כל כך קטן שיכלנו באופן הגיוני לכתוב אותו כקוד במבנה ה- switch .
על כל פנים, כדי לשמור על הסדר, פירקנו אותו כמתודה נפרדת המכונה myMousDwnEvntHandler(int x, int y).
כשקראנו למתודה הזו הוצאנו את ערכי ה x וה y מאובייקט ה Eventוהעברנו אותם פנימה כפרמטרים.
{ (public boolean handleEvent(Event evntObj ;break end swith//{ |
מתודה המטפלת באירועים ומותאמת אישית
כעת אנו הולכים לדון במטפל אירועים המותאם אישית המכונהmyMousDwnEvntHandler() .
עד לשלב זה, הצלחנו להימנע מלעסוק בסוגיות רבות של קוד ה-GUI.
עם זאת, אנו עומדים להיתקל בכמה מהן ונצטרך להסביר אותן בקצרה:
כשאתה מתכנת במצב GUI בג'אווה, כל הקלט למסך הוא בצורה של bit-map , לעיתים קרובות מתייחסים להצבה שלbit-maps אלה על המסך כצביעה של המסך.
למען האמת, קיימת מתודה הנקראת paint() השייכת למחלקה Component שבה אפשר להשתמש בכדי לשלוט על האופן בו ימוקם החומר שלנו על המסך.
למעשה, אנחנו אף פעם לא קוראים למתודה paint(). במקום זה, אנחנו קוראים למתודה repaint().
כשאנו דורסים את paint() וקוראים ל repaint() , זה גורם להפעלתה של גרסת ה paint() הדרוסה שלנו. כשהיא מופעלת, אובייקט מסוג Graphics מועבר פנימה כפרמטר.
האובייקט הוא למעשה הייצוג הגרפי של המסך בתוך החלון שלנו. זה נותן לנו גישה למסך במצב גרפיקה ואנו יכולים לשים כל מה שאנחנו רוצים לראות על המסך בנקודה זו.
כפי שאולי תשער, המחלקה Graphics מספקת מספר מתודות שימושיות להם אפשר לקרוא על מנת להציב את החומר שלנו על המסך.
אם כך, המטפל באירועים המותאם אישית שלנו:
· שומר את ערכי הקואורדינטות x ו- y
· מחבר הודעה המכילה את ערכי ה-x וה- y
· מבצע קריאה ל ()repaint כך שאת העבודה האמיתית של צביעת מידע על המסך ניתן לבצע
בגרסתpaint() הדרוסה שלנו.
public void myMousDwnEvntHandler(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 }//end myMousDwnEvntHandler() |
paint() דריסת המתודה
כעת אנו עומדים לדון במתודה paint() עצמה. קיימות מספר גרסאות מועמסות ל- repaint() שאחראיות על אותו חלק של המסך שייצבע מחדש.
צביעת המסך היא תהליך יקר למדי. לפיכך, במקרים מסוימים בהם אנו יודעים שרק חלק קטן של המסך השתנה, באפשרותנו להימנע מצביעת המסך במלואו. במקרה שלנו, לא ניסינו בשום דרך לבצע מיטוב (to optimize) .
פשוט קראנו לגרסה זו של repaint() שתפעיל את המתודה paint() על אזור המסך המלא בתוך המסגרת שלנו.
כפי שניתן לראות בקוד שלהלן, המתודה paint() הדרוסה שלנו היא פשוטה למדי.
אנו פשוט מפעילים את אחת המתודות של המחלקה Graphics הנקראת drawString() כדי שהמידע הקשור בקואורדינטות שלנו "ישורטט" על המסך במיקום המוגדר על ידי ערכי ה-x וה- y של מצביע העכבר.
public void paint(Graphics g){
g.drawString(msg, clickX, clickY);
}//end paint()