Τα περισσότερα προγράμματα, για να είναι χρήσιμα, πρέπει να ανταποκρίνονται σε εντολές του χρήστη. Για να γίνει αυτό, τα προγράμματα Java βασίζονται σε συμβάντα που περιγράφουν τις ενέργειες των χρηστών.
Τον περασμένο μήνα έδειξα πώς να συγκεντρώσω μια γραφική διεπαφή χρήστη από στοιχεία που παρέχονται από το αφηρημένο παράθυρο εργαλείων της βιβλιοθήκης κλάσης Java. Μετά τη συναρμολόγηση μερικών τέτοιων διεπαφών, μίλησα εν συντομία για το θέμα του χειρισμού συμβάντων, αλλά σταμάτησα μια πλήρη περιγραφή του χειρισμού συμβάντων όπως εφαρμόστηκε από το AWT. Αυτόν τον μήνα, παίρνουμε από εκεί που σταματήσαμε.
Να καθοδηγείται από εκδηλώσεις
Στο μακρινό παρελθόν, ένα πρόγραμμα που ήθελε να μάθει τι έκανε ο χρήστης έπρεπε να συλλέξει ενεργά αυτές τις πληροφορίες. Στην πράξη, αυτό σήμαινε ότι αφού ένα πρόγραμμα αρχικοποιήθηκε, μπήκε σε έναν μεγάλο βρόχο στον οποίο φαινόταν επανειλημμένα να δει αν ο χρήστης έκανε κάτι ενδιαφέρον (για παράδειγμα, πατώντας ένα κουμπί, αγγίζοντας ένα πλήκτρο, μετακινώντας ένα ρυθμιστικό, μετακινώντας το ποντίκι) και στη συνέχεια έλαβε την κατάλληλη ενέργεια. Αυτή η τεχνική είναι γνωστή ως σφυγμομέτρηση.
Η ψηφοφορία ολοκληρώνει τη δουλειά, αλλά τείνει να είναι δυσκίνητη όταν χρησιμοποιείται σε σύγχρονες εφαρμογές για δύο σχετικούς λόγους: Πρώτον, η χρήση της ψηφοφορίας τείνει να ωθεί όλο τον κώδικα χειρισμού συμβάντων σε μία τοποθεσία (μέσα στον μεγάλο βρόχο). Δεύτερον, οι προκύπτουσες αλληλεπιδράσεις στο μεγάλο βρόχο τείνουν να είναι περίπλοκες. Επιπλέον, η ψηφοφορία απαιτεί ένα πρόγραμμα να παραμείνει βρόχος, να καταναλώνει κύκλους CPU, ενώ περιμένει τον χρήστη να κάνει κάτι - μια σοβαρή σπατάλη ενός πολύτιμου πόρου.
Το AWT έλυσε αυτά τα προβλήματα αγκαλιάζοντας ένα διαφορετικό παράδειγμα, ένα που βασίζεται σε όλα τα σύγχρονα συστήματα παραθύρων: προγραμματισμός βάσει εκδηλώσεων. Μέσα στο AWT, όλες οι ενέργειες των χρηστών ανήκουν σε ένα αφηρημένο σύνολο πραγμάτων που ονομάζονται εκδηλώσεις. Ένα συμβάν περιγράφει, με αρκετή λεπτομέρεια, μια συγκεκριμένη ενέργεια χρήστη. Αντί για το πρόγραμμα να συλλέγει ενεργά συμβάντα που δημιουργούνται από τον χρήστη, ο χρόνος εκτέλεσης Java ειδοποιεί το πρόγραμμα όταν συμβαίνει ένα ενδιαφέρον γεγονός. Λέγεται ότι είναι προγράμματα που χειρίζονται την αλληλεπίδραση των χρηστών με αυτόν τον τρόπο με γνώμονα το συμβάν.
Η τάξη των εκδηλώσεων
Το μάθημα Event είναι ο πρωταρχικός παίκτης στο παιχνίδι του event. Προσπαθεί να συλλάβει τα θεμελιώδη χαρακτηριστικά όλων των συμβάντων που δημιουργούνται από τον χρήστη. Τραπέζι 1 παραθέτει τα δημόσια μέλη δεδομένων που παρέχονται από την κατηγορία Event.
Τύπος | Ονομα | Περιγραφή |
Αντικείμενο | στόχος | Μια αναφορά στο στοιχείο που έλαβε αρχικά το συμβάν. |
μακρύς | πότε | Το χρονικό σημείο στο οποίο συνέβη το συμβάν. |
int | ταυτότητα | Ο τύπος συμβάντος (ανατρέξτε στην ενότητα Τύποι συμβάντων για περισσότερες πληροφορίες). |
int | Χ | Η συντεταγμένη x στην οποία πραγματοποιήθηκε η ενέργεια σε σχέση με το στοιχείο που επεξεργάζεται το συμβάν. Για ένα δεδομένο συμβάν, η συντεταγμένη x θα αλλάξει σε αξία καθώς το συμβάν ανεβαίνει την ιεραρχία των στοιχείων. Η προέλευση του επιπέδου συντεταγμένων βρίσκεται στην επάνω αριστερή γωνία του εξαρτήματος. |
int | γ | Η συντεταγμένη y στην οποία πραγματοποιήθηκε η ενέργεια σε σχέση με το στοιχείο που επεξεργάζεται το συμβάν. Για ένα δεδομένο συμβάν, η συντεταγμένη y θα αλλάξει σε αξία καθώς το συμβάν ανεβαίνει την ιεραρχία στοιχείων. Η προέλευση του επιπέδου συντεταγμένων βρίσκεται στην επάνω αριστερή γωνία του εξαρτήματος. |
int | κλειδί | Για συμβάντα πληκτρολογίου, μόλις πατήσατε ο κωδικός του πλήκτρου. Η τιμή του θα είναι συνήθως η τιμή Unicode του χαρακτήρα που αντιπροσωπεύει το κλειδί. Άλλες δυνατότητες περιλαμβάνουν τιμές για τα ειδικά πλήκτρα HOME, END, F1, F2 και ούτω καθεξής. |
int | τροποποιητές | Ένας αριθμητικός ή επιθυμητός συνδυασμός των τιμών SHIFT_MASK, CTRL_MASK, META_MASK και ALT_MASK. Η τιμή του αντιπροσωπεύει την κατάσταση των πλήκτρων shift, control, meta και alt, αντίστοιχα. |
int | κλικCount | Ο αριθμός των διαδοχικών κλικ του ποντικιού. Αυτό το μέλος δεδομένων είναι σημαντικό μόνο σε MOUSE_DOWN συμβάντα. |
Αντικείμενο | υποστηρίζει | Ένα επιχείρημα που εξαρτάται από το συμβάν. Για αντικείμενα κουμπιών, αυτό το αντικείμενο είναι ένα αντικείμενο συμβολοσειράς που περιέχει την ετικέτα υφής του κουμπιού. |
Όπως θα εξηγήσω στην ενότητα με τίτλο Αποστολή και διάδοση εκδηλώσεων, μια παρουσία συμβάντος κλάσης δημιουργείται συνήθως από το σύστημα χρόνου εκτέλεσης Java. Ωστόσο, είναι δυνατό για ένα πρόγραμμα να δημιουργήσει και να στείλει συμβάντα σε στοιχεία μέσω αυτών postEvent ()
μέθοδος.
Τύποι συμβάντων
Όπως αναφέρθηκε παραπάνω, η κλάση συμβάντων είναι ένα μοντέλο ενός συμβάντος διεπαφής χρήστη. Τα γεγονότα εμπίπτουν φυσικά σε κατηγορίες με βάση τον τύπο του συμβάντος (ο τύπος συμβάντος υποδεικνύεται από το ταυτότητα
μέλος δεδομένων). Ο Πίνακας 2 παραθέτει όλα τα συμβάντα που ορίζονται από το AWT, ταξινομημένα κατά κατηγορία.
Μπορεί να είναι διδακτικό να δούμε τη δημιουργία εκδηλώσεων σε δράση. Το κουμπί στο σχήμα 1, όταν πατηθεί, δημιουργεί ένα πρόγραμμα περιήγησης συμβάντων που εμφανίζει πληροφορίες συμβάντων σχετικά με τα συμβάντα που λαμβάνει το πρόγραμμα περιήγησης. Ο πηγαίος κώδικας για το πρόγραμμα περιήγησης είναι διαθέσιμος εδώ.
Χρειάζεστε ένα πρόγραμμα περιήγησης με δυνατότητα Java για να δείτε αυτό το appletΣχήμα 1: Δημιουργία γεγονότων σε δράση
Αποστολή και διάδοση εκδηλώσεων
Εξετάστε το applet στο Σχήμα 2. Αποτελείται από δύο παρουσίες της κλάσης Button, ενσωματωμένες σε μια παρουσία της κλάσης Panel. Αυτή η παρουσία της κλάσης Panel ενσωματώνεται σε μια άλλη παρουσία της κλάσης Panel. Η τελευταία εμφάνιση της κλάσης Panel βρίσκεται κάτω από μια παρουσία της κλάσης TextArea και και οι δύο παρουσίες ενσωματώνονται σε μια παρουσία της κλάσης Applet. Το Σχήμα 3 παρουσιάζει τα στοιχεία που απαρτίζουν αυτήν τη μικροεφαρμογή που ορίζεται ως δέντρο, με τις παρουσίες TextArea και Button ως φύλλα, και μια παρουσία Applet ως τη ρίζα. (Για περισσότερες πληροφορίες σχετικά με την ιεραρχική διάταξη των στοιχείων σε μια διεπαφή χρήστη, διαβάστε την εισαγωγή του AWT τον περασμένο μήνα.)
Χρειάζεστε ένα πρόγραμμα περιήγησης με δυνατότητα Java για να δείτε αυτό το appletΣχήμα 2: Μαθήματα ενσωματωμένες σε τάξεις
Σχήμα 3: Δέντρο στοιχείων Applet (ιεραρχία)
Όταν ένας χρήστης αλληλεπιδρά με το applet στο Σχήμα 2, το σύστημα χρόνου εκτέλεσης Java δημιουργεί μια παρουσία συμβάντος κλάσης και συμπληρώνει τα μέλη δεδομένων του με πληροφορίες που περιγράφουν τη δράση. Στη συνέχεια, το σύστημα Java χρόνου εκτέλεσης επιτρέπει στη μικροεφαρμογή να χειριστεί το συμβάν. Ξεκινά με το στοιχείο που έλαβε αρχικά το συμβάν (για παράδειγμα, το κουμπί στο οποίο έγινε κλικ) και ανεβαίνει προς τα επάνω το δέντρο συστατικών, το συστατικό με το συστατικό, μέχρι να φτάσει στο κοντέινερ στην κορυφή του δέντρου. Στην πορεία, κάθε στοιχείο έχει την ευκαιρία να αγνοήσει το συμβάν ή να αντιδράσει σε αυτόν με έναν (ή περισσότερους) από τους ακόλουθους τρόπους:
- Τροποποιήστε τα μέλη δεδομένων της παρουσίας συμβάντος
- Αναλάβετε δράση και εκτελέστε κάποιον υπολογισμό βάσει των πληροφοριών που περιέχονται στην εκδήλωση
- Υποδείξτε στο σύστημα χρόνου εκτέλεσης Java ότι το συμβάν δεν θα πρέπει να διαδοθεί περισσότερο στο δέντρο
Το σύστημα εκτέλεσης Java μεταβιβάζει πληροφορίες συμβάντος σε ένα στοιχείο μέσω του στοιχείου handleEvent ()
μέθοδος. Όλα ισχύουν handleEvent ()
οι μέθοδοι πρέπει να έχουν τη μορφή
δημόσια boolean handleEvent (Event e)
Ένας χειριστής συμβάντων απαιτεί ένα μόνο κομμάτι πληροφοριών: μια αναφορά στην παρουσία της κλάσης συμβάντων που περιέχει πληροφορίες σχετικά με το συμβάν που μόλις συνέβη.
Η τιμή επέστρεψε από το handleEvent ()
η μέθοδος είναι σημαντική. Υποδεικνύει στο σύστημα χρόνου εκτέλεσης Java εάν το συμβάν έχει χειριστεί πλήρως ή όχι στο πρόγραμμα χειρισμού συμβάντων. Μια πραγματική τιμή δείχνει ότι το συμβάν έχει αντιμετωπιστεί και η διάδοση πρέπει να σταματήσει. Μια λανθασμένη τιμή υποδεικνύει ότι το συμβάν έχει αγνοηθεί, δεν μπορεί να αντιμετωπιστεί ή ότι έχει αντιμετωπιστεί ατελή και πρέπει να συνεχίσει το δέντρο.
Εξετάστε την ακόλουθη περιγραφή της αλληλεπίδρασης ενός φανταστικού χρήστη με το applet στο Σχήμα 2. Ο χρήστης κάνει κλικ στο κουμπί με την ένδειξη "Ένα". Το σύστημα χρόνου εκτέλεσης της γλώσσας Java συγκεντρώνει πληροφορίες σχετικά με το συμβάν (τον αριθμό των κλικ, τη θέση του κλικ, τη στιγμή που έγινε το κλικ και το στοιχείο που έλαβε το κλικ) και συσκευάζει αυτές τις πληροφορίες σε μια παρουσία της κλάσης συμβάντων. Στη συνέχεια, το σύστημα Java χρόνου εκτέλεσης ξεκινά από το στοιχείο στο οποίο έγινε κλικ (σε αυτήν την περίπτωση, το κουμπί με την ένδειξη "Ένα") και, μέσω κλήσης προς το στοιχείο handleEvent ()
μέθοδος, προσφέρει στο συστατικό την ευκαιρία να αντιδράσει στο συμβάν. Εάν το στοιχείο δεν χειρίζεται το συμβάν ή δεν χειρίζεται πλήρως το συμβάν (υποδεικνύεται από τιμή επιστροφής false), το σύστημα χρόνου εκτέλεσης Java προσφέρει την παρουσία συμβάντος στο επόμενο υψηλότερο στοιχείο στο δέντρο - σε αυτήν την περίπτωση μια παρουσία του Κατηγορία πίνακα. Το σύστημα χρόνου εκτέλεσης Java συνεχίζεται με αυτόν τον τρόπο μέχρι να αντιμετωπιστεί το συμβάν ή το σύστημα χρόνου εκτέλεσης να εξαντληθεί για να δοκιμάσετε. Το σχήμα 4 απεικονίζει τη διαδρομή αυτού του συμβάντος καθώς η μικροεφαρμογή προσπαθεί να το χειριστεί.
Εικόνα 4: Η διαδρομή ενός συμβάντος
Κάθε συστατικό που αποτελεί το applet στο Σχήμα 2 προσθέτει μια γραμμή στο αντικείμενο TextArea που δείχνει ότι έλαβε ένα συμβάν. Στη συνέχεια επιτρέπει στο συμβάν να εξαπλωθεί στο επόμενο στοιχείο του δέντρου. Η λίστα 1 περιέχει τον κωδικό για ένα τυπικό handleEvent ()
μέθοδος. Ο πλήρης πηγαίος κώδικας για αυτό το applet είναι διαθέσιμος εδώ.
δημόσιο boolean handleEvent (Event evt) {if (evt.id == Event.ACTION_EVENT) {ta.appendText ("Panel" + str + "saw action ... \ n"); } αλλιώς εάν (evt.id == Event.MOUSE_DOWN) {ta.appendText ("Panel" + str + "είδε το ποντίκι προς τα κάτω ... \ n"); }
επιστροφή super.handleEvent (evt); }
Λίστα 1: Ένα τυπικό handleEvent ()
μέθοδος
Μέθοδοι βοηθού συμβάντων
ο handleEvent ()
Η μέθοδος είναι ένα μέρος που ένας προγραμματιστής μπορεί να βάλει τον κωδικό εφαρμογής για το χειρισμό συμβάντων. Περιστασιακά, ωστόσο, ένα στοιχείο θα ενδιαφέρεται μόνο για γεγονότα ενός συγκεκριμένου τύπου (για παράδειγμα, συμβάντα ποντικιού). Σε αυτές τις περιπτώσεις, ο προγραμματιστής μπορεί να τοποθετήσει τον κωδικό σε ένα βοηθητική μέθοδος, αντί να το τοποθετήσετε στο handleEvent ()
μέθοδος.
Ακολουθεί μια λίστα με τις βοηθητικές μεθόδους που διατίθενται στους προγραμματιστές. Δεν υπάρχουν βοηθητικές μέθοδοι για συγκεκριμένους τύπους εκδηλώσεων.
δράση (Event evt, Object what)
gotFocus (Event evt, Object what)
lostFocus (Event evt, Object what)
mouseEnter (Εκδήλωση evt, int x, int y)
mouseExit (Εκδήλωση evt, int x, int y)
mouseMove (Εκδήλωση evt, int x, int y)
mouseUp (Εκδήλωση evt, int x, int y)
mouseDown (Event evt, int x, int y)
mouseDrag (Event evt, int x, int y)
keyDown (Event evt, int key)
keyUp (Event evt, int key)
false για να δείξει ότι η μέθοδος βοηθού δεν αντιμετώπισε το συμβάν.
Η εφαρμογή του handleEvent ()
μέθοδος που παρέχεται από την κλάση Component επικαλείται κάθε βοηθητική μέθοδο. Για το λόγο αυτό, είναι σημαντικό οι επαναπροσδιορισμένες εφαρμογές του handleEvent ()
μέθοδος σε παράγωγες τάξεις τελειώνει πάντα με τη δήλωση
επιστροφή super.handleEvent (e);
Ο κωδικός στην Λίστα 2 απεικονίζει αυτόν τον κανόνα.
public boolean handleEvent (Event e) {if (e.target instanceof MyButton) {// κάνε κάτι ... επιστρέψτε αληθινό; }
επιστροφή super.handleEvent (e); }
Λίστα 2: Κανόνας για τον τερματισμό της δήλωσης σε handleEvent ()
μέθοδος
Η μη τήρηση αυτού του απλού κανόνα θα αποτρέψει την ορθή επίκληση μεθόδων βοηθού.
Το σχήμα 5 περιέχει μια μικροεφαρμογή που χειρίζεται τα γεγονότα του ποντικιού αποκλειστικά μέσω κώδικα που τοποθετείται σε βοηθητικές μεθόδους. Ο πηγαίος κώδικας είναι διαθέσιμος εδώ.
Εκδήλωση | κτλ | Το επόμενο συμβάν σε μια συνδεδεμένη λίστα συμβάντων. |
Εκδηλώσεις παραθύρων | ||
Τα συμβάντα παραθύρου δημιουργούνται ως απάντηση σε αλλαγές στην κατάσταση ενός παραθύρου, πλαισίου ή διαλόγου. | ||
Εκδήλωση | ταυτότητα | |
WINDOW_DESTROY | 201 | |
WINDOW_EXPOSE | 202 | |
WINDOW_ICONIFY | 203 | |
WINDOW_DEICONIFY | 204 | |
WINDOW_MOVED | 205 | |
Συμβάντα πληκτρολογίου | ||
Τα συμβάντα πληκτρολογίου δημιουργούνται ως απάντηση στα πλήκτρα που πιέζονται και απελευθερώνονται ενώ ένα στοιχείο έχει εστίαση εισόδου. | ||
Εκδήλωση | ταυτότητα | |
KEY_PRESS | 401 | |
KEY_RELEASE | 402 | |
KEY_ACTION | 403 | |
KEY_ACTION_RELEASE | 404 | |
Εκδηλώσεις ποντικιού | ||
Τα συμβάντα του ποντικιού δημιουργούνται ως απόκριση στις ενέργειες του ποντικιού που συμβαίνουν εντός των ορίων ενός στοιχείου. | ||
Εκδήλωση | ταυτότητα | |
ΜΟΥΣΕΙΟ_ ΚΑΤΩ | 501 | |
MOUSE_UP | 502 | |
MOUSE_MOVE | 503 | |
MOUSE_ENTER | 504 | |
MOUSE_EXIT | 505 | |
MOUSE_DRAG | 506 | |
Κύλιση συμβάντων | ||
Τα γεγονότα κύλισης δημιουργούνται ως απάντηση στο χειρισμό των γραμμών κύλισης. | ||
Εκδήλωση | ταυτότητα | |
SCROLL_LINE_UP | 601 | |
SCROLL_LINE_DOWN | 602 | |
SCROLL_PAGE_UP | 603 | |
SCROLL_PAGE_DOWN | 604 | |
SCROLL_ABSOLUTE | 605 | |
Λίστα συμβάντων | ||
Τα συμβάντα λίστας δημιουργούνται ως απάντηση στις επιλογές που γίνονται σε μια λίστα. | ||
Εκδήλωση | ταυτότητα | |
LIST_SELECT | 701 | |
LIST_DESELECT | 702 | |
Διάφορα γεγονότα | ||
Διάφορα γεγονότα δημιουργούνται ως απάντηση σε μια ποικιλία ενεργειών. | ||
Εκδήλωση | ταυτότητα | |
ACTION_EVENT | 1001 | |
LOAD_FILE | 1002 | |
ΑΠΟΘΗΚΕΥΣΕΤΕ ΤΟ ΑΡΧΕΙΟ | 1003 | |
GOT_FOCUS | 1004 | |
LOST_FOCUS | 1005 |
Μάθετε περισσότερα σχετικά με αυτό το θέμα
- Το Java Tutorial των Mary Campione και Kathy Walrath. Η ηλεκτρονική πρόχειρη έκδοση είναι διαθέσιμη στη διεύθυνση //java.sun.com/tutorial/index.html.
Αυτή η ιστορία, "Java και χειρισμός εκδηλώσεων" δημοσιεύθηκε αρχικά από την JavaWorld.