|
Les applications et les applets |
Les applications Java
Les applets
L'intégration des applets
dans les navigateurs
Transformer une applet en
application
Ce chapitre décrit les applications Java et le package java.applet de Java 1.0 qui rassemble les classes permettant de programmer une applet Java et de l'intégrer dans un navigateur.
Comme il est décrit au premier chapitre, l'environnement Java vous permet de développer principalement deux types de programmes : des applications Java ou des applets Java.
Les applications sont comparables à tout programme écrit dans un autre langage. Le point d'entrée d'une application Java est la méthode main () de la classe donnée en argument à la commande java et respectant la déclaration suivante :
public static void main (String [ ] args)Comme n'importe quelle classe ClasseExec qui définit cette méthode peut être exécutée par la Machine Virtuelle Java, vous pouvez ajouter une méthode main () à une ou plusieurs classes utilisées dans un même programme. Ceci permet de tester individuellement chacune de ces classes.
Attention, cette méthode est static et la Machine Virtuelle Java ne crée donc aucune instance de la classe ClasseExec.
Les arguments passés après le nom de la classe, comme dans la ligne de commande java ClasseExec arg0 arg1 sont mémorisés dans le tableau args (args [0] mémorise la chaîne arg0).La méthode main () peut être suivie d'une clause throws pour citer toutes les classes d'exceptions qu'elle n'intercepte pas. Ceci est pratique quand vous voulez écrire de petits programmes de test sans vous soucier du traitement de certaines exceptions.
De manière comparable au C, le point d'entrée d'un programme Java, est la méthode static main () définie par la classe passée en argument à l'interpréteur Java.
La Machine Virtuelle Java rend la main au système une fois terminée l'exécution de la méthode main (), si et seulement si plus aucun thread n'est vivant, excepté pour les threads en tâche de fond (daemon).
Vous pouvez aussi utiliser la méthode exit () de la classes System à tout moment pour forcer la Machine Virtuelle à rendre la main.
Pour sa propre gestion, la bibliothèque AWT crée un ensemble de threads aussitôt qu'elle est utilisée. Comme ces thread ne sont pas des daemons, il faut donc se servir de la méthode exit () pour forcer la fin d'un programme utilisant AWT.
Caractéristiques
Les applets sont des applications spéciales qui fonctionnent différemment des applications Java. En voici les principales caractéristiques :
- La classe d'une applet doit obligatoirement dériver de la classe Applet, être public et avoir un constructeur sans paramètre public (éventuellement celui fourni par défaut).
- Une applet de classe ClasseApplet est lancée grâce à la balise (tag) <APPLET CODE=ClasseApplet ...> définie dans un fichier HTML.
- Différents paramètres peuvent être passés à une applet grâce aux balise <PARAM NAME="Param" VALUE="ValueParam"> inclus après la balise <APPLET ...>.
- Une instance de la classe de l'applet demandée est créée pour chaque balise <APPLET ...>.
- Une applet n'a pas un unique point d'entrée comme pour les applications : les méthodes outrepassées init (), start (), stop () et destroy () d'une classe d'applet ClasseApplet sont appelées respectivement à la création de l'applet ClasseApplet, son affichage, son effacement et sa destruction.
- Une applet est une portion de fenêtre graphique : entendez par là que l'affichage d'informations d'une applet est en mode graphique et pas en mode texte : On n'utilise pas la méthode println () dans une applet pour afficher du texte, mais plutôt la méthode graphique drawString ().
- Comme pour une image, une applet s'affiche dans une zone de taille définie par la balise <APPLET ...> de la page HTML dans laquelle elle est exécutée.
- La classe Applet dérive de la classe Panel et non de la classe Window, ce qui implique que les applets ne peuvent bénéficier de services que l'on retrouve sur les fenêtres isolées (menus, icone, titre,...).
- La classe Applet et celles du package java.applet définissent des méthodes utiles dans un navigateur Internet (chargement d'un fichier HTML, récupération de l'URL courante et des paramètres passées à l'applet,...).
- Pour éviter toute intrusion dans le système où fonctionne le navigateur, le gestionnaire de sécurité (SecurityManager) défini par la Machine Virtuelle du navigateur est très restrictif :
- Aucun accès au système de fichiers local.
- Possibilité d'accéder uniquement à l'hôte sur lequel est hébergée le fichier de la classe de l'applet.
- Les fenêtres créées par une applet (de classe dérivée de la classe Window) comportent un bandeau indiquant que la fenêtre a été créée par l'applet.
- Impossibilité de lancer des applications locales.
- Impossibilité de définir des méthodes native et d'utiliser des librairies du système.
- Accès limité au propriétés du système de la Machine Virtuelle.
appletviewer et certains navigateurs permettent de modifier les paramètres du gestionnaire de sécurité, pour autoriser certaines opérations. Mais si vous voulez réaliser des applets accessibles publiquement sur Internet, concevez les en considérant que le niveau de sécurité des navigateurs utilisés pour exécuter vos applets sera à son maximum.
Certaines caractéristiques qui précédent s'adressent à l'utilisation d'applet dans des pages HTML affichées par un navigateur. Si vous utilisez appletviewer (ou Applet Runner sous Mac OS 9), la commande appletviewer pageweb.html créera une fenêtre isolée pour chaque applet définie par la balise <APPLET ...> du fichier pageweb.html.
On rencontre habituellement deux types d'applet :
- Des applets dans lesquelles on dessine directement un dessin ou un texte en outrepassant la méthode paint () de la classe Component, comme l'applet HelloWorld décrite au premier chapitre, dont le résultat donne ceci :
- Des applets qui sont utilisées comme container pour y inclure différents composants, en appelant la méthode add () de la classe Container, comme l'applet AppletBouton décrite au chapitre suivant, dont le résultat donne ceci :
La classe java.applet.Applet
La classe Applet appartient au package java.applet, et dérive des classes Panel, Container, Component, du package java.awt. Ces dernières classes définissent beaucoup de méthodes utiles à la gestion de fenêtres graphiques auxquelles la classe Applet ajoute des méthodes propres à la gestion des applets.
Constructeur
public Applet ()Méthodes
public void init ()Cette méthode est appelée automatiquement une fois au chargement du fichier HTML dans lequel une applet est appelée. C'est le point d'entrée principal de l'applet (comparable à la méthode main () des applications). Outrepassez cette méthode dans votre classe d'applet, pour initialiser votre applet.
public void start ()Cette méthode est appelée à chaque fois qu'une applet est visualisée dans un navigateur ou dans appletviewer. Si vous devez effectuer des opérations à chaque visualisation de votre applet, outrepassez cette méthode dans votre classe d'applet.
public void stop ()Cette méthode est appelée à chaque fois qu'une applet est effacée dans un navigateur ou dans appletviewer (la page HTML où est visualisée l'applet n'est plus la page courante). Si par exemple votre applet utilise un thread qui tourne continuellement, c'est l'endroit idéal pour l'arrêter, en outrepassant cette méthode dans votre classe d'applet, comme dans l'exemple du chronomètre. En effet, n'oubliez pas que si le thread n'est pas arrêté, il effectuera des opérations dont le résultat peut être inutile, puisque la page HTML n'est plus affichée dans le navigateur.
public void destroy ()Cette méthode est appelée quand le fichier HTML dans lequel une applet est appelée est supprimé de la mémoire du navigateur. Si vous devez libérer certaines ressources utilisées par votre applet, outrepassez cette méthode dans votre classe d'applet.
public String getAppletInfo ()Cette méthode renvoie une chaîne de caractères d'information sur une applet. Outrepasser cette méthode pour renvoyer une chaîne indiquant les renseignements concernant votre applet (Copyright, version,...) .
public String [ ][ ] getParameterInfo ()Cette méthode renvoie un tableau de chaînes de caractères correspondant aux paramètres qu'il est possible d'utiliser sur une applet. Outrepasser cette méthode pour renvoyer la liste des paramètres accepter par votre applet. Le tableau doit être un ensemble de tableaux de 3 chaînes fournissant pour chaque paramètre son nom, le type de valeur attendue et sa description, comme par exemple : {"param", "0-10", "Description de param"}.
public void resize (int width, int height) public void resize (Dimension d)Permet de changer les dimensions d'une applet.
public URL getDocumentBase ()Renvoie l'URL du fichier HTML dans lequel l'applet est incluse.
public URL getCodeBase ()Renvoie l'URL du répertoire du fichier .class à partir duquel l'applet a été chargée (cette URL est construite grâce à l'attribut CODEBASE du tag APPLET).
public String getParameter (String name)Cette méthode permet de récupérer la valeur ValueParam du paramètre name de l'applet donné par la balise <PARAM NAME="name" VALUE="ValueParam">. null est renvoyé si le paramètre name n'existe pas.
public AppletContext getAppletContext ()Renvoie l'instance de la classe AppletContext, représentant le contexte dans lequel l'applet tourne (fourni par le navigateur ou par appletviewer).
public boolean isActive ()Renvoie true si une applet est active. Une applet devient active à l'appel de sa méthode start ().
public void showStatus (String msg)Cette méthode affiche le message msg dans la fenêtre d'état du navigateur (en général, cette fenêtre est une barre d'état située en bas des fenêtres des navigateurs).
public Image getImage (URL url) public Image getImage (URL url, String name)Ces méthodes permettent d'obtenir l'image à l'URL url ou l'image name relative à url. L'image n'est effectivement chargée qu'à sa première utilisation (voir le chargement des images). Les images peuvent être aux formats GIF animé ou non, ou JPEG.
public AudioClip getAudioClip (URL url) public AudioClip getAudioClip (URL url, String name) public void play (URL url) public void play (URL url, String name)Ces méthodes permettent d'obtenir ou de jouer directement le fichier son à l'URL url ou le fichier son name relatif à url.
public final void setStub (AppletStub stub)Permet de donner à l'applet une instance stub de la classe implémentant AppletStub. Cette méthode est appelée par le navigateur ou par appletviewer pour lier l'applet aux fonctionnalités fournies par les interfaces AppletContext, AppletStub et AudioClip.
Les méthodes start () et stop () des classes Applet et Thread n'ont aucun lien entre elles. Une applet n'est pas un thread, mais par contre, il est vrai que la plupart des navigateurs crée un thread pour chaque applet d'une page HTML.
Exemples
Vous avez l'embarras du choix dans la liste des applets fournie dans la table des matières !
La plupart des méthodes de la classe Applet font appel aux méthodes des interfaces suivantes. Les classes implémentant ces interfaces sont fournies avec les navigateurs ou avec appletviewer.
L'interface java.awt.AppletContext
L'interface AppletContext représente le contexte dans lequel l'applet tourne.
Méthodes
public AudioClip getAudioClip (URL url) public Image getImage (URL url) public void showStatus (String status)Voir la classe Applet.
public Applet getApplet (String name) public Enumeration getApplets ()Ces méthodes renvoient soit une applet en fonction de son nom (donné par la valeur de NAME dans la balise <APPLET ...>), soit une énumération de toutes les applets du contexte dans lequel une applet tourne. Par exemple, une fois que vous avez trouvé une applet, il est possible de communiquer avec elle (voir l'exemple qui suit).
public void showDocument (URL url) public void showDocument (URL url, String target)Ces méthodes permettent de charger dans le navigateur ou dans appletviewer un nouveau document à l'adresse url. target peut être égal à une des valeurs suivantes :
- "_self" : le document est chargé dans le frame courant.
- "_parent" : le document est chargé dans le frame parent.
- "_top" : le document est chargé dans le frame de niveau le plus élevé.
- "_blank" : le document est chargé dans une nouvelle fenêtre sans nom.
- Une autre chaîne "Titre" : le document est chargé dans le cadre (frame) dénommé Titre.
showDocument () est utilisé typiquement pour charger un document quand un utilisateur clique sur un bouton défini dans une applet.
Exemples
Applets PlayApplet et BoutonsNavigation.
L'interface java.applet.AppletStub
L'interface AppletStub est utilisée pour intégrer une applet dans un navigateur ou dans appletviewer.
Méthodes
public boolean isActive () public URL getDocumentBase () public URL getCodeBase () public String getParameter (String name) public AppletContext getAppletContext ()Voir la classe Applet pour la définition de ces méthodes.
public void appletResize (int width, int height)Cette méthode est appelée par les méthodes resize () de la classe Applet pour redimensionner une applet dans la fenêtre d'un navigateur.
Voici un exemple d'utilisation des méthodes getParameter () et getApplet (), qui permet de retrouver une applet appletControlee dont le nom est donné en paramètre. Une fois trouvée cette applet, on lui associe un bouton qui appelle alternativement les méthodes start () ou stop () de l'applet appletControlee pour la démarrer ou l'arrêter. Ici, l'applet de la classe Observable est reprise pour illustrer cet exemple :
et le programme Java correspondant (à copier dans un fichier dénommé PlayApplet.java et invoqué à partir d'un fichier HTML) :
import java.applet.Applet; import java.awt.*; public class PlayApplet extends Applet { private Applet appletControlee = null; private Button boutonDemarrerArreter; public void init () { String nomApplet = getParameter ("Applet"); String action = getParameter ("Action"); if (nomApplet != null) try { Applet applet; do // Recherche de l'applet dont le nom égale nomApplet if ( (applet = getAppletContext () .getApplet (nomApplet)) == null || !applet.isActive ()) // Si l'applet recherchée n'existe pas, attendre 1 seconde // (l'applet n'est peut-être pas encore chargée) Thread.sleep (1000); else appletControlee = applet; while (appletControlee == null); // L'applet a été trouvée, ajouter un bouton pour la contrôler add (boutonDemarrerArreter = new Button (action)); // Si le paramètre action indique de démarrer l'applet au départ, // arrêter l'applet pour l'utilisateur puisse la démarrer if (action.equals ("D\u00e9marrer")) appletControlee.stop (); } catch (InterruptedException e) { } } // Méthode appelée quand on clique sur le bouton public boolean action (Event event, Object arg) { if (event.target == boutonDemarrerArreter) { // Arrêter ou démarrer l'applet suivant le nom du bouton if ("Arr\u00eater".equals (arg)) appletControlee.stop (); else { appletControlee.start (); appletControlee.validate (); } // Changer le nom du bouton et le réafficher boutonDemarrerArreter.setLabel ("Arr\u00eater".equals (arg) ? "D\u00e9marrer" : "Arr\u00eater"); boutonDemarrerArreter.invalidate (); validate (); return true; } return super.action (event, arg); } }Si vous consultez le source de ce fichier HTML , vous pourrez voir comment utiliser l'applet PlayApplet avec ses paramètres. Le paramètre de nom Applet vous permettant d'indiquer quel est le nom de la classe de l'applet que vous voulez contrôler :
<APPLET CODE="ObservateurCalcul" CODEBASE="../classes" NAME="calcul" ALT="ObservateurCalcul" WIDTH=250 HEIGHT=30 ALIGN=middle> </APPLET> <APPLET CODE="PlayApplet" CODEBASE="../classes" ALT="PlayApplet" WIDTH=80 HEIGHT=30 ALIGN=middle> <PARAM NAME="Applet" VALUE="calcul"> <PARAM NAME="Action" VALUE="Démarrer"> </APPLET>L'applet PlayApplet n'a pas qu'un intérêt didactique : elle permet de contrôler sans les modifier, des applets qui utilisent des threads créés dans la méthode start () et arrêtés dans la méthode stop (). Quand, comme dans certains exemples de ce manuel, vous utilisez des applets gourmandes en temps de calcul, ceci permet de proposer à l'utilisateur que ces applets aient leur threads qui ne fonctionnent qu'à sa demande (malheureusement la méthode getParameter () ne fonctionne pas avec les premières versions de certains navigateurs sous Windows).
L'interface java.applet.AudioClip
L'interface AudioClip permet de jouer les fichiers sons chargés. Le seul type de son reconnu sous Java 1.0 et 1.1 est le type de fichier Sun .au (µlaw, 8000 Hz, mono). Si vous voulez convertir des fichiers existants dans ce format, il existe des outils de conversion disponibles en shareware ou en freeware sur Internet. Il est possible de mixer plusieurs sons ensemble (si vous exécutez les méthodes play () ou loop () ensemble sur différents sons, les différents sons seront mélangés).
Méthodes
public void play ()Cette méthode démarre le son de l'objet AudioClip. A chaque fois, que cette méthode est appelée, le son redémarre.
public void loop ()Démarre le son et le joue en boucle.
public void stop ()Arrête le son. N'oubliez pas d'arrêter de jouer un son dans la méthode stop () d'une applet, si ce son ne doit être joué qu'avec cette applet et surtout s'il est joué en boucle.
Voici un exemple d'utilisation de l'interface AudioClip, qui joue le son correspondant à la note d'un octave de piano sur lequel on clique (il faut bien sûr une carte son sur votre ordinateur !):
et le programme Java correspondant (à copier dans un fichier dénommé Piano.java et invoqué à partir d'un fichier HTML) :
import java.applet.*; import java.awt.*; public class Piano extends Applet { AudioClip [ ] octave = new AudioClip [12]; String [ ] notes = {"do.au", "dodiese.au", "re.au", "rediese.au", "mi.au", "fa.au", "fadiese.au", "sol.au", "soldiese.au", "la.au", "ladiese.au", "si.au"}; Rectangle [ ] rectNotes = new Rectangle [12]; boolean [ ] notesBlanches = {true, false, true, false, true, true, false, true, false, true, false, true}; public void init () { // Chargement des 12 fichiers de notes for (int i = 0; i < notes.length; i++) octave [i] = getAudioClip (getCodeBase (), notes [i]); // Changement de la couleur de fond setBackground (Color.white); } // Méthode appelée par la Machine Virtuelle quand l'applet change de taille public void reshape (int newx, int newy, int largeur, int hauteur) { int largeurBlanche = largeur / 7; int largeurNoire = largeurBlanche / 2; // Calcul des rectangles représentant les 12 notes (noires ou blanches) for (int x = 0, i = 0; i < notes.length; x += notesBlanches [i++] ? largeurBlanche : 0) if (notesBlanches [i]) rectNotes [i] = new Rectangle (x, 0, largeurBlanche - 1, hauteur - 1); else rectNotes [i] = new Rectangle (x - largeurNoire / 2, 0, largeurNoire - 1, 2 * hauteur / 3); // Rappel de la méthode de la super classe super.reshape (newx, newy, largeur, hauteur); } // Méthode appelée par la Machine Virtuelle quand l'applet doit être dessinée public void paint (Graphics gc) { gc.setColor (Color.black); // Dessin des blanches for (int i = 0; i < notes.length; i++) if (notesBlanches [i]) gc.drawRect (rectNotes [i].x, rectNotes [i].y, rectNotes [i].width, rectNotes [i].height); // Dessin des noires for (int i = 0; i < notes.length; i++) if (!notesBlanches [i]) gc.fillRect (rectNotes [i].x, rectNotes [i].y, rectNotes [i].width, rectNotes [i].height); } // Méthode recherchant la note à la position (x,y) private AudioClip rechercherNote (int x, int y) { // Recherche d'abord parmi les noires puis les blanches car les // rectangles des noires sont au-dessus de ceux des blanches for (int i = 0; i < notes.length; i++) if ( !notesBlanches [i] && rectNotes [i].inside (x, y)) return octave [i]; for (int i = 0; i < notes.length; i++) if (rectNotes [i].inside (x, y)) return octave [i]; return null; } // Méthode appelée par la Machine Virtuelle // quand le bouton de la souris est enfoncé public boolean mouseDown (Event evt, int x, int y) { AudioClip note = rechercherNote (x, y); if (note != null) note.play (); return true; } }Les méthodes paint () et reshape () sont décrites dans le chapitre suivant. Les méthodes utilisées dans la méthode paint () ainsi que la méthode outrepassée mouseDown () sont décrites dans le chapitre sur la gestion de l'interface utilisateur.
Bien que le seul format reconnu actuellement réduise la taille (et la qualité) des fichiers sons, ceux-ci sont très gourmands en octets. Rien que l'applet Piano qui utilise douze (petits) fichiers sons de 6 K en moyenne, doit charger 72 K pour fonctionner. Donc faites attention à la taille de vos sons, si vous voulez utiliser vos applets sur Internet.
Il est partiellement possible de créer une classe d'applet qui puisse aussi fonctionner comme application isolée, en définissant une méthode main () qui crée une fenêtre dans laquelle l'applet est ajoutée (voir l'exemple de la classe Frame).
Les méthodes suivantes de la classe Applet sont en fait des appels indirects aux classes qui implémentent les interfaces AppletContext, AppletStub et AudioClip. Ces classes fournies par les navigateurs ou Appletviewer, sont liées à une applet après sa création grâce à la méthode setStub () de la classe Applet :
getDocumentBase ()
interface AppletStub
getCodeBase ()
interface AppletStub
getParameter ()
interface AppletStub
getAppletContext ()
interface AppletStub
isActive ()
interface AppletStub
getImage ()
interface AppletContext
getAudioClip ()
interface AppletContext
showStatus ()
interface AppletContext
play ()
interface AudioClip
Si vous utilisez dans votre applet une de ces méthodes, pour éviter le déclenchement d'exception il vous faut créer la ou les classes qui implémentent les méthodes des interfaces correspondantes, même si leur implémentation ne fait rien (seule la méthode getImage () est aussi disponible dans la classe Toolkit).
Une instance de la classe implémentant AppletStub est associée à chaque applet grâce à la méthode setStub (), une instance de la classe implémentant AppletContext est associée à chaque fenêtre de navigateur et une instance de la classe implémentant AudioClip est associée à chaque son.
|