MIM1
TD 7 de POOGL
Applets et Entrées-sorties
Vincent BOUDET
Bureau 343 (84-70)
email vboudet@ens-lyon.fr
15 mars 2001
A Rappels et exemples
Les applets sont des programmes Java présentant les caractéristiques
suivantes :
-
elles utilisent comme interface une fenêtre affichée dans une zone rectangulaire
d'une page HTML,
- elles disposent d'un contexte d'exécution fourni par l'application qui affiche
la page HTML (Netscape, Explorer, appletviewer...)
- elles sont soumises à des restrictions d'accès aux ressources,
- elles n'executent pas automatiquement la méthode main mais
la méthode init qui n'est psa statique.
Pour créer une applet, on étend la classe java.applet.Applet.
Regardons l'exemple suivamt :
import java.awt.*;
public class Bonjour extends java.applet.Applet
{
String s;
public void init()
{
s="Bonjour";
}
public void paint(Graphics g)
{
g.drawString(s,80,50);
}
}
Dans cet exemple, on redéfinit la méthode init. Cette méthode est la première à être
appelée lorsqu'on charge l'applet. Ici, nous définissons la chaîne s.
Dans un second temps, le navigateur appelle la méthode start que nous n'avons pas
redéfini ici. paint est ensuite appelée pour afficher le contexte graphique.
Enfin, nous aurions pu définir les méthodes stop (invoquée lorsque le
navigateur quitte la page) et destroy (invoquée lorsque le navigateur est quitté).
Pour afficher l'applet, il faut utiliser une page HTML et la balise <APPLET>.
Voici un exemple :
<html>
<body>
<applet code="Bonjour" width=200 height=150>
</applet>
</body>
</html>
Les paramêtres obligatoires sont code, width et height.
Comment passer des paramêtres à une applet ? Pour celà, on utilise la balise <PARAM> et la méthode
getParameter.
Question A.1
Modifier l'exmple précédent pour souhaiter la bienvenue à une personne dont le nom est passé
en paramêtre dans la page HTML.
B Utilisation un peu plus avancée
On va créer une applet permettant de dessiner à la souris.
Dans notre classe qu'on va appelée Dessin.java nous avons
besoin d'un constructeur et de deux gestionnaires d'évènements.
Il faut définir un MouseAdapter pour redéfinir la méthode
MousePressed. On veut mémoriser la position courante
de la souris qu'on fait un simple clic de la souris.
Question B.1
Créer une classe interne à Dessin étendant MouseAdapter
qui définit la méthode mousePressed pour mémoriser la position de
la souris.
On veut maintenant tracer les mouvements de la souris quand le
bouton de la souris est maintenu enfoncé. Pour celà, nous devons
utiliser un MouseMotionListener et plus particulièrement
la méthode mouseDragged.
Question B.2
Créer une classe interne à Dessin étendant MouseMotionAdapter
qui définit la méthode mouseDragged. Dans cette méthode, on trace un trait
entre les valeurs en mémoire de la souris (au dernier clic) et les
coordonnées courantes. On met ensuite à jour ces valeurs.
Question B.3
Définisser maintenant (et pour finir) le constructeur Dessin
en ajoutant les gestionnaires d'évènements. N'oubliez pas de faire
appel au constructeur de la classe Applet.
C Entrées-sorties
Les entrées et les sorties sont organisées en Java autour du concept de flot (anglais stream), à l'aide d'un ensemble très
développé de types. Un flot est une suite de valeurs (octets, caractères, objets quelconques) successivement lues ou
écrites. Ces flots sont ainsi classifiés en flots d'entrée (qui comportent des méthodes de lecture), et en flots de sortie (qui
comportent des méthodes d'écriture). Outre le programme, un flot d'entrée est connecté à une source, et un flot de
sortie à une cible. La source ou la cible d'un flot peut être un fichier, un tampon en mémoire, une chaîne de caractères,
un autre flot, une ressource Web ou bien un port Internet.
Les flots les plus basiques sont des flots d'octets. Les classes des flots d'octets en écriture ont un nom en
...OutputStream ; celles des flots d'octets en lecture ont un nom en ...InputStream. Pour travailler avec des
flots de caractères Unicode, on utilisera des classes en ...Writer et ...Reader.
C.1 Lire et écrire des flots d'octets
Les méthodes générales de lecture sur un flot d'octets sont :
-
int read(), qui lit l'octet suivant disponible sur le flot (et se bloque en l'attendant), et le retourne dans un int
entre 0 et 255, ou bien retourne -1 si la fin du flot est atteinte.
- int read(byte b[]), qui lit au plus b.length octets du flot, les place dans le tableau b, et retourne le
nombre d'octets lus ou bien -1 si la fin du flot est atteinte
Les méthodes générales d'écriture sur un flot d'octets sont :
-
void write(int c), qui écrit un octet, représenté par un int
- void write(byte[] b), qui écrit les b.length octets de b
- void flush(), qui vide le flot sur sa cible (mémoire, fichier, etc)
La lecture et l'écriture d'octets sur un fichier se fait à l'aide des classes FileInputStream et FileOutputStream.
Question C.1
Faites un programme qui copie un fichier dans un autre (dont les noms sont donnés sur la ligne de
commande), octet par octet ; si les deux noms de fichiers ne sont pas données sur la ligne de commande, on utilise les
flots standards System.in , et System.out (de type PrintStream), ce qui est possible car FileOutputStream et
PrintStream sont des sous-classes de OutputStream.
C.2 Lire et écrire sur un flot de caractères
Les flots de caractères sont des objets de classe Reader (flots de caractères d'entrée) ou Writer (flots de caractères de
sortie). Les méthodes read et write de ces classes sont analogues à celles opérant sur des flots d'octets, à la différence
que c'est un caractère 16 bits qui est lu ou écrit, et non un octet.
La conversion entre un flot d'octets et un flot de caractères se fait à l'aide des classes OutputStreamWriter et
InputStreamReader. Cette conversion se fait en connectant un flot d'octets à un flot de caractères :
InputStreamReader isr = new InputStreamReader(System.in);
Cette conversion permet éventuellement de spécifier le codage utilisé (par exemple, par la chaîne "MacSymbol" s'il
s'agit d'un codage MacIntosh) :
InputStreamReader isr =
new InputStreamReader(
new FileInputStream("toto"),
"MacSymbol"
);
Pour connecter un flot de caractères à un fichier, si cette conversion n'est pas nécessaire, il est plus simple de recourir
aux classe FileWriter et FileReader.
C.3 Connecter un flot à un tampon
Chaque opération de lecture ou d'écriture peut être très coûteuse sur certains flots ; c'est notamment le cas des accès à
un fichier, ou des accès à l'Internet. Pour éviter des opérations individuelles (sur un octet ou sur un caractère à la fois),
on préfère souvent travailler sur un tampon (anglais buffer). Par exemple, pour écrire sur un fichier, on écrira sur un
flot-tampon, lequel est connecté à un flot d'écriture sur un fichier.
Les classes qui mettent en oeuvre ces tampons sont :
-
BufferedInputStream, pour les flots d'octets en entrée
- BufferedOutputStream, pour les flots d'octets en sortie
- BufferedReader, pour les flots de caractères en entrée
- BufferedWriter, pour les flots de caractères en sortie
Un flot de caractères de la classe BufferedReader permet des opérations supplémentaires (par exemple, lecture d'une
ligne de texte). Il est très courant de connecter un tel tampon à un flot de lecture sur un fichier :
BufferedReader in =
new BufferedReader(new FileReader("toto"));
String s = in.readline();
Symétriquement, pour écrire sur un fichier, il est préférable de travailler avec un tampon :
PrintWriter out =
new PrintWriter(
new BufferedWriter(
new FileWriter("toto")));
out.println("un long texte");
Question C.2
Refaites le programme qui copie un fichier en utilisant un flot-tampon.
On peut connecter un flot à une ressource Web. Pour cela, on crée un objet URL
qui prend en paramêtre une adresse internet. Dans la classe URL, il existe une méthode
openStream.
Question C.3
Écrire un programme qui va chercher le fichier donné par son URL et le recopie dans
un autre fichier ou sur la sortie standard.
C.4 Connecter un flot à une socket TCP
On peut aussi connecté un flot d'entrée à un port Internet spécifié par un nom de machine et un numéro de
port. Par exemple, le numéro 13, est celui d'un serveur dont la réponse est une ligne contenant la date et l'heure
courante. La connexion à ce port utilise le protocole TCP.
Question C.4
Écrire un programme qui se connecte au port 13 de votre machine ou du machine
passé en paramêtre (Socket s = new Socket(machine, 13);) lit le flot d'entrée
de la socket (getInputStream). Ce flot d'entrée est ensuite transformé en un flot de caractères, puis placé
dans un tampon ; la ligne lue sur ce flot d'entrée est simplement copiée sur la sortie standard du programme.
On reviendra sur les flots quand on étudiera les threads et les sockets un peu plus en détail la prochaine fois.
This document was translated from LATEX by
HEVEA.