9 Threads + AWT = Applets
Survol des principaux traits de Java : noyau du langage, couche objet, types
Slide: 1
Processus légers (Thread)
Modèle de parallélisme à mémoire partagée
- contexte d'exécution sur une même machine virtuelle
- même zone mémoire (¹ fork)
- ne dépend pas du système (Windows 3.1)
- possède un nom et une priorité
- pas de préemption à priorité égale
Þ le faire à la main
- ne va pas plus vite
- sert à exprimer des algos concurrents
Slide: 2
Création et Exécution
2 possibilités :
- sous-classer la classe Thread
et redéfinir la méthode public void run()
MCThread x = new MCThread (); x.start();
- Implanter l'interface Runnable
et implanter public void run
MCTheadI x = new MCThreadI();
MCThreadI y = new Thread(x,"Nom"); y.start()
Quand start() retourne, la tâche termine.
Slide: 3
Méthodes sur les threads
- start() et stop()
- suspend() et resume()
- wait() et notify (synchronisation)
- sleep(i)
- yield()
- interrupt() (exception)
Slide: 4
Relations entre threads
- sans relation
- avec relation mais sans synchronisation
- relation d'exclusion mutuelle
- relation d'exclusion mutuelle avec communication
Slide: 5
Sans relation
indentation
public class SR {
public static void main ( String []s) {
Thread t1 = new Aff("Bonjour");
t1.start();
new Aff("Au revoir").start();
}
}
class Aff extends Thread {
String txt;
Aff (String s){txt=s;}
public void run () {
while(true) {
ES.writeln(txt);
yield();
}
}
}
Slide: 6
Relation sans synchronisation
sur une même structure de données à des endroits différents :
Exemple : calcul de la nouvelle génération du jeu de la vie
par différentes threads.
ou ouverture d'une connexion sur une socket
Slide: 7
Synchronisation
Verrou (accès exclusif) sur un objet :
synchronized (o) { ... }
}
// ou sur une methode
synchronized type nom_methode( ..) { ...}
Une seule thread peut prendre le verrou (les autres attendent).
Le verrou est rendu à la sortie du bloc de synchronisation.
Slide: 8
Relation d'exclusion mutuelle
Dès que le verrou est pris :
-
appel d'une méthode synchronized
il garantit qu'une seule méthode ``synchronisee'' peut être
appelée
sur cet objet
- bloc synchronized sur un objet
il verouille l'objet.
Slide: 9
Communication
à l'intérieur d'un bloc de synchronisation
- o.wait() : relache le verrou et attend une notification
- o.notify() : relance une tâche en attente (une au hasard). Elle doit
en premier réacquérir le verrou.
- o.notifyAll() : relance toutes les tâches.
Slide: 10
Exclusion mutuelle avec communication
Producteur/Consommateur :
// thread du producteur // thread consommateur
entree code sync entree code sync
while(buffer plein) while (buffer vide)
wait() wait()
produit_1() consomme_1()
notify() notify()
Slide: 11
Abstract Windowing Toolkit
Paquetage de classes pour la construction d'interfaces graphiques :
- système graphique indépendant d'une plateforme
Þ avoir les boutons Mac sur MAc, Motif sous Motif, ...
- avoir une API de porgrammation simple (??)
- qui pourra être intégré dans un navigateur.
Slide: 12
Hiérarchie de classes
Slide: 13
Composants
objet abstrait ayant : une position, une taille, dessinable et pouvant recevoir des évènements
- composants simples : Button, Label, ...
- conteneurs : pouvant recevoir d'autres composants
possèdent un contexte graphique (Graphics).
Slide: 14
Conteneurs
- Ceux qui n'ouvrent pas de fenêtres : Panel, Applet
- Ceux qui ouvrent une fenêtre : Dialog, FileDialog et Frame
Pouvant suivre différents algorithmes de placement de composants.
Application graphique : instancie au moins une fois une Frame
Applet : est un composant graphique
Slide: 15
Dessiner
indentation
import java.awt.*;
import java.awt.event.*;
class TestXframeD {
static public void main(String [] args) {
XframeD d = new XframeD();
d.dessine();
}
}
class XframeD extends Frame {
Canvas p;
XframeD() {
super("DESSIN");
p = new Canvas();
p.setSize(400,300);
this.add(p);
this.pack();
this.show();
}
void dessine() {
Color c1 = Color.blue;
Color c2 = Color.red;
Graphics g = p.getGraphics();
g.drawString("Mon dessin",160,40);
for (int i = 0; i< 10; i++) {
g.fillRect(40+i*20,100,10,10);
}
}
}
Slide: 16
Créer une interface
indentation
import java.awt.*;
import java.awt.event.*;
class TestXframe {
static public void main(String [] args) {
Xframe e = new Xframe();
e.init_event();
}
}
class Xframe extends Frame {
String monlogin ="emmanuel";
String monpasswd ="pilpoil";
TextField login;
TextField passwd;
Panel p;
Xframe() {
super("LOGIN");
p = new Panel();
p.setSize(400,500);
login = new TextField(8);
passwd = new TextField(8);
p.add(new Label("Login : "));
p.add(login);
p.add(new Label("Password : "));
passwd.setEchoChar('*');
p.add(passwd);
this.add(p);
this.pack();
this.show();
}
void init_event() {
}
}
Slide: 17
Evénements
En JDK 1.1 : modèle par délégation.
figure=event1.eps,height=0.5
Slide: 18
Sources et délégués
Les composants (Source) peuvent déclencher des évènements
Ceux-ci seront traités par les ``délégués'' enregistrés:
instances de classe implantant des interfaces `Listener
public <TypeEvt>Listener set<TypeEvt>Listener(
<TypeEvt>Listener monDelegue)
public <TypeEvt>Listener add<TypeEvt>Listener(
<TypeEvt>Listener monDelegue)
public <TypeEvt>Listener remove<TypeEvt>Listener(
<TypeEvt>Listener monDelegue)
où <TypeEvt>
est remplacé par un événement :
addMouseListener(MouseListener monDelegue)
Slide: 19
Evénements et Composants
Chaque composant peut déclencher certains événements :
un Panel pourra déclencher un événement souris
(MouseEvent).
Un délégué implante une interface Listener.
Il existe des adaptateur implantant certaines interfaces (méthodes
> 1).
Listener Interface |
Adaptater Class |
Methods |
ActionListener |
NON |
actionPerformed |
MouseListener |
MouseAdapter |
mousePressed ... |
Slide: 20
Délégué
indentation
import java.awt.*;
import java.awt.event.*;
class AdaptateurAction implements ActionListener {
XframeE A;
AdaptateurAction(XframeE a) {
A=a;
}
public void actionPerformed(ActionEvent e) {
if ((e.getSource() == A.login) || (e.getSource() == A.passwd))
{if ((A.login.getText().equals(A.monlogin)) &&
(A.passwd.getText().equals(A.monpasswd)))
{A.OK=true; A.good();}
else {A.nogood();}
}
}
}
Slide: 21
Enregistrement
indentation
import java.awt.*;
import java.awt.event.*;
class TestXframeE {
static public void main(String [] args) {
XframeE e = new XframeE();
e.init_event();
}
}
class XframeE extends Xframe {
boolean OK = false;
void init_event () {
AdaptateurAction aa;
aa = new AdaptateurAction(this);
login.addActionListener(aa);
passwd.addActionListener(aa);
}
void good() {
ES.writeln("C'est parti");
System.exit(0);
}
void nogood() {
ES.writeln("Essaie encore!!!");
}
}
Slide: 22
Classes locales
Pour simplifier la communication entre le délégué et le
composant :
le JDK 1.1 a introduit les classes locales ou internes (y compris anonymes).
Rightarrow cela permet de ne pas passer le composant comme variable
du délégué.
Les variables dínstance du composant sont directement accessibles.
Slide: 23
Déclaration de classes locales
- nouveau membre (champs) d'une classe
- à l'intérieur d'un bloc d'instructions
Premier cas : accessible par la notation ``point''
Deuxième cas : non accessible en dehors du bloc
mais la valeur peut sortie du bloc (si implantation d'une interface)
Slide: 24
Exemple d'une classe locale
indentation
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
class Test3_1 extends Applet {
class AdaptateurSouris extends MouseAdapter
implements MouseListener {
public void mousePressed (MouseEvent e)
{
int x = e.getX();
int y = e.getY();
System.out.println("x = " + x + " y = "+y);
getGraphics().drawString("salut tout le monde",x,y);
}
}
Test3_1() {
MouseListener clic = new AdaptateurSouris();
addMouseListener(clic);
}
public void init () {
this.setBackground(Color.white);
}
}
Slide: 25
Classe (locale) anonyme
Dans les cas où le nom de la classe n'a pas d'importance :
elle peut être déclarée anonymement!!!
Slide: 26
Exemple d'une classe locale
indentation
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
class Test3_2 extends Applet {
Test3_2() {
MouseListener clic = new MouseAdapter () {
public void mousePressed (MouseEvent e)
{
int x = e.getX();
int y = e.getY();
System.out.println("x = " + x + " y = "+y);
getGraphics().drawString("salut tout le monde",x,y);
}
};
addMouseListener(clic);
}
public void init () {
this.setBackground(Color.white);
}
}
Slide: 27
Applets
La classe Applet hérite de Panel et implante Runnable.
Une applet possède une zone graphique (conteneur Panel) qui n'ouvre
pas une nouvelle fenêtre.
Slide: 28
cycle de vie
init()Þstart()Þstop()Þdestroy() où :
- init() : appelée au démarrage de l'applet(initialisation);
- start() : appelée pour lancer l'applet (après l'initialisation ou
après un stop()),
effectue le travail;
- stop() : appelée pour arrêter l'applet (quand la page HTML disparaît);
- destroy() : appelée pour libérer les ressources
allouées par l'applet (juste avant la disparition de l'applet).
void paint(Graphics g) : sera appelée à chaque réaffichage.
Slide: 29
Exécution
- Ecrire un fichier ``HTML''avec une balise
<APPLET>
... </APPLET>
- Lancer
appletviewer
sur ce fichier
- Télécharger ce fichier dans un navigateur :
HotJava, Communicator et I-Explorer
Slide: 30
Balise
<html>
<head> Exercices en Java
</head>
<body>
<H1> Test </H1>
<P>
<applet code="Test1" height=400 width=400>
<P><EM> Not a java-powered browser! </EM>
</applet>
</body>
</html>
Slide: 31
Applet dessin
indentation
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class graf extends Applet {
public void paint(Graphics g) {
g.drawRect(25,30,60,40);
g.drawRect(125,30,100,100);
g.setColor(Color.cyan);
g.drawOval(25,30,60,40);
g.drawOval(125,30,100,100);
}
}
Slide: 32
Applet login
indentation
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class passwdTest extends Applet {
String monlogin ="tartempi";
String monpasswd ="itaparit";
TextField login;
TextField passwd;
boolean OK = false;
ActionListener RC = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if ((e.getSource() == login) || (e.getSource() == passwd))
{if ((login.getText().equals(monlogin)) &&
(passwd.getText().equals(monpasswd)))
{OK=true; good();}
else {nogood();}
}
}
};
public void init() {
login = new TextField(8);
passwd = new TextField(8);
add(new Label("Login : "));
add(login);
add(new Label("Password : "));
passwd.setEchoChar('*');
add(passwd);
login.addActionListener(RC);
passwd.addActionListener(RC);
}
public void good() {
resize(120,180);
this.getGraphics().drawString("c'est parti...",10,150);
}
public void nogood() {
this.getGraphics().drawString("identification incorrecte",10,100);
}
}
This document was translated from LATEX by HEVEA.