» נושאי לימוד
» נושאי לימוד
יום שני 29 באפריל 2024
היררכית הטיפול האירועים ופונקצית ה-()postEvent
דף ראשי  מתקדמים  היררכית הטיפול האירועים ופונקצית ה-()postEvent גרסה להדפסה
 

 

היררכית הטיפול האירועים ופונקצית ה-()postEvent

 

 

 ·  מבוא

 ·  תיאור מדויק יותר של התהליך

 ·  פונקציות ה- ()postEvent  וה- deliverEvent()

 ·  דוגמא של תוכנית היררכיה


 

מבוא

 

תכנות Java, סיכומי הרצאה 70#, מעודכן 8/3/97.

 

גרסת בטא של JDK 1.1  זמינה כרגע לבדיקה, ו Sun הכריזו כי היא תכלול שינויים חשובים ל – Abstract Windows Toolkit, כולל שינויים ליישום אירועים וטיפול אירועים.

 

כאשר JDK 1.1 ישוחרר ומידע קונקרטי לגבי שינויים אלה יהיה זמין, שיעור זה יושלם על ידי שיעור חדש אשר יתאר את האירועים וטיפול אירועים תחת JDK 1.1.

 

ייתכן וקיים אצלך בלבול הקשור לדיונים הקודמים אודות העברת אירועים במעלה היררכית המכל. אם כן, ננסה לסדר בלבול זה במהלך השיעור הזה.

 

בשיעור קודם, הגדרנו איך פעולות משתמש הכוללות רכיבי GUI הומרו להודעות על ידי מערכת ההפעלה, ואיך הודעות אלה נשלחו למערכת זמן ההרצה של Java.

 

אמרנו שכאשר זה מתרחש, מערכת זמן ההרצה של Java

-    סוגרת בתוכה מידע המתאר אירוע משתמש זה לתוך אובייקט ממחלקת Event,

-    קוראת לפונקצית ה-()handleEvent  של רכיב ה- GUI המעורב באירוע המשתמש

-   ומעבירה את אובייקט ה- Event כפרמטר אל פונקצית ה- handleEvent().

 

ציינו לאורך הדרך שזהו פישוט יתר המתעלם ממעורבות פונקציה אחרת בשם postEvent().

 

 

בשיעור זה, נתאר איך פונקצית ה- postEvent() משתלבת
ואיך היא מתקשרת לפונקצית ה-
handleEvent().
בנוסף נתאר איך הפונקציה מתקשרת לפונקצית
deliverEvent().

 

הסברנו כי אם פונקצית handleEvent() מחזירה שקר, האירוע עובר למכל הבא בהיררכית המכלים.

 

בשיעור זה, נכתוב תוכנה אשר מרכיבה היררכית מכלים שכזו ונוכל לצפות באירוע עובר במעלה ההיררכיה בזמן ביצוע התוכנה.

 

בנוסף הסברנו שאם handleEvent() חוזר אמת, האירוע ייעצר ברמה זו ולא יועבר למכל הבא בהיררכיה.

 

תהליך העברת האירועים ממשיכה עד שפונקצית handleEvent() ברמה מסוימת מחזירה אמת, או שאין יותר מכלים אליהם ניתן להעביר.

 

 

תיאור מדויק יותר של התהליך

 

לפי Exploring Java  של Patrick Neimeyer ו- Joshua Peck,

- "למעשה, אירועים מועברים תחילה  לפונקצית ה- ()PostMethod של מחלקת ה-Componentהתנהגות ברירת המחדל של postEvent() היא ליישם את התוכנית שתיארתי לעיל.

הוא קורא לפונקצית ה- handleEvent()  של הרכיב, ומעניק לו הזדמנות לקחת את האירוע.

אם הרכיב אינו רוצה את האירוע, זה קורא לאח הגדול שלו, פונקצית ה- postMethod() של מחלקת המכל הסוגר. אם זה נכשל, זה מעביר את האירוע לאובייקט ה-  בסיס.

 

הקוד הבא מייצג תאור של ()postEvent  

public boolean postEvent(Event evt)
     Posts an event to this component by calling its
handleEvent method.
     If handleEvent returns false,
the event is posted to this component's parent.
     If this component and all of its parents return false,
the event is passed to this component's peer
object's handleEvent method.
     Parameters:
           evt - the event
    Returns:
           true if this component,one of its parents,
or this component's peer handled the event;
          false otherwise.
      See Also:
           deliverEvent.

 

המידע שלעיל הציג מונח חדש נוסף: אובייקט בסיס.

 

לפי המילון המונחים ב- Exploring Java,

אובייקט בסיס: היישום הממשי של רכיב GUI ברציף ספציפי."

 

כלומר, מערכת ההרצה למעשה קוראת ל- postEvent() ןלא ישירות ל- handleEvent() ומערכת זמן ההרצה מעבירה את אובייקט ה- Event כפרמטר לפונקצית ה- postEvent().

 

פונקצית ה- postEvent() היא זו שלמעשה מיישמת את התהליך של העברת האירועים במעלה ההיררכיה ממכל אחד לשני.

 

בכל נקודה לאורך הדרך, postEvent() קורא ל- handleEvent() אשר יכול להחזיר אמת או שקר.

 

אם מוחזר אמת בכל אחת מן הרמות, פונקצית ה- postEvent() מחסלת את התהליך. אחרת, היא מעבירה את האירוע עד לפונקצית ה- postEvent() הבא בהיררכית המכלים אשר חוזרת על הפעולה.

 

לבסוף, כאשר אין יותר מכלים ב- postEvent(), האירוע מועבר לחלק אחר של המערכת עבור טיפול מחדל, אם יש צורך בכך.

 

 

פונקציות ה-  postEvent() ו- deliverMethod()

 

נעשה טיול קצר, הכולל גם את פונקצית ה- postMethod().

 

בשיעור מוקדם יותר כאשר יצרנו אירועים מיוצרי- תוכנה, אמרנו שניתן להעביר את האירוע מיוצר-התוכנה למקבל תוך שימוש ב-  deliverEvent()או ב- postEvent(). נסתכל על הסיבה בגללה ניתן להשתמש בכל אחת מן הפונקציות.

 

התיאור הבא של deliverEvent() נלקח מתוך תיעוד API .

 

public void deliverEvent(Event evt)
     Delivers an event to this component
or one of its subcomponents.
      The deliverEvent method of Component
calls the component's
      postEvent method
on the event.
      Parameters:           evt - the event

 

מסתבר, כשמבססים על הכתוב לעיל, deliverEvent() פשוט קורא ל-  postEvent() ומעביר את האירוע כפרמטר. זאת הסיבה שניתן להשתמש בכל אחת מהן. לא מצאתי דבר אשר מראה חסרון לקריאת postEvent() ישירות מהתוכנה שלך, אך כרגיל ייתכן וישנו אחד שמסתתר אפושהוא. אחרת, לא היה צורך בקיום ה- deliverEvent() מלכתחילה. 

 

 

דוגמא לתוכנית היררכיה

 

מאוחר יותר כשנלמד על יצירת ממשקים של משתמשים גרפיים, נלמד שעל מנת להשיג את העריכה, המראה וההתנהגות הרצויים, לעיתים קרובות יש צורך לבצע תת-חלוקה של ממשק כולל למכלים נפרדים, כאשר כל אחד מהם מכיל מרכיבים או מכלים אחרים.

 

התוכנה הבאה לא נועדה להדגים עיצוב ממשק יעיל. אך עם זאת, היא נועדה להדגים את התהליך בעזרתו ניתן להקים היררכיות מכלים. זה מוביל באופן טבעי לחקר אירועים המופצים במעלה היררכית המיכלים.

 

לא אספק הרבה דיון כתוב על תוכנה זו מלבד הדיון בהערות בתחילת התוכנה, מכיוון שאין כאן הרבה דברים חדשים.

 

נשתמש במונח חדש: פנל. (Panel).ב- Java, פנל זוהי מחלקה בחבילת java.awt בה ניתן להשתמש על מנת לאתחל מיידית אובייקטים מסוג  מכל.

 

לא ניתן לראות פנל. זהו פשוט מקום לשים בו רכיבים אחרים בסדר רצוי כלשהו.

 

לפנל ורכיביו, עם סידורם הספציפי, ניתן להתייחס כאל אובייקט יחיד אשר ניתן למקם יחד עם עוד אובייקטים כאלה בתוך מכל אחר.

 

כך נבנית היררכית המכלים.

 

הסתכל על התוכנה הבאה. למרות שהיא ארוכה דיה. היא חוזרת על עצמה.

 

אם תלקט, תערוך ותריץ תוכנה זו, תראה עמודות של אובייקטים המכילים שלושה אובייקטים של TextField ואובייקט אחד של Button. הכפתור הוא בתחתית, ואובייקט ה- TextField ברמה העלינה נמצא בחלק העליון.

אם תלחץ על אובייקט Button, אתה אמור לראות את הטקסט בכל אחד מאובייקטים של TextField משתנה, עם עיכוב של שנייה אחת בין השינויים באובייקטים של ה- TextField, מלמטה למעלה. זוהי סימולציה של אובייקט Event המופץ במעלה היררכית מכלים.

 

בנקודה זו, אין צורך לדאוג לקוד מנהל תצוגה בו נאלצתי להשתמש. מספיק לציין שיש מנהל תצוגה העוזר לך בסידור הרכיבים במכל.

 

ישנם מספר סגנונות  שונים של מנהלי תצוגה. כאן יש שימוש במנהל תרשים גבולות. במנהל התצוגה ניתן להשתמש על מנת לשים עד חמישה אובייקטים במכל: אחד במרכז, וארבעת האחרים בעמדות צפון, דרום, מזרח ומערב.

 

דבר שכן דורש את תשומת לבך המיוחד הוא איך המכל ורכיביו מאותחלים לתוך אובייקט אשר הופך להיות אחד הרכיבים במכל בדרגה הגבוהה הבאה.

/*File Event04.java Copyright 1997, R.G.Baldwin
Illustrates the propagation of an event up through the
GUI object hierarchy, from container to container,
to container, etc.
A Frame is created at the top level which contains
a TextField and a Panel.
The Panel in the frame contains a TextField and another
Panel.
That Panel contains a TextField and a Button.
Thus, the Panelcontaining the TextField and the Button
are at the innermostlevel of the hierarchy.
When the button is clicked, an ACTION_EVENT is generated
on theButton.
The handleEvent() method of the innermost container is used
to put a message in the TextField
The handleEvent() method returns false to cause the event
to propagate up to the nextcontainer in the hierarchy.
Because the method returns false, the system
passes the event tothe handleEvent() method in the
next container up the line
That method puts a message in its TextField and returns
false as well.Again, because the handleEvent() method
returns false, the event is then passed up to the next level
which is the top level container.
The handleEvent() method in the top-level container puts
a message in its TextField, invokes super.handleEvent(),
and exits.In summary, as the event propagates up through
the hierarchy, the handleEvent() method of the container
at each level displays a message and passes the event along.
Thus, messages are generated at all three levels as the
event is propagated upward.To make it easier to see what
is happening, a one-second delay isimplemented in each event
handler before the new text is actuallydisplayed.
Depending on the resolution of your screen, you may need
to changethe size of the frame to make all three TextFields
visible.
The following code is presented in an innermost to outermost
order.

*/import java.awt.*;
class ThirdLevel extends Panel{
//define class for innermost container 
Button myButton;
//reference variable for Button object
  TextField myTextField;
//reference field for TextField object
  ThirdLevel(){
//constructor
    setLayout(new BorderLayout());
    myButton = new Button("click here");
//instantiate Button object
    add("South",myButton);
    myTextField = new TextField("TextField, Third Level");
//TextField object
    add("North",myTextField);
    resize(preferredSize());
  }//end constructor for ThirdLevel class
    //Event handler for innermost container
  public boolean handleEvent(Event evObj)
{//confirm Button action event
    if( (evObj.id == Event.ACTION_EVENT) &&
         (evObj.target == myButton) )
{      try{Thread.currentThread().sleep(1000);
      }catch(InterruptedException e){}
//do-nothing exception handler
      myTextField.setText("Third Level ACTION_EVENT");
    }//end if
    return false;
//pass the event up to the next container
  }//end handleEvent()
  }//end class
ThirdLevelclass SecondLevel extends Panel{
//class for middle-level container, panel
  ThirdLevel myThird;
  TextField myTextField;
    SecondLevel(){//constructor
    setLayout(new BorderLayout() );
    myThird = new ThirdLevel();
//instantiate innermost container as an object
    add("South",myThird);
    myTextField = new TextField("TextField, Second Level");
    add("North",myTextField);
    resize(preferredSize());
  }//end constructor for SecondLevel class
    public boolean handleEvent(Event evObj){
//Confirm that the event is an action event that originated
         //at the button in the innermost container.

    if( (evObj.id == Event.ACTION_EVENT) &&
         (evObj.target == myThird.myButton) ){
      try{Thread.currentThread().sleep(1000);
      }catch(InterruptedException e){
}//do-nothing exception handler     
myTextField.setText("Second Level ACTION_EVENT");
      }//end if
    return false;
//pass the event on up the line
  }//end handleEvent()
  }//end class SecondLevel
//This is the class for the outermost container which
//is the controlling
// class for the application.
// Make it extend the Frame class to produce
// a window that can accept events.
public class Event04 extends Frame{
  SecondLevel mySecond;
  TextField myTextField;
    Event04(){//constructor
    setLayout(new BorderLayout(1,3));
    mySecond = new SecondLevel();
//Instantiate middle container as object
    add("South",mySecond);
    myTextField = new TextField("TextField, Top Level");
    add("North",myTextField);
    setTitle("Copyright 1997, R. G. Baldwin");
    resize(300,110);
  }//end constructor for Event04 class
    public boolean handleEvent(Event evObj){
    if(evObj.id == Event.WINDOW_DESTROY) System.exit(0);
      //Test to determine if the event is an action
// event generated by
     // the button in the innermost container. 
//Note the use of two    
// dot operators to reference that Button object.
    if( (evObj.id == Event.ACTION_EVENT)&&
         (evObj.target == mySecond.myThird.myButton) ){
      try{Thread.currentThread().sleep(1000);
      }catch(InterruptedException e){
}//do-nothing exception handler
      myTextField.setText("Top Level ACTION_EVENT"); 
   }//end if
    return super.handleEvent(evObj);
          }//end handleEvent()
  public static void main(String[] args){
    Event04 obj = new Event04();
//instantiate an object
    obj.show();
//and display it
  }//end main}
//end class Event04
 

 

 

זהו המפתח להיררכית מכלים של GUI  בה דנו בשיעורים אחדים.

 

 

-סוף-

 

 29-11-03 / 19:34  עודכן ,  13-10-03 / 17:10  נוצר ע"י רונית רייכמן  בתאריך 
 תוכנית הדגמה - הקודםהבא - טיפול באירועים ב-JDK 1.0.2, רכיבים חכמים 
תגובות הקוראים    תגובות  -  0
דרכונט
מהי מערכת הדרכונט?
אינך מחובר, להתחברות:
דוא"ל
ססמא
נושאי לימוד
חיפוש  |  לא פועל
משלנו  |  לא פועל
גולשים מקוונים: 5