Προγραμματισμός

Διαχείριση Java και συμβάντων

Τα περισσότερα προγράμματα, για να είναι χρήσιμα, πρέπει να ανταποκρίνονται σε εντολές του χρήστη. Για να γίνει αυτό, τα προγράμματα 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 συμβάντα.
ΑντικείμενουποστηρίζειΈνα επιχείρημα που εξαρτάται από το συμβάν. Για αντικείμενα κουμπιών, αυτό το αντικείμενο είναι ένα αντικείμενο συμβολοσειράς που περιέχει την ετικέτα υφής του κουμπιού.
Πίνακας 1: Δημόσια μέλη δεδομένων που παρέχονται από την κατηγορία Event

Όπως θα εξηγήσω στην ενότητα με τίτλο Αποστολή και διάδοση εκδηλώσεων, μια παρουσία συμβάντος κλάσης δημιουργείται συνήθως από το σύστημα χρόνου εκτέλεσης Java. Ωστόσο, είναι δυνατό για ένα πρόγραμμα να δημιουργήσει και να στείλει συμβάντα σε στοιχεία μέσω αυτών postEvent () μέθοδος.

Τύποι συμβάντων

Όπως αναφέρθηκε παραπάνω, η κλάση συμβάντων είναι ένα μοντέλο ενός συμβάντος διεπαφής χρήστη. Τα γεγονότα εμπίπτουν φυσικά σε κατηγορίες με βάση τον τύπο του συμβάντος (ο τύπος συμβάντος υποδεικνύεται από το ταυτότητα μέλος δεδομένων). Ο Πίνακας 2 παραθέτει όλα τα συμβάντα που ορίζονται από το AWT, ταξινομημένα κατά κατηγορία.

Πίνακας 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_DESTROY201
WINDOW_EXPOSE202
WINDOW_ICONIFY203
WINDOW_DEICONIFY204
WINDOW_MOVED205
Συμβάντα πληκτρολογίου
Τα συμβάντα πληκτρολογίου δημιουργούνται ως απάντηση στα πλήκτρα που πιέζονται και απελευθερώνονται ενώ ένα στοιχείο έχει εστίαση εισόδου.
Εκδήλωσηταυτότητα
KEY_PRESS401
KEY_RELEASE402
KEY_ACTION403
KEY_ACTION_RELEASE404
Εκδηλώσεις ποντικιού
Τα συμβάντα του ποντικιού δημιουργούνται ως απόκριση στις ενέργειες του ποντικιού που συμβαίνουν εντός των ορίων ενός στοιχείου.
Εκδήλωσηταυτότητα
ΜΟΥΣΕΙΟ_ ΚΑΤΩ501
MOUSE_UP502
MOUSE_MOVE503
MOUSE_ENTER504
MOUSE_EXIT505
MOUSE_DRAG506
Κύλιση συμβάντων
Τα γεγονότα κύλισης δημιουργούνται ως απάντηση στο χειρισμό των γραμμών κύλισης.
Εκδήλωσηταυτότητα
SCROLL_LINE_UP601
SCROLL_LINE_DOWN602
SCROLL_PAGE_UP603
SCROLL_PAGE_DOWN604
SCROLL_ABSOLUTE605
Λίστα συμβάντων
Τα συμβάντα λίστας δημιουργούνται ως απάντηση στις επιλογές που γίνονται σε μια λίστα.
Εκδήλωσηταυτότητα
LIST_SELECT701
LIST_DESELECT702
Διάφορα γεγονότα
Διάφορα γεγονότα δημιουργούνται ως απάντηση σε μια ποικιλία ενεργειών.
Εκδήλωσηταυτότητα
ACTION_EVENT1001
LOAD_FILE1002
ΑΠΟΘΗΚΕΥΣΕΤΕ ΤΟ ΑΡΧΕΙΟ1003
GOT_FOCUS1004
LOST_FOCUS1005
Ο Todd Sundsted προγραμματίζει από τότε που οι υπολογιστές έγιναν διαθέσιμοι σε μοντέλα επιτραπέζιων υπολογιστών. Αν και αρχικά ενδιαφερόταν να δημιουργήσει κατανεμημένες εφαρμογές αντικειμένων στο C ++, ο Todd μετακόμισε στη γλώσσα προγραμματισμού Java όταν η Java έγινε μια προφανής επιλογή για κάτι τέτοιο. Εκτός από τη γραφή, ο Todd παρέχει συμβουλευτικές υπηρεσίες διαδικτύου και εφαρμογών Ιστού σε εταιρείες στις νοτιοανατολικές Ηνωμένες Πολιτείες.

Μάθετε περισσότερα σχετικά με αυτό το θέμα

  • Το Java Tutorial των Mary Campione και Kathy Walrath. Η ηλεκτρονική πρόχειρη έκδοση είναι διαθέσιμη στη διεύθυνση //java.sun.com/tutorial/index.html.

Αυτή η ιστορία, "Java και χειρισμός εκδηλώσεων" δημοσιεύθηκε αρχικά από την JavaWorld.