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

Οικοδόμηση μιας σειράς φασολιών: Δημιουργήστε επαναχρησιμοποιήσιμα στοιχεία JavaBeans

Σε αυτήν τη σύντομη σειρά, εξετάζουμε την ανάπτυξη στοιχείων λογισμικού JavaBeans. Τελικά, τα περισσότερα φασόλια θα υποστούν χειρισμό σε ένα περιβάλλον ανάπτυξης φασολιών. Ωστόσο, εδώ ασχολούμαστε μόνο με τις πτυχές σε επίπεδο πηγής του πλαισίου. Τα πλεονεκτήματα της ανάπτυξης JavaBeans - δηλαδή, σύμφωνα με τις προδιαγραφές JavaBeans - είναι πολλά, μεταξύ αυτών:

  • Τα φασόλια μπορούν εύκολα να χειριστούν σε περιβάλλοντα οπτικής ανάπτυξης από χρήστες που δεν χρειάζονται τεχνική εξειδίκευση στην ανάπτυξη Java σε επίπεδο πηγής.

  • Λόγω της τυπικής διεπαφής, τα φασόλια είναι άμεσα διανεμήσιμα, γεγονός που επιτρέπει σε τρίτα μέρη να ενσωματώνονται πιο εύκολα στις αναπτυξιακές προσπάθειες.

  • Οι προγραμματιστές μπορούν εύκολα να μεταφέρουν κώδικα που έχει αναπτυχθεί για ένα έργο σε μια επαναχρησιμοποιήσιμη βιβλιοθήκη στοιχείων, στην οποία μπορείτε να έχετε πρόσβαση σε μελλοντικές προσπάθειες ανάπτυξης.

Το μάτι της καταιγίδας

Στο

πρώτο μέρος αυτής της σειράς

, αναπτύξαμε δύο απλά φασόλια: ένα μη οπτικό φασόλι συναγερμού και ένα γραφικό φασόλι αριστερού / δεξιού βέλους. Και οι δύο αυξήθηκαν με οπτικά

προσαρμοστής

και

πληροφορίες φασολιών

τάξεις. Στα φασόλια που καλύπτουμε αυτόν τον μήνα, δεν θα παρέχουμε εργαλεία προσαρμογής. Αντ 'αυτού, θα επικεντρωθούμε στη χρήση υπαρχόντων φασολιών και συστατικών για τη δημιουργία μεγαλύτερων, καλύτερων φασολιών.

Προαπαιτούμενα

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

Τα φασόλια

Από την αρχή έως το τέλος αυτής της σειράς, αναπτύσσουμε τα ακόλουθα φασόλια:

Συναγερμός Ένα μη γραφικό φασόλι που πυροδοτεί ένα συμβάν μετά από καθορισμένη καθυστέρηση.
ArrowBean

Ένα γραφικό φασόλι αριστερού βέλους / δεξιού βέλους.

ProgressBean

Ένα γραφικό φασόλι προβολής προόδου.

NumberFieldBean

Ένα γραφικό αριθμητικό Πεδίο κειμένου φασόλι με ρολά κουμπιά. Αυτό το φασόλι χρησιμοποιεί το φασόλι ArrowBean.

FontChooserBean

Ένα γραφικό φασόλι επιλογής γραμματοσειρών. Αυτό το φασόλι χρησιμοποιεί το NumberFieldBean.

FontSelectorBean

Ένα γραφικό φασόλι επιλογής γραμματοσειρών που εμφανίζει την τρέχουσα γραμματοσειρά και παρέχει κουμπιά OK / Cancel. Αυτό το φασόλι χρησιμοποιεί το FontChooserBean φασόλι.

FontDialogBean

Ένα γραφικό φασόλι επιλογής γραμματοσειρών που εμφανίζει τον επιλογέα γραμματοσειρών σε ξεχωριστό διάλογο. Αυτό το φασόλι χρησιμοποιεί το FontSelectorBean.

Συζητήσαμε το Συναγερμός και ArrowBean φασόλια λεπτομερώς τον περασμένο μήνα? σε αυτό το επεισόδιο, θα συζητήσουμε τα υπόλοιπα φασόλια σε διάφορα επίπεδα λεπτομέρειας.

Ίσως αναρωτιέστε γιατί χτίζουμε τρεις κόκκους γραμματοσειρών. Ο απώτερος στόχος είναι απλώς να παραχθεί ένας επιλογέας γραμματοσειρών που εμφανίζει ένα παράθυρο διαλόγου γραμματοσειράς όταν ο χρήστης κάνει κλικ σε ένα κουμπί. Αυτή η εργασία χωρίζεται φυσικά στα τρία φασόλια που θα παράγουμε: Το πρώτο είναι το περιβάλλον εργασίας χρήστη για την επιλογή γραμματοσειράς, το δεύτερο προσθέτει στοιχεία ελέγχου διαλόγου και ένα δείγμα γραμματοσειράς και το τρίτο εισάγει ένα κουμπί για να εμφανιστεί ο διάλογος και περιέχει το βασικό κωδικός χειρισμού διαλόγου.

Χωρίς φασόλια, θα πρέπει να αναπτύξουμε αυτά τα αντικείμενα ως εξειδικευμένα συστατικά AWT ή ως μία μονολιθική τάξη. χρησιμοποιώντας φασόλια, μπορούμε να αναπτύξουμε τα τρία μέρη ως ανεξάρτητα φασόλια που μπορούν να επαναχρησιμοποιηθούν από μόνα τους.

Το πεδίο εφαρμογής μας

Όπως και με την πρώτη δόση αυτής της σειράς, ασχολούμαστε μόνο με τους φασαρία αυτών των τάξεων και όχι τα πραγματικά παξιμάδια και μπουλόνια που τους κάνουν να τρυπούν. Ως αποτέλεσμα, θα συζητήσουμε τα φασόλια σε σκελετική μορφή, επισημαίνοντας με κόκκινο χρώμα τα θραύσματα που έχουν ιδιαίτερη σημασία, και αφήνοντας τις άλλες λεπτομέρειες για να διαβάσετε τον ελεύθερο χρόνο σας. Ούτε θα ασχοληθούμε με τα εργαλεία προσαρμογής, τα οποία καλύψαμε με αρκετή λεπτομέρεια με τη συζήτησή μας για τα δύο πρώτα φασόλια.

Για να δείτε την καταναγκαστική εργασία πίσω από τα φασόλια, ρίξτε μια ματιά στον πλήρη πηγαίο κώδικα.

Οικοδόμηση του φασολιού ProgressBean

ProgressBean

είναι ένα απλό φασόλι προόδου. Πρόκειται για ένα προσαρμοσμένο στοιχείο AWT που εμφανίζει μια ποσοστιαία τιμή και γραφική αναπαράσταση αυτής της τιμής, όπως φαίνεται στο παρακάτω σχήμα. Εκθέτει δύο ιδιότητες: τις τρέχουσες και τις μέγιστες τιμές γραμμής.

Η τρέχουσα τιμή εκτίθεται ως παρατηρήσιμη ιδιοκτησία. Παρατηρήσιμες ιδιότητες είναι ιδιότητες των οποίων οι αλλαγές μπορούν να παρατηρηθούν. Οι παρατηρητές είναι εγγεγραμμένοι στο φασόλι με τον ίδιο τρόπο που είναι οι ακροατές συμβάντων και ειδοποιούνται κάθε φορά που αλλάζει μια ιδιότητα. Οι μεμονωμένες ιδιότητες ενός φασολιού πρέπει να γίνονται σαφώς παρατηρήσιμες από το φασόλι. δεν είναι δυνατόν να παρατηρηθούν αλλαγές σε οποιαδήποτε ιδιοκτησία οποιουδήποτε φασολιού.

Αυτό το φασόλι εφαρμόζεται με τις ακόλουθες δύο κατηγορίες:

  • ProgressBean - Η κύρια κατηγορία φασολιών

  • ProgressBeanBeanInfo - Η κατηγορία πληροφοριών για τα φασόλια

Κατηγορία ProgressBean

ο

ProgressBean Η κατηγορία είναι η κύρια κατηγορία φασολιών, ένα απλό προσαρμοσμένο στοιχείο AWT και Java bean.

δημόσια τάξη ProgressBean επεκτείνει το στοιχείο ... 

Αυτό το φασόλι είναι ένα ελαφρύ συστατικό, γι 'αυτό επεκτείνουμε Συστατικό αντί Καμβάς, και παρέχει μια κατάλληλη χρώμα() μέθοδος. Το ελαφρύ πλαίσιο συνιστωσών είναι πιο αποτελεσματικό από το παραδοσιακό πλαίσιο προσαρμοσμένων συστατικών, που απαιτεί λιγότερους πόρους του τοπικού συστήματος παραθύρου. Ως συστατικό στοιχείο, κληρονομούμε αυτόματα την σειριοποιησιμότητα που απαιτείται από το JavaBeans και παρέχουμε τον προεπιλεγμένο κατασκευαστή no-arg.

public void setBarground (Color c) ... public Color getBarground () ... δημόσιο συγχρονισμένο void setMaximum (int m) ... public int getMaximum () ... 

Εδώ, εκθέτουμε το Χρώμα ιδιοκτησία barground (το χρώμα της γραμμής που εμφανίζεται) και το int ιδιοκτησία ανώτατο όριο (η μέγιστη τιμή γραμμής).

δημόσιο συγχρονισμένο void setValue (int v) {if (τιμή! = v) {value = v; βάφω ξανά (); fireValueChange (); }} δημόσια int getValue () ... 

ο int ιδιοκτησία αξία είναι παρατηρήσιμο, πράγμα που σημαίνει ότι πρέπει να ενημερώνουμε όλους τους ενδιαφερόμενους ακροατές όποτε αλλάζει η αξία του. Για το σκοπό αυτό, καλούμε μας fireValueChange () μέθοδος για την ενημέρωση των ακροατών όποτε setValue () λέγεται.

προστατευμένο ακροατήριο PropertyChangeSupport = νέο PropertyChangeSupport (αυτό); δημόσιο άκυρο addPropertyChangeListener (PropertyChangeListener l) {listeners.addPropertyChangeListener (l); } public void removePropertyChangeListener (PropertyChangeListener l) {listeners.removePropertyChangeListener (l); } 

Εδώ, διατηρούμε μια λίστα αντικειμένων που έχουν καταχωρηθεί για να ειδοποιούνται κάθε φορά που αλλάζει μια παρατηρήσιμη ιδιότητα. Χρησιμοποιούμε την τάξη PropertiChangeSupport από το java.beans πακέτο για τη διατήρηση αυτής της λίστας. Ο κατασκευαστής αυτής της τάξης απαιτεί να καθορίσουμε το φασόλι που θα είναι η προέλευση των γεγονότων αλλαγής ιδιοκτησίας. σε αυτήν την περίπτωση, είναι Αυτό, και οι μέθοδοι που παρέχει μας επιτρέπουν να διατηρήσουμε τη λίστα.

Εκθέτοντας τις μεθόδους addPropertyChangeListener () και αφαίρεσηPropertyChangeListener (), υποδεικνύουμε αυτόματα ότι αυτό το φασόλι έχει παρατηρήσιμες ιδιότητες. Ωστόσο, δεν το υποδεικνύουμε οι οποίες ιδιότητες είναι παρατηρήσιμες. Αυτές οι πληροφορίες πρέπει να τεκμηριώνονται κατάλληλα με το φασόλι.

προστατευμένο Integer oValue = νέο ακέραιο (τιμή); προστατευμένο άκυρο fireValueChange () {listeners.firePropertyChange ("value", oValue, oValue = new Integer (value)); } 

Καλούμε αυτήν τη μέθοδο για να ειδοποιήσουμε τους ακροατές για μια αλλαγή στο δικό μας αξία ιδιοκτησία; χρησιμοποιούμε το firePropertyChange () μέθοδος της λίστας μας για τη διάδοση αυτής της ειδοποίησης. Η πρώτη παράμετρος είναι το όνομα της ιδιότητας, η οποία πρέπει να ταιριάζει με το όνομα μιας εκτεθειμένης ιδιότητας. Η δεύτερη παράμετρος είναι η παλιά τιμή της ιδιότητας. και η τρίτη ιδιότητα είναι η νέα τιμή. ο PropertiChangeSupport η τάξη επιστρέφει χωρίς να κάνει τίποτα αν οι παλιές και νέες τιμές είναι ίδιες.

Κατηγορία ProgressBeanBeanInfo

ο

ProgressBeanBeanInfo η τάξη περιγράφει απλά το ProgressBean φασόλι, κρύβοντας τυχόν κληρονομικές πληροφορίες που θέλουμε να αποκρύψουμε.

Δημιουργία του φασολιού NumberFieldBean

Αυτό το φασόλι εφαρμόζει ένα κοινό στοιχείο διεπαφής χρήστη, το κυλιόμενο πεδίο εισαγωγής αριθμών - ένα αριθμητικό πεδίο κειμένου που παρέχει βέλη αύξησης και μείωσης, όπως φαίνεται στο παρακάτω σχήμα. Αυτό το φασόλι φέρνει μια σημαντική ιδέα JavaBeans:

προγραμματισμός χειρισμού των φασολιών

.

Ο προγραμματικός χειρισμός των φασολιών αναφέρεται στους μηχανισμούς που παρέχει το JavaBeans για τη δημιουργία και την πρόσβαση στα φασόλια μέσω προγραμματισμού. Αν και είναι δυνατή η πρόσβαση στα φασόλια χρησιμοποιώντας την τυπική δημιουργία αντικειμένων Java (νέο X ()) και μηχανισμοί χύτευσης τύπου ((Υ) x, συνιστάται να χρησιμοποιήσετε τους παρεχόμενους μηχανισμούς JavaBeans για να επιτρέψετε τη μελλοντική επέκταση του πλαισίου JavaBeans.

Αυτό το φασόλι εφαρμόζεται με τις ακόλουθες δύο κατηγορίες:

  • NumberFieldBean - Η κύρια κατηγορία φασολιών

  • NumberFieldBeanBeanInfo - Η κατηγορία πληροφοριών για τα φασόλια

Αριθμός κλάσης FieldBean

ο NumberFieldBean κλάση, η κύρια κατηγορία φασολιών, είναι ένα δοχείο AWT που προσθέτει τρία συστατικά: δύο ArrowBean φασόλια και α Πεδίο κειμένου. Πρόσβαση μέσω προγραμματισμού στο ArrowBean Το μάθημα απαιτεί να κάνουμε χρήση των μηχανισμών χειρισμού φασολιών που ανέφερα πριν από λίγο.

Η τρέχουσα αριθμητική τιμή εκτίθεται ως παρατηρήσιμη ιδιότητα. Αν και είναι μια φυσιολογική ιδιότητα που μπορεί να προσεγγιστεί και να χειριστεί μέσω των συνηθισμένων μεθόδων πρόσβασης φασολιών, είναι επίσης αισθητός, έτσι οι ακροατές μπορούν να εγγραφούν για να ειδοποιούνται κάθε φορά που αλλάζει η αξία του. Δεν ενεργοποιούμε ένα συμβάν όταν ο χρήστης πατά το Return, αν και αυτό θα ήταν μια προφανής επέκταση σε αυτήν την τάξη.

δημόσια τάξη NumberFieldBean επεκτείνει το Container υλοποιεί το ActionListener ... 

Επεκτείνουμε Δοχείο και εφαρμόστε ActionListener προκειμένου να λαμβάνουμε εκδηλώσεις από τα φασόλια και τα συστατικά AWT που χρησιμοποιούμε. Επέκταση Δοχείο αντί για τα πιο παραδοσιακά Πίνακας σημαίνει ότι αυτό το φασόλι, όπως το ProgressBean το φασόλι είναι ένα ελαφρύ συστατικό.

δημόσιο NumberFieldBean () ... 

Ως φασόλι, πρέπει να παρέχουμε έναν δημόσιο κατασκευαστή no-arg. Σημειώστε ότι δεν πρέπει να παρέχουμε άλλους κατασκευαστές για χρήση μέσω προγραμματισμού. Κάτι τέτοιο θα ήταν αντίθετο με τον μηχανισμό πρόσβασης JavaBeans.

δοκιμάστε το {down = (ArrowBean) Beans.instantiate (getClass () .getClassLoader (), "org.merlin.beans.arrow.ArrowBean"); } catch (Exception ex) {ex.printStackTrace (); } 

Εδώ, δημιουργούμε ένα ArrowBean χρησιμοποιώντας τον μηχανισμό εμφάνισης προγραμματισμού φασολιών. Δεν χρησιμοποιούμε την τυπική Java νέος χειριστής; αντ 'αυτού, χρησιμοποιούμε το θεσμικός () μέθοδος τάξης Φασόλια. Προσδιορίζουμε το ClassLoader για χρήση για τη φόρτωση της κατηγορίας φασολιών. σε αυτήν την περίπτωση, χρησιμοποιούμε τη δική μας ClassLoader και το πλήρως αναγνωρισμένο όνομα της κατηγορίας φασολιών ("org.merlin.beans.arrow.ArrowBean") και ρίξτε το αποτέλεσμα Αντικείμενο στην κατάλληλη τάξη.

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

προσθήκη ("East", (Component) Beans.getInstanceOf (down, Component.class)); 

Εδώ, ρίχνουμε το ArrowBean σε ένα Συστατικό και προσθέστε το ως κανονικό Συστατικό. Δεν χρησιμοποιούμε το πρότυπο (Συστατικό) μηχανισμός τύπου χύτευσης και δεν χρησιμοποιούμε το γεγονός ότι το δικό μας Συναγερμός είναι μια υποκατηγορία του Συστατικό; αντ 'αυτού, χρησιμοποιούμε το getInstanceOf () μέθοδος τάξης Φασόλια. Προσδιορίζουμε το φασόλι που θέλουμε να ρίξουμε και το Τάξη αντικείμενο στο οποίο θέλουμε να το ρίξουμε (σε αυτήν την περίπτωση, Component.class).

Παρόλο που αυτή η προσέγγιση δεν έχει νόημα αυτήν τη στιγμή, οι μελλοντικές εκδόσεις του JavaBeans θα υποστηρίζουν τα φασόλια που αποτελούνται από αρχεία πολλαπλών τάξεων, καθώς και τα φασόλια που μπορούν να εκθέσουν διαφορετικές πτυχές του εαυτού τους ως τις διαφορετικές κατηγορίες. Για παράδειγμα, ένα φασόλι μπορεί να φαίνεται να υποκατηγορεί και τα δύο Συστατικό και Απομακρυσμένο αντικείμενο παρέχοντας δύο συζευγμένες κατηγορίες: α Συστατικό και ένα Απομακρυσμένο αντικείμενο. Χρησιμοποιώντας τον μηχανισμό χύτευσης τύπου JavaBeans, το κατάλληλο αντικείμενο φασολιών μπορεί να επιστραφεί αυτόματα, έτσι ώστε τα φασόλια να έχουν εμφανή πολλαπλή κληρονομιά, αν και η Java δεν το υποστηρίζει εγγενώς. Για λεπτομέρειες, ανατρέξτε στην προδιαγραφή JavaBeans "Γλασκόβη". (Ένας σύνδεσμος προς αυτήν την προδιαγραφή παρέχεται στην ενότητα Πόροι αυτού του άρθρου.)

Είναι απαραίτητο για εμάς να χρησιμοποιήσουμε αυτούς τους μηχανισμούς πρόσβασης φασολιών τώρα, ώστε να μπορούμε να μεταφέρουμε τα φασόλια μας σε μελλοντικές τεχνολογίες JavaBeans χωρίς προβλήματα.

down.setDirection (ArrowBean.LEFT); down.addActionListener (αυτό); 

Εδώ, διαμορφώνουμε το ArrowBean χρησιμοποιώντας το setDirection () αξεσουάρ και το addActionListener () μέθοδος εγγραφής. Μπορούμε να χρησιμοποιήσουμε αυτές τις μεθόδους καταχώρησης αξεσουάρ και ακροατών απευθείας στο φασόλι που μόλις δημιουργήσαμε. Είναι απαραίτητο να χρησιμοποιήσετε τη δυνατότητα χύτευσης τύπου JavaBeans μόνο όταν έχουμε πρόσβαση σε μια πτυχή ενός φασολιού που κληρονομείται από άλλη τάξη.

δημόσιο συγχρονισμένο void setValue (int v) {field.setText (String.valueOf (v)); fireValueChange (getValue ()); } δημόσιο συγχρονισμένο int getValue () ... 

Εδώ, εκθέτουμε το int ιδιοκτησία αξία, η οποία είναι η αξία αυτού του πεδίου. Αυτή η ιδιότητα είναι παρατηρήσιμη, επομένως πρέπει να ειδοποιούμε τους ακροατές όποτε αλλάζει. Το κάνουμε αυτό καλώντας μας fireValueChange () μέθοδος.

public void setColumns (int c) ... public int getColumns () ... public synchronized void setMinimum (int m) ... public int getMinimum () ... δημόσιο συγχρονισμένο κενό σύνολοMaximum (int m) ... public int getMaximum () ... δημόσιο συγχρονισμένο κενό setStep (int s) ... public int getStep () ... 

Εδώ, εκθέτουμε το int ιδιότητες στήλες, ελάχιστο, ανώτατο όριο, και βήμα, που είναι, αντίστοιχα, ο αριθμός των στηλών που εμφανίζονται στο Πεδίο κειμένου, τις ελάχιστες και μέγιστες τιμές που πρέπει να διατηρεί αυτό το πεδίο και το ποσό με το οποίο τα κουμπιά βέλους πρέπει να αλλάξουν την τιμή. Αυτές οι ιδιότητες δεν είναι παρατηρήσιμες.

Λάβετε υπόψη ότι χρησιμοποιούμε συγχρονισμό για να διασφαλίσουμε την ασφάλεια του νήματος όπου χρειάζεται.

δημόσιο συγχρονισμένο άκυρο actionPerformed (ActionEvent e) {int value = getValue (); if (e.getSource () == κάτω) {if (τιμή> ελάχιστο) {value = (τιμή - βήμα> τιμή); ελάχιστο: σφιγκτήρας (τιμή - βήμα); setValue (τιμή); }} ...