10. Εισαγωγή στα Java Applets Ολοκληρώνοντας αυτό το κεφάλαιο θα μπορείτε Να περιγράφετε τη διαφορά ανάμεσα σε μία αυτοδύναμη εφαρμογή Java και ένα Java applet Να γράφετε μία HTML tag που θα καλεί ένα Java applet Να περιγράφετε την ιεραρχία κλάσεων του Applet και AWT Να δημιουργείτε το Java applet Hello world Να αναφέρετε και να περιγράφετε τις βασικές μεθόδους ενός applet Να περιγράφετε και να χρησιμοποιείτε ορθά το μοντέλο ζωγραφικής του AWT Να χρησιμοποιείτε μεθόδους applet για να διαβάζετε εικόνες και αρχεία από URLs Να χρησιμοποιείτε tags <param> για να διαμορφώνετε τα applets 10.1 Τι είναι ένα applet Ένα applet είναι ένα κομμάτι κώδικα Java που εκτελείται σε ένα περιβάλλον πλοηγού (browser). Διαφέρει από μία εφαρμογή στον τρόπο με τον οποίο εκτελείται. Μία εφαρμογή ξεκινά όταν καλείται η μέθοδος main(). Αντίθετα ο κύκλος ζωής ενός applet είναι μάλλον περισσότερο πολύπλοκος. Το κεφάλαιο αυτό θα ασχοληθεί με το πώς εκτελείται ένα applet, πώς να το φορτώσετε στο browser και πώς να γράψετε κώδικα για ένα applet. 10.1.1. Φόρτωμα ενός applet Επειδή ένα applet εκτελείται σε ένα Web browser δεν ξεκινά άμεσα πληκτρολογώντας μία εντολή. Αντ αυτού πρέπει να δημιουργήσετε ένα αρχείο HTML που θα λέει στον browser τι να φορτώσει και πώς να το εκτελέσει. Στη συνέχεια «δείχνετε» στο browser στο URL που καθορίζει το αρχείο HTML. Θα δούμε σε λίγο πώς πρέπει να είναι η μορφή ενός αρχείου HTML. 10.1.2. Περιορισμοί ασφαλείας σε ένα applet Επειδή τα applets είναι κομμάτια κώδικα που φορτώνεται πάνω από το δίκτυο, αναπαριστούν μία εγγενώς επικίνδυνη κατάσταση. Τι θα συμβεί αν κάποιος γράψει ένα «κακό» πρόγραμμα που διαβάζει το αρχείο με τους κωδικούς σας και το αποστέλλει μέσω internet; Ο τρόπος με τον οποίο η Java αποτρέπει κάτι τέτοιο είναι παρέχοντας μία κλάση SecurityManager που ελέγχει την πρόσβαση σε σχεδόν κάθε κλήση επιπέδου συστήματος στη Java Virtual Machine. Το μοντέλο αυτό ονομάζεται μοντέλο ασφαλείας sandbox η JVM παρέχει ένα sandbox που επιτρέπει στα applets να «παίζουν» όμορφα, αλλά απαγορεύεται να βγουν έξω από το sandbox τους. Το βάθος στο οποίο ελέγχεται η ασφάλεια υλοποιείται σε επίπεδο browser. Οι περισσότεροι browsers (συμπεριλαμβανομένου του Netscape) αποτρέπουν τα ακόλουθα: Εκτέλεση άλλου προγράμματος κατά το χρόνο εκτέλεσης 1
Οποιαδήποτε είσοδο/έξοδο σε αρχείο Κλήσεις σε οποιαδήποτε ιθαγενή μέθοδο (native method) Προσπάθειες να ανοίξει ένα socket σε οποιαδήποτε άλλη διεργασία που δε βρίσκεται στον υπολογιστή που παρείχε το applet. 10.1.3. Παράδειγμα Hello World! Ο πηγαίος κώδικας για το applet HelloWorld (στο πηγαίο αρχείο HelloWorld.java) παρουσιάζεται στη συνέχεια: Sample HelloWorld applet import java.awt.graphics; import java.applet.applet; public class HelloWorld extends Applet { String hw_text; public void init() { hw_text = Hello World ; public void paint(graphics g) { g.drawstring(hw_text, 25, 25); 10.2 Συγγραφή ενός applet Για να γράψετε ένα applet θα πρέπει να δημιουργήσετε μία κλάση που χρησιμοποιεί αυτή τη μορφή: import java.applet.*; public class HelloWorld extends Applet { Για να είναι μία κλάση applet, θα πρέπει να είναι δημόσια, και έτσι το όνομα του αρχείου θα πρέπει να ταιριάζει με το όνομα της κλάσης του applet στην περίπτωση αυτή HelloWorld.java. Επιπρόσθετα, η κλάση θα πρέπει να είναι υποκλάση της κλάσης java.applet.applet. 10.2.1. Ιεραρχία κλάσης Applet Στην πράξη η κλάση java.applet.applet είναι υποκλάση της java.awt.container. Είναι χρήσιμο να έχετε μία συνολική αίσθηση της ιεραρχίας των κλάσεων Applet και AWT. 2
java.lang.object java.awt.component java.awt.button java.awt.container java.awt.textarea java.awt.frame java.awt.panel java.applet.applet Η ιεραρχία δείχνει ότι ένα applet μπορεί να χρησιμοποιηθεί άμεσα ως αρχικό σημείο για ένα AWT layout. Επειδή το applet είναι panel, έχει εξ ορισμού flow layout manager. 10.2.2. Βασικές μέθοδοι Applet Σε κάθε εφαρμογή το πρόγραμμα ξεκινά από τη μέθοδο main(). Σε ένα applet όμως δεν ισχύει το ίδιο. Ο πρώτος κώδικας που εκτελεί ένα applet είναι αυτός που έχει οριστεί για την αρχικοποίησή του και η συνάρτηση δημιουργίας του. Αφού ολοκληρωθεί η συνάρτηση δημιουργίας, ο browser καλεί μία μέθοδο του applet που ονομάζεται init(). Η μέθοδος init() θα πρέπει να κάνει βασική αρχικοποίηση του applet και στη συνέχεια να ολοκληρωθεί. Αφού ολοκληρωθεί η init() ο browser καλεί μία άλλη μέθοδο που ονομάζεται start(). Θα δούμε τη start() πιο αναλυτικά στη συνέχεια. Αμφότερες οι μέθοδο init() και start() εκτελούνται μέχρι να ολοκληρωθούν πριν «ζωντανέψει» το applet και εξ αιτίας αυτού δεν μπορούν να χρησιμοποιηθούν για να προγραμματίσουμε συμπεριφορά που θα εμφανιστεί στη συνέχεια στο applet. Στην πράξη, σε αντίθεση με τη main() σε μία απλή εφαρμογή, δεν υπάρχει μία μέθοδος που να εκτελείται συνεχώς σε ολόκληρη τη ζωή του applet. Θα δούμε στη συνέχεια πώς αυτό επιτυγχάνεται με χρήση νημάτων, αλλά προς το παρόν, δεν μπορούμε να το κάνουμε. 10.2.3. Εμφάνιση ενός Applet Ουσιαστικά τα applets είναι γραφικά από τη φύση τους, συνεπώς αν και μπορείτε να κάνετε κλήσεις στην System.out.println(), κανονικά δε θα έπρεπε. Αντ αυτού θέλετε να δημιουργήσετε μία παρουσίαση (display) σε ένα γραφικό περιβάλλον. Μπορείτε να σχεδιάζεται (draw) στην παρουσίαση ενός applet δημιουργώντας μία μέθοδο paint(). Η μέθοδος paint() καλείται από το περιβάλλον του browser όποτε υπάρχει ανάγκη ανανέωσης της παρουσίασης του applet. Αυτό για παράδειγμα συμβαίνει όταν το παράθυρο του browser αποκτά ξανά το αρχικό του μέγεθος, μετά από κάποια ελαχιστοποίησή του. 3
Η μέθοδος paint() θα πρέπει να γραφεί έτσι ώστε να λειτουργεί σωστά οποτεδήποτε μπορεί να κληθεί. Αυτό ισχύει γιατί η έκθεση εξαρτάται από το περιβάλλον, και όχι από το πρόγραμμα και συνεπώς συμβαίνει ασύγχρονα. 10.2.4. Η μέθοδος paint() και τα Graphics Η μέθοδος paint() λαμβάνει ένα όρισμα, το οποίο είναι στιγμιότυπο της κλάσης java.awt.graphics. Μπορείτε να το χρησιμοποιήσετε για να σχεδιάσετε ή να γράψετε κείμενο μέσα στο applet σας. Αυτό που ακολουθεί είναι ένα ελάχιστο παράδειγμα ενός applet, η οποία χρησιμοποιεί τη μέθοδο paint() για να γράψει κείμενο. import java.awt.*; import java.applet.applet; public class HelloWorld extends Applet { public void paint(graphics g) { g.drawstring( Hello World!, 25, 25); Σημείωση Τα αριθμητικά ορίσματα στη μέθοδο drawstring είναι οι συντεταγμένες x και y σε pixel για την αρχή του κειμένου. Οι συντεταγμένες αυτές αναφέρονται στη γραμμή βάσης (baseline) της γραμματοσειράς, συνεπώς αν γράψετε στην y συντεταγμένη μηδέν το αποτέλεσμα θα είναι το μεγαλύτερο μέρος των γραμμάτων σας να βρίσκονται έξω (πάνω) από το χώρο παρουσίασης μόνο ότι γράφεται κάτω από τη γραμμή, π.χ. η «ουρά» στο «μ» θα είναι ορατό. 10.3 Μέθοδοι applet και κύκλος ζωής ενός applet Ο κύκλος ζωής ενός applet είναι λίγο πιο πολύπλοκη απ ό,τι την περιγράψαμε μέχρι τώρα. Υπάρχουν τρεις βασικές μέθοδοι που σχετίζονται με αυτόν τον κύκλο ζωής. Αυτές είναι οι init(), start() και stop(). 10.3.1. init() Αυτή η συνάρτηση μέλος καλείται όταν δημιουργείται το applet και φορτώνεται για πρώτη φορά σε ένα browser που υποστηρίζει Java (όπως ο Applet Viewer). Το applet μπορεί να χρησιμοποιήσει τη μέθοδο αυτή για να αρχικοποιήσει τιμές δεδομένων. Η μέθοδος αυτή δεν καλείται κάθε φορά που ο browser ανοίγει τη σελίδα που περιέχει το applet, αλλά μόνο την πρώτη φορά. 10.3.2. start() Η μέθοδος start() καλείται για να δηλώσει στο applet ότι θα πρέπει να «ζωντανέψει». Αυτό συμβαίνει όταν το applet ξεκινά για πρώτη φορά, αφού ολοκληρωθεί η μέθοδος init(). Επίσης συμβαίνει οποτεδήποτε ο browser επανέρχεται στην κατάστασή του μετά από μία κατάσταση όπου είχε γίνει εικονίδιο ή όταν ο browser επιστρέφει στη σελίδα που περιέχει το applet αφού έχουμε μεταφερθεί σε ένα άλλο URL. Αυτό σημαίνει ότι το applet μπορεί να χρησιμοποιήσει τη μέθοδο αυτή για να πραγματοποιήσει εργασίες όπως να ξεκινά ένα animation ή να παίζουν ήχοι. public void start() { 4
musicclip.play(); 10.3.3. stop() Η μέθοδος stop() καλείται όταν το applet παύει να είναι «ζωντανό». Αυτό συμβαίνει όταν ο browser γίνεται εικονίδιο (iconized) ή όταν ακολουθεί ένα σύνδεσμο σε ένα άλλο URL. Το applet μπορεί να χρησιμοποιήσει τη μέθοδο αυτή για να πραγματοποιήσει εργασίες όπως να σταματήσει το animation. public void stop() { musicclip.stop(); Ουσιαστικά οι μέθοδοι start() και stop() δημιουργούν ένα ζευγάρι, έτσι ώστε η start() να μπορεί να χρησιμοποιηθεί για να προκαλέσει συμπεριφορά σε ένα applet, ενώ η stop() χρησιμοποιείται για να σταματήσει αυτή τη συμπεριφορά. 10.4 Ζωγραφική AWT Επιπρόσθετα στις βασικές μεθόδους του κύκλου ζωής ένα applet έχει σημαντικές μεθόδους που σχετίζονται με την παρουσίασή του. Οι μέθοδοι αυτοί στην πράξη δηλώνονται και τεκμηριώνονται για την κλάση AWT Component και είναι σημαντικό να συμμορφωνόμαστε στο σωστό μοντέλο για την παρουσίαση και χειρισμό με χρήση του AWT. Η ενημέρωση της παρουσίασης γίνεται από διακριτό νήμα στο οποίο θα αναφερόμαστε ως νήμα AWT. Το νήμα αυτό μπορεί να κληθεί για να χειριστεί δύο καταστάσεις οι οποίες σχετίζονται με την ενημέρωση της παρουσίασης. Η πρώτη από τις δύο καταστάσεις είναι η έκθεση (exposure), όπου μέρος της παρουσίασης έχει καταστραφεί και πρέπει να αντικατασταθεί. Αυτό μπορεί να συμβεί οποτεδήποτε και το πρόγραμμά σας θα πρέπει να μπορεί να το αντιμετωπίζει. Η δεύτερη κατάσταση είναι όταν το πρόγραμμα αποφασίζει να ξανασχεδιάσει την παρουσίαση με νέα περιεχόμενα. Αυτό μπορεί να απαιτεί την αφαίρεση πρώτα της παλιάς εικόνας. 10.4.1. Η μέθοδος paint(graphics g) Ο χειρισμός έκθεσης (exposure handling) γίνεται αυτόματα και έχει ως αποτέλεσμα μία κλήση στη μέθοδο paint(). Χρησιμοποιείται μία διευκόλυνση της κλάσης Graphics, η οποία ονομάζεται clip rectangle, ώστε να βελτιστοποιήσει τη μέθοδο paint ώστε οι ενημερώσεις να μη γίνονται σε ολόκληρη την περιοχή των γραφικών, αλλά μόνο στην περιοχή που καταστράφηκε. 10.4.2. Η μέθοδος repaint() Από την άλλη, μπορείτε να ενημερώσετε το σύστημα ότι θέλετε να αλλάξετε την παρουσίαση καλώντας τη repaint(). 5
10.4.3. Η μέθοδος update(graphics g) H repaint προκαλεί ένα AWT νήμα να καλέσει μία άλλη μέθοδο που ονομάζεται update(). Η μέθοδος update συνήθως συμπεριφέρεται καθαρίζοντας την τρέχουσα παρουσίαση και καλώντας στη συνέχεια την paint(). Το μοντέλο αυτό απαιτεί να έχετε υιοθετήσει μία συγκεκριμένη στρατηγική για τη συντήρηση της παρουσίασής σας: Συντήρηση ενός μοντέλου της παρουσίασης. Αυτό μπορεί να γίνει χρησιμοποιώντας πολλές διαφορετικές προσεγγίσεις. Θα μπορούσατε να χρησιμοποιείται μία απεικόνιση τιμών pixels ή μία τεχνική υψηλότερου επιπέδου, όπως ένα πίνακα σχημάτων. Η μέθοδος paint() σας θα πρέπει να κάνει render την παρουσίαση με βάση μόνο τα περιεχόμενα του μοντέλου. Αυτό τη επαναδημιουργία της παρουσίασης με συνεπή τρόπο όποτε καλείται, και συνεπώς υπάρχει ορθός χειρισμός της έκθεσης. Όταν το πρόγραμμα θέλει να αλλάξει την παρουσίαση θα πρέπει να ενημερώνει το μοντέλο και στη συνέχεια να καλεί τη μέθοδο repaint(), ώστε να καλείται από το νήμα AWT η μέθοδος update(). Σημείωση Μόνο ένα νήμα AWT χειρίζεται όλη τη ζωγραφική των components και επίσης την κατανομή των συμβάντων εισόδου. Εξ αιτίας αυτού, θα πρέπει να αποφεύγετε να σπαταλάτε πολύ χρόνο είτε στην paint() είτε στην update(). Σε εξαιρετικές περιπτώσεις θα χρειαστείτε τη βοήθεια και άλλων νημάτων για να το επιτύχετε. Ο προγραμματισμός νημάτων αποτελεί θέμα άλλου κεφαλαίου. Το διάγραμμα που ακολουθεί παρουσιάζει τον τρόπο με τον οποίο σχετίζονται οι μέθοδοι paint(), update() και repaint(). repaint() Νήμα AWT (σε αναμονή) Έκθεση update() - καθαρισμός περιοχής κλήση paint() paint() 10.5 O appletviewer Ο appletviewer είναι μία εφαρμογή Java η οποία σάς επιτρέπει να εκτελείτε applets χωρίς να χρησιμοποιείτε ένα web browser. 6
Σημείωση Οποιοσδήποτε browser με υποστήριξη Java πραγματοποιεί τις ίδιες βασικές λειτουργίες όπως αυτές που θα περιγράψουμε εδώ για το appletviewer. 10.5.1. Τι είναι ο appletviewer; Συνήθως ένα applet εκτελείται μέσα από ένα Web browser που υποστηρίζει Java, όπως ο HotJava ή ο Netscape Navigator. Όμως, για να απλοποιήσουμε και να επιταχύνουμε τη διαδικασία ανάπτυξης, το JDK περιέχει ένα απλό εργαλείο το οποίο έχει σχεδιαστεί μόνο για να βλέπουμε applets και όχι σελίδες HTML. Το εργαλείο αυτό είναι ο appletviewer. Ο appletviewer διαβάζει HTML από ένα URL που του παρέχεται στη γραμμή εντολής. Σε αυτή την HTML αναμένει να βρει εντολές για να φορτώσει και να εκτελέσει ένα ή περισσότερα applets. Θα αγνοήσει οποιαδήποτε άλλη HTML εντολή και εξ αιτίας αυτού ο appletviewer δεν παρουσιάζει απλή HTML και δεν ενσωματώνει τα applets μέσα σε μία σελίδα κειμένου. 10.5.2. Κλήση applets με τον appletviewer Ο appletviewer μοιάζει με ένα μικρό browser. Αναμένει ως όρισμα το όνομα ενός αρχείου HTML για να το φορτώσει. Το αρχείο αυτό περιέχει μία tag HTML η οποία καθορίζει τον κώδικα που θα φορτώσει ο appletviewer. <html> <applet code=helloworld.class width=100 height=100> </applet> </html> Ο appletviewer δημιουργεί το χώρο ενός browser, συμπεριλαμβανομένης μίας περιοχής γραφικών, στην οποία θα εκτελεστεί το applet και στη συνέχεια καλεί την κατάλληλη κλάση applet. Στο παράδειγμα αυτό, ο appletviewer φορτώνει μία κλάση με το όνομα HelloWorld και της επιτρέπει να λειτουργεί μέσα στο γραφικό χώρο. 10.5.3. appletviewer και ιεραρχία Applet Το ακόλουθο διάγραμμα παρουσιάζει την ιεραρχία κληρονομικότητας για τον appletviewer και applets. java.lang.object +- -java.awt.component +-----java.awt.container java.awt.panel -------+------java.awt.window +--java.applet.applet +------java.awt.frame +---sun.applet.appletviewer 7
10.6 Χρήση appletviewer 10.6.1. Σύνοψη appletviewer [-debug] urls... O appletviewer δέχεται είτε το όνομα ενός αρχείου HTML που περιέχει το tag <applet> ή το όνομα ενός URL σε ένα αρχείου HTML. Αν το HTML αρχείο που θα μεταβιβαστεί στον appletviewer δεν περιέχει ένα έγκυρο <applet> tag, ο appletviewer δε θα κάνει τίποτα. Ο appletviewer δεν παρουσιάζει άλλες HTML tags. Η μόνη έγκυρη επιλογή στο appletviewer είναι η ένδειξη debug, η οποία ξεκινά το applet στο Java debugger, jdb. Για να μπορέσετε να δείτε τον Java πηγαίο κώδικα στο debugger θα πρέπει να μεταγλωττίσετε το Java κώδικά σας με την επιλογή g. 10.6.2. Παράδειγμα Η εντολή appletviewer που φαίνεται στη συνέχεια ξεκινά το appletviewer $ appletviewer example1.html Αυτό προκαλεί και παρουσιάζει το πιο κάτω μικρό παράδειγμα. 10.7 Η tag applet 10.7.1. Σύνταξη Στη συνέχεια παρουσιάζεται η πλήρης σύνταξη της tag applet <applet archive=archivelist code=appletfile.class width=pixels height=pixels [codebase=codebaseurl] [alt=alternatetext] [name=appletinstancename] [align=alignment] [vspace=pixels] [hspace=pixels] > 8
[<param name=appletattribute1 value=value>] [<param name=appletattribute2 value=value>]... [alternatehtml] </applet> 10.7.2. Περιγραφή archive=archivelist Η προαιρετική αυτή attribute περιγράφει ένα ή περισσότερα αρχεία (archives) που περιέχουν κλάσεις ή άλλους πόρους που θα «προ-φορτωθούν». Οι κλάσεις φορτώνονται χρησιμοποιώντας ένα στιγμιότυπο ενός AppletClassLoader μαζί με το δεδομένο CODEBASE. Τα αρχεία στην archivelist χωρίζονται με «,». code=appletfile.class Η υποχρεωτική αυτή attribute δίνει το όνομα του αρχείου που περιέχει τη μεταγλωττισμένη υποκλάση της Applet που αντιστοιχεί στο συγκεκριμένο applet. Θα μπορούσε να είναι επίσης της μορφής apackage.appletfile.class. Σημείωση Το αρχείο αυτό είναι σχετικό με βάση το URL του HTML αρχείου από το οποίο το φορτώνετε. Δεν μπορεί να περιλαμβάνει ένα όνομα διαδρομής. Για να αλλάξετε το URL βάσης του applet, δείτε την tag codebase πιο κάτω. width=pixels height=pixels Οι υποχρεωτικές αυτές attributes δίνουν το αρχικό πλάτος και ύψος (σε pixels) της περιοχής παρουσίασης του applet, χωρίς να υπολογίζονται οποιαδήποτε παράθυρα ή dialogs εμφανίζει το applet. codebase=codebaseurl Η προαιρετική αυτή attribute καθορίζει το URL βάσης για το applet τον κατάλογο που περιέχει τον κώδικα του applet. Αν δεν έχει καθοριστεί αυτή η attribute χρησιμοποιείται το URL του κειμένου. alt=alternatetext Η προαιρετική αυτή attribute καθορίζει οποιοδήποτε κείμενο θα πρέπει να παρουσιάζεται αν ο browser κατανοεί το tag applet αλλά δεν μπορεί να εκτελέσει Java applets. name=appletinstancename Η προαιρετική αυτή attribute καθορίζει ένα όνομα για το στιγμιότυπο του applet, ώστε τα applets που βρίσκονται στην ίδια σελίδα να μπορούν να βρουν το ένα το άλλο (και να επικοινωνούν μεταξύ τους). align=alignment Η προαιρετική αυτή attribute καθορίζει τη στοίχιση του applet. Οι δυνατές τιμές είναι οι ίδιες με αυτές της tag IMG στη βασική HTML: left, right, top, texttop, middle, absmiddle, baseline, bottom και absbottom. vspace=pixels hspace=pixels Οι προαιρετικές αυτές attributes καθορίζουν το πλήθος των pixels πάνω και κάτω από το applet (vspace) και σε κάθε πλευρά του applet (hspace). Αντιμετωπίζονται με τον ίδιο τρόπο όπως και οι attributes vspace και hspace της tag IMG. <param name=appletattribute1 value=value> Αυτή η tag είναι ο μόνος διαθέσιμος τρόπος για να ορίσουμε attributes συγκεκριμένες στο applet. Τα applets έχουν πρόσβαση στα attributes τους με τη μέθοδο getparameter(). 9
Οι browsers που δεν υποστηρίζουν Java θα παρουσιάζουν όλη την κανονική HTML που παρουσιάζεται ανάμεσα στα tags <applet> και </applet>. Οι browsers που υποστηρίζουν Java αγνοούν την κανονική HTML που βρίσκεται ανάμεσα σε αυτά τα tags. To URL που καθορίζετε ως όρισμα στον appletviewer θα πρέπει να περιέχει εντολές για τη φόρτωση ενός applet. Οι εντολές αυτές έχουν τη μορφή ενός applet tag το οποίο στην πιο απλή μορφή του φαίνεται ως εξής: <applet code=helloworld.class width=100 height=100> </applet> Σημειώστε ότι η γενική μορφή αυτού του tag είναι η ίδια όπως και όλων των άλλων HTML, με χρήση των συμβόλων < και > για να διαχωριστούν οι εντολές. Όλα τα τμήματα που παρουσιάζονται εδώ είναι απαραίτητα, πρέπει να έχετε τόσο το <applet > όσο και το </applet>, και στο τμήμα <applet > πρέπει να καθορίζετε την καταχώρηση για κώδικα και ύψος και πλάτος. Σημείωση Γενικά, θα πρέπει να αντιμετωπίζετε τα applets σα να είναι σταθερού μεγέθους, λαμβάνοντας το μέγεθος όπως καθορίζεται στο applet tag. Θα βρείτε στη συνέχεια ότι είναι πιθανό υπό ορισμένες συνθήκες να αλλάζετε το μέγεθος ενός applet, αλλά τα αποτελέσματα δεν είναι πάντα καλά. 10.8 Επιπρόσθετες διευκολύνσεις Applet Υπάρχουν διαθέσιμες αρκετές επιπλέον διευκολύνσεις σε ένα applet και θα τα παρουσιάσουμε εδώ. Όλα τα προγράμματα Java έχουν πρόσβαση σε δικτυακές διευκολύνσεις, χρησιμοποιώντας τις κλάσεις του πακέτου java.net. Τα applets έχουν επιπρόσθετες μεθόδους που τους επιτρέπουν να καθορίζουν πληροφορία σχετικά με το περιβάλλον του browser στο οποίο έχουν ξεκινήσει. Η κλάση java.net.url περιγράφει URLs και μπορεί να χρησιμοποιηθεί για να συνδεθεί σε αυτά. Δύο μέθοδοι στην κλάση Applet μπορούν να καθορίσουν την τιμή σημαντικών URLs. getdocumentbase() επιστρέφει ένα αντικείμενο URL που περιγράφει την τρέχουσα σελίδα του browser. getcodebase() επιστρέφει ένα αντικείμενο URL που περιγράφει την πηγή του κώδικα του ίδιου του applet. Συχνά αυτό είναι το ίδιο με την τρέχουσα σελίδα, αλλά αυτό δεν είναι απαραίτητο. Χρησιμοποιώντας το αντικείμενο URL ως αρχικό σημείο μπορείτε να φέρετε στο applet σας εικόνες και ήχους. getimage(url base, String target) φέρνει μία εικόνα από το αρχείο με όνομα target το οποίο βρίσκεται στο URL που καθορίζει η base. Η επιστρεφόμενη τιμή είναι ένα στιγμιότυπο της κλάσης Image. getaudioclip(url base, String target) φέρνει έναν ήχο από το αρχείο με όνομα target το οποίο βρίσκεται στο URL που καθορίζει η base. Η επιστρεφόμενη τιμή είναι ένα στιγμιότυπο της κλάσης AudioClip. 10
10.9 Μία απλή δοκιμή Image Το επόμενο applet θα φέρει το αρχείο εικόνας graphics/joe.surf.yellow.small.gif σχετικό ως προς τη διαδρομή καταλόγου που επιστρέφει η μέθοδος getdocumentbase και θα το εμφανίσει στον appletviewer. HelloWorld extended to draw an image Assumes existence of graphics/joe.surf.yellow.small.gif import java.awt.*; import java.applet.applet; public class HwImage extends Applet { Image duke; public void init() { duke = getimage(getdocumentbase(), graphics/joe.surf.yellow.small.gif ); public void paint(graphics g) { g.drawimage(duke, 25, 25, this); Τα ορίσματα της μεθόδου drawimage() είναι: 1. Το αντικείμενο Image που πρόκειται να σχεδιαστεί 2. Η συντεταγμένη X για τη σχεδίαση 3. Η συντεταγμένη Y για τη σχεδίαση 4. Ο παρατηρητής εικόνας (image observer). Ένας παρατηρητής εικόνας είναι κάτι που πρέπει να γνωρίζει αν άλλαξε η εικόνα. Μία εικόνα που φορτώνεται με το getimage() θα αλλάξει με το χρόνο αφού γίνει πρώτη φορά η κλήση. Αυτό συμβαίνει γιατί η φόρτωση γίνεται στο παρασκήνιο (background). Κάθε φορά που φορτώνεται μεγαλύτερο μέρος της εικόνας καλείται ξανά η μέθοδος paint(). Αυτό γίνεται γιατί το applet έχει δηλωθεί ως παρατηρητής μεταβιβαζόμενος ως το τέταρτο όρισμα της κλήσης drawimage(). 10.10 AudioClips Η γλώσσα Java έχει επίσης μεθόδους για να παίζει audio clips. Οι μέθοδοι αυτές βρίσκονται στην κλάση java.applet.audioclip. Προφανώς, για να παίξετε ήχο θα πρέπει να έχετε το κατάλληλο υλικό στον υπολογιστή σας. 11
10.10.1. Παίζοντας ένα clip Ο πιο απλός τρόπος για να ακούσετε ένα audio clip είναι μέσω της μεθόδου play της Applet: play(url sounddirectory, String soundfile); ή πιο απλά play(url soundurl); Ένα σύνηθες URL για να χρησιμοποιήσετε με τη μέθοδο play() είναι ο κατάλογος όπου βρίσκονται τα αρχεία HTML. Η πρόσβαση στη θέση αυτή γίνεται μέσω της μεθόδου getdocumentbase(): play(getdocumentbase(), bark.au ); Για να δουλέψει αυτό το αρχείο HTML και το αρχείο bark.au πρέπει να βρίσκονται στον ίδιο κατάλογο. 10.11 Μία απλή δοκιμή ήχου Το επόμενο applet εκτυπώνει το μήνυμα Audio Test στον appletviewer και στη συνέχεια παίζει ένα αρχείο ήχου sounds/cuckoo.au HelloWorld extended to play an Audio sound Assume existence of sounds/cuckoo.au file import java.awt.graphics; import java.applet.applet; public class HwAudio extends Applet { public void paint(graphics g) { g.drawstring( Audio Test, 25, 25); play(getdocumentbase(), sounds/cuckoo.au ); 10.12 Επανάληψη με ένα audio clip Μπορείτε επίσης να αντιμετωπίσετε ένα audio clip ως εικόνα. Μπορείτε να τα φορτώσετε και να τα παίξετε αργότερα. 10.12.1. Φόρτωση ενός Audio Clip Για να φορτώσετε ένα audio clip, χρησιμοποιήστε τη μέθοδο getaudioclip από την κλάση java.applet.applet: AudioClip sound; sound = getaudioclip(getdocumentbase(), bark.au ); Από τη στιγμή που ένα clip έχει φορτωθεί, μπορείτε να χρησιμοποιήσετε μία από τις τρεις μεθόδους που σχετίζονται μαζί τους: play, loop ή stop. 12
10.12.2. Παίξιμο ενός Audio Clip Για να παίξουμε ένα φορτωμένο audio clip χρησιμοποιούμε στη μέθοδο play της κλάσης java.applet.audioclip sound.play(); Για να ξεκινήσουμε ένα clip να παίζει και να το αναγκάσουμε να επαναλαμβάνεται (αυτόματα) χρησιμοποιούμε τη μέθοδο loop της κλάσης java.applet.audioclip sound.loop(); 10.12.3. Σταμάτημα ενός Audio Clip Για να σταματήσουμε ένα clip που παίζεται χρησιμοποιούμε τη μέθοδο stop στην κλάση java.applet.audioclip sound.stop(); 10.13 Μία απλή δοκιμή επανάληψης Ιδού ένα παράδειγμα που κάνει αυτόματη επανάληψη σε ένα φορτωμένο audio clip HelloWorld extended to loop an audio track Assumes existence of sounds/cuckoo.au import java.awt.graphics; import java.applet.*; public class HwLoop extends Applet { AudioClip sound; public void init() { sound = getaudioclip(getdocumentbase(), sounds/cuckoo.au ); public void paint(graphics g) { g.drawstring( Audio test, 25, 25); public void start() { sound.loop(); public void stop() { sound.stop(); 13
10.14 Είσοδος από το ποντίκι Ένα από τα πιο χρήσιμα χαρακτηριστικά που υποστηρίζει η γλώσσα Java είναι η άμεση αλληλεπίδραση. Μία εφαρμογή μπορεί να δίνει σημασία στο ποντίκι και να αντιδρά σε αλλαγές στο ποντίκι. Το μοντέλο συμβάντων στο JDK 1.1 υποστηρίζει έναν τύπο συμβάντος για κάθε αλληλεπίδρασης. Τα συμβάντα ποντικιού λαμβάνονται από κλάσεις που υλοποιούν τη διεπαφή MouseListener, η οποία λαμβάνει συμβάντα για: mouseclicked όταν έχει γίνει κλικ στο ποντίκι (το πλήκτρο του ποντικιού έχει πιεστεί και έχει αφεθεί σε μία κίνηση). mouseentered όταν το ποντίκι έχει μπει σε ένα component mouseexited όταν το ποντίκι αφήνει ένα component mousepressed όταν το πλήκτρο του ποντικιού είναι πατημένο mousereleased όταν το πλήκτρο του ποντικιού έχει εν συνεχεία αφεθεί. 10.15 Μία απλή δοκιμή με το ποντίκι Το επόμενο πρόγραμμα παρουσιάζει τη θέση ενός κλικ με το ποντίκι μέσα σε ένα applet. HelloWorld extended to watch for mouse input HelloWorld! is reprinted at the location of the mouse click. import java.awt.*; import java.awt.event.*; import java.applet.applet; public class HwMouse extends Applet implements MouseListener { int mousex = 25; int mousey = 25; Register the mousepressed event public void init () { addmouselistener(this); public void paint(graphics g) { g.drawstring( Hello world!, mousex, mousey); public void mousepressed(mouseevent evt) { mousex = evt.getx(); 14
mousey = evt.gety(); repaint(); We are not using the other mouse events public void mouseclicked(mouseevent evt) { public void mouseentered(mouseevent evt) { public void mouseexited(mouseevent evt) { public void mousereleased(mouseevent evt) { 10.16 Ανάγνωση παραμέτρων Στο αρχείο HTML η tag applet μπορεί να μεταβιβάσει πληροφορία διαμόρφωσης (configuration) στο applet. Αυτό γίνεται χρησιμοποιώντας την tag <param>. Για παράδειμα: <applet code=configureme.class width=100 heigh=100> <param name=image value=duke.gif> </applet> Μέσα στο applet μπορείτε να χρησιμοποιήσετε τη μέθοδο getparameter() για να διαβάσετε τις τιμές αυτές import java.awt.*; import java.applet.*; public class DrawAny extends Applet { Image im; public void init() { URL mypage = getdocumentbase(); String imagename = getparameter( image ); im = getimage(mypage, imagename); public void paint(graphics g) { g.drawimage(im, 0, 0, this); Αν το όνομα της παραμέτρου δεν μπορεί να βρεθεί σε κάποια tag <param> μέσα στο ζεύγος <applet> </applet>, τότε η getparameter() επιστρέφει null. Ένα πρόγραμμα παραγωγής θα πρέπει να το αντιμετωπίσει με καλό τρόπο (gracefully). Ο τύπος παραμέτρου είναι πάντα String. Αν τη χρειάζεστε με άλλον τύπο πρέπει να τη μετατρέψετε. Για παράδειγμα για να διαβάσετε μία int παράμετρο: int speed = Integer.parseInt(getParameter( speed )); 15
Οι παράμετροι, εξ αιτίας της φύσης της HTML δεν είναι case sensitive. Είναι όμως καλό στυλ να αποφασίσετε και να χρησιμοποιείτε είτε μόνο κεφαλαία είτε μόνο πεζά, όπως παρουσιάζονται. 10.17 Κώδικας που λειτουργεί με δύο τρόπους Είναι δυνατό να δημιουργήσουμε κώδικα στη Java μέσα στο ίδιο αρχείο που να μπορεί να λειτουργεί είτε ως εφαρμογή Java είτε ως Java applet. Υπάρχει λίγη παραπάνω δουλειά στην κατανόηση του τι απαιτεί η εφαρμογή, αλλά από τη στιγμή που έχει δημιουργηθεί ο κώδικας applet/εφαρμογής μπορεί να χρησιμοποιηθεί ως πρότυπο για πιο πολύπλοκα προγράμματα. 10.17.1. Applet/Εφαρμογή Στη συνέχεια δίνεται το πρόγραμμα Hello World ως applet/εφαρμογή Example of Hello World that is both an applet and an application import java.applet.applet; import java.awt.*; import java.awt.event.*; public class AppletApp extends Applet { An application will require a main() public static void main (String args[]) { Create a Frame to house the applet Frame frame = new Frame( Application ); Create an instance of the class (applet) AppletApp app = new AppletApp(); Add it to the center of the frame frame.add( Center, app); frame.setsize(200, 200); frame.validate(); frame.setvisible(true); Register the AppletApp class as the listener for a Window Destroy event frame.addwindowlistener(new WindowControl(app)); Call the applet methods app.init(); app.start(); end main 16
public void paint(graphics g) { g.drawstring( Hello World, 25, 25); public void destroy () { System.exit(0); Class used to control the applet window class WindowControl extends WindowAdapter { Applet c; public WindowControl (Applet c) { this.c = c; public void windowclosing(windowevent e) { c.destroy(); 10.18 Εργασίες 10.18.1. Επιπέδου 1: Γράψτε ένα applet 1. Ξεκινήστε ένα καινούριο παράθυρο Shell ή Command Window 2. Χρησιμοποιώντας έναν text editor πληκτρολογήστε το πρόγραμμα HwMouse.java 3. Τροποποιήστε το πρόγραμμα ώστε να επαναλαμβάνει τρία διαφορετικά μηνύματα καθώς κάνετε κλικ μέσα στο applet. 4. Μεταγλωττίστε το πρόγραμμα HelloWorld.java $ javac HwMouse.java 5. Χρησιμοποιώντας έναν text editor, δημιουργήστε ένα αρχείο HwMouse.html με ένα tag <applet> για να καλέσετε το πρόγραμμα HwMouse.class 6. Ελέγξτε το applet σας με την εντολή appletviewer $ appletviewer HwMouse.html 10.18.2. Επιπέδου 2: Ομόκεντρα τετράγωνα 1. Δημιουργήστε ένα applet που παράγει μία σειρά από ομόκεντρα τετράγωνα (ή ομόκεντρους κύκλους) όπως οι επόμενοι 17
2. Προσπαθήστε να κάνετε κάθε τετράγωνο (ή κύκλο) διαφορετικού χρώματος: αν κάνετε import την κλάση java.awt.color μπορείτε να προσθέσετε χρώμα στα Java applets με την μέθοδο setcolor: import java.awt.color;... public void paint(graphics g) { g.setcolor(color.blue); g.drawline(5, 5, 50, 50);... 10.18.3. Επιπέδου 3: Java Rollover Applet 1. Γράψτε ένα applet που θα παρουσιάζει μία εικόνα σε μία θέση του ποντικιού μαζί με έναν ήχο όταν το ποντίκι περνάει πάνω από την περιοχή της εικόνας. 2. Όταν το ποντίκι κάνει κλικ στην εικόνα βάλτε μία άλλη εικόνα ή έναν άλλο ήχο. 18