Le langage JAVA 1.1 : le résumé

publicité
20/11/00
_________________________________________________________
_________________________________________________________
Le langage JAVA 1.1 : le résumé
auteur : Véronique Gaildrat
_________________________________________________________
_________________________________________________________
Cours Java 1.1
1
20/11/00
Table des matières
1.Le langage............................................................................................................................... 4
1.1 Syntaxe....................................................................................................................................... 4
1.1.1
1.1.2
1.1.3
1.1.4
1.1.5
Expressions...................................................................................................................................... 4
Instructions ...................................................................................................................................... 5
Variables ......................................................................................................................................... 6
Types ............................................................................................................................................... 6
Tableaux.......................................................................................................................................... 7
1.2 Classes ....................................................................................................................................... 7
1.2.1
1.2.2
1.2.3
1.2.4
Définition de classes ........................................................................................................................ 7
Variables de classes ......................................................................................................................... 8
Constantes ( mot clef final ) ............................................................................................................. 8
Interrogation sur les classes.............................................................................................................. 8
1.3 Instances..................................................................................................................................... 8
1.3.1
1.3.2
1.3.3
1.3.4
1.3.5
1.3.6
1.3.7
Variables d'instances........................................................................................................................ 8
Création........................................................................................................................................... 9
This ................................................................................................................................................. 9
Super ............................................................................................................................................. 10
Clones............................................................................................................................................ 10
Comparaison : equals..................................................................................................................... 11
instanceOf...................................................................................................................................... 11
1.4 Contrôle de la visibilité des variables et des méthodes ................................................................ 11
1.5 Méthodes .................................................................................................................................. 12
1.5.1
1.5.2
1.5.3
1.5.4
1.5.5
1.5.6
1.5.7
Déclaration de méthodes ................................................................................................................ 12
Mode de transmission des paramètres ............................................................................................ 12
Surcharge des méthodes et Constructeurs....................................................................................... 13
Destructeurs [option]...................................................................................................................... 15
Appel des méthodes ....................................................................................................................... 15
Méthodes de classe (mot clef static)................................................................................................ 16
Main.............................................................................................................................................. 17
1.6 Exemple.................................................................................................................................... 17
2.Héritage (mot clef extends).................................................................................................... 18
2.1 Héritage simple ......................................................................................................................... 19
2.2 Conversion de types .................................................................................................................. 19
2.3 Conversion d'objets (typage dynamique) .................................................................................... 19
2.4 Polymorphisme - Redéfinition.................................................................................................... 20
3.Méthodes et classes abstraites................................................................................................ 20
4.Exceptions............................................................................................................................. 21
4.1 Hiérarchie de classes exception.................................................................................................. 21
4.2 Créer une nouvelle classe exception ........................................................................................... 21
4.3 Récupérer une exception............................................................................................................ 21
4.4 Debugger .................................................................................................................................. 22
4.5 Lever une exception .................................................................................................................. 22
Cours Java 1.1
2
20/11/00
4.6 La clause throws ....................................................................................................................... 22
4.7 La clause finally........................................................................................................................ 23
5.Input / Output ....................................................................................................................... 23
5.1 Affichage à l'écran .................................................................................................................... 23
5.2 Lecture au clavier...................................................................................................................... 24
5.3 Entrées/Sorties dans un fichier................................................................................................... 25
6.Packages ............................................................................................................................... 28
7.Interfaces (mot clef implements) ............................................................................................ 30
8.AWT et gestion des événements ............................................................................................ 30
8.1.1 Identification du bouton cliqué....................................................................................................... 31
8.2 Version simple .......................................................................................................................... 31
8.3 Version complète (plus complexe) ............................................................................................. 32
9.Threads ................................................................................................................................. 35
10. Exemple ............................................................................................................................ 36
Cours Java 1.1
3
20/11/00
1. Le langage
1.1 Syntaxe
1.1.1 Expressions
Commentaires
// fin de ligne commentée
/* commentaire borné aux extrémités */
/** pour javadoc */
pour générer de la doc de façon automatique
Constantes :
-4
// cte entière de type int
4L
// entier long de valeur 4
0777
// cte octale
0XFF
// hexadécimal
10e45 ou .36E-2 ou 5.62
// cte virgule flottante double
2.56f
// cte float
Booléen : true ou false
Caractères :
'a'
// caractère a
\n
// <RC, LF>
\r
// <RC>
\t
// tab
\f
// saut de page
\b
// back
\\
// anti slash
\'
// guillemet simple
\"
// guillemet double
\d
// octal
\x
// hexadécimal
\u
// unicode (symboles codés)
Constantes chaînes :
"ceci est une chaîne"
""
// chaîne vide
"ceci est un chaîne avec \" guillemets \" à l'intérieur"
\u2122
// ™ (trade mark)
Opérateurs et expressions :
+
*
/
// int / int -> int
%
// modulo
==
// ATTENTION syntaxe du test d'égalité C like !!!!
!=
// différent
<
<=
>
>=
&&
// ET logique
||
// OU logique
!
// NON logique
^
// XOR bit à bit
~
// NOT bit à bit
<<
// décalage à gauche bit à bit
>>
// décalage à droite bit à bit
>>>
// décalage à droite avec remplissage avec des 0 bit à bit
&
// ET bit à bit
|
// OU bit à bit
Cours Java 1.1
4
20/11/00
new
1.1.2 Instructions
création d'une nouvelle instance de classe
Toute instruction est toujours terminée par un ---> ;
// affectation
i = 1;
// déclaration
int i;
// déclaration avec affectation d'une valeur initiale à la variable
int i = 1;
// initialisation d'une variable d'instance
m.engineStart = True;
// affichage à l'écran d'un message composé de chaînes de carac et de valeurs numériques
System.out.println ("texte entre les guillemets " + entier1 + "...." + string1 + flottant1 + ....);
// bloc d'instructions
{
// dans les structures de contrôle, on peut trouver une instruction
...
// ou un bloc d'instructions
}
// instruction conditionnelle
if ( cond )
instruction
// ou { bloc d'instructions }
else
instruction;
// ou { bloc d'instructions }
// opérateur conditionnel
test ? true_result : false_result; // test true => exécution de true_result, false_result sinon
int smaller = x < y ? x : y;
// branchement conditionnel
switch (variable)
// type de base autorisé : byte, char, short, int, long
{
case v1 :
{
...
// accolades si bloc d'instructions
}
break;
case v2 :
instruction;
break;
default : default_result;
}
// boucle for
for (cond. initiales; cond d'arrêt; expression devant faire évoluer vers la cond d'arrêt)
instruction;
// ou { bloc d'instructions }
// boucle while
while (cond)
instruction;
// ou { bloc d'instructions }
do
Cours Java 1.1
5
20/11/00
{ ...;
} while (cond);
Les sorties de blocs peuvent être forcées par l'instruction break.
Il y a la possibilité de faire des boucles étiquetées.
exterieur:
for ( cond )
{
while ( x < 50 )
{
...
if ( cond )
{
break exterieur;
}
}
}
L'instruction continue permet de redémarrer la boucle à la prochaine itération. Cela permet
d'éviter certains tests mais il vaut mieux éviter de l'utiliser si on ne maîtrise pas ...
1.1.3 Variables
Les variables locales sont déclarées et utilisées dans les blocs.
Les valeurs des variables de classe s'appliquent à toutes les instances de la classe (et à la classe
elle même);
Les variables d'instance sont les attributs de la classe et permettent de connaître l'état d'une
instance donnée.
On ne trouve pas de variables globales.
// déclaration de variables
type nom de var = init;
type n1 = v1, n2 = v2, n3 = v3;
// toute variable locale doit être initialisée avant d'être utilisée.
Les instances de classe sont initialisées à null à la déclaration.
Les variables d'instance et de classe sont initialisées par défaut à la création de l'instance :
num -> 0
carac -> '\0'
bool -> false
Convention de noms de variables pour les mots combinés : le premier en minuscule, les autres en
majuscule (un nom de classe est toujours majuscule).
Exemple : Button theButton
1.1.4 Types
8 types de données de base :
byte
(octet)
short
(2 octets)
int
(4 octets)
long
(8 octets)
Toute classe est un type :
Cours Java 1.1
float
double
char
boolean
(4 octets)
(8 octets)
(2 octets non signés)
(true, false)
6
20/11/00
String
Font
1.1.5 Tableaux
lastName;
basicFont;
Les tableaux sont typés. Il faut déclarer une variable pour stocker l'adresse du tableau :
Point hits [];
// <=> Point [] hits; !!
Il faut ensuite créer une nouvelle instance tableau et affecter sa référence à la variable.
ATTENTION
de la même façon qu'en C les indices pour un tableau de 10
éléments vont de 0 à 9 !!
les tableaux sont des tableaux d'instances, il faut donc créer
chaque élément du tableau indépendamment
1.1.5.1 Création d'instances de tableaux
// 10 références nulles vers une chaîne
(et non une chaîne de 10 carac!)
String names [] = new String [10];
Point hits [2] = new Point { {10, 20}, {11, 21} };
String riz [] = {"rond", "long", "parfumé"};
// initialisé par les données
1.1.5.2 Accès à un élément
hits [0].x --> fournit la valeur 10
hits [1].y --> fournit la valeur 21
ATTENTION vérification de dépassement de capacité
names [10] = "toto" => erreur de compilation ou d'exécution si l'indice est évalué à l'exec
int len = names.length;
// len recevra la valeur 10
1.1.5.3 Multidimensionnels
int coords [][] = new int [4][4];
...
coords [0][0] = 15;
coords [0][1] = 12;
1.2 Classes
Toute classe hérite de façon implicite de la classe Object qui est donc à la racine de toute
arborescence de classes.
Classe
Attributs <=> Variables d’instances -> stockées dans l’instance
Variables de classe -> stockées dans la classe
Comportement <=> méthodes définies dans la classe
Méthodes d’instances appelées Méthodes
Méthodes de classe qui agissent sur la classe
1.2.1 Définition de classes
Cours Java 1.1
7
20/11/00
- simple :
class MyClassName
{
...;
}
- héritage :
class MyClassName extends ClasseParente
{
...;
}
- référence à une interface :
class MyClassName implements nomInterface1, nI2, ...
{
...;
}
1.2.2 Variables de classes
Pour qu'une variable déclarée dans la classe soit considérée comme une variable de classe, il faut
placer le mot clef static dans sa déclaration :
class Famille
{
static String nom = "Durand";
String prénom;
int âge;
...
}
Durand est fixé pour toutes les instances de famille. Prénom et âge sont propres à chaque
instance.
Famille dad = new Famille ();
System.out.println (" nom : " + dad.nom);
// donne le même résultat que
System.out.println (" nom : " + Famille.nom);
1.2.3 Constantes ( mot clef final )
Les constantes sont déclarées dans les classes ou en local :
final float pi = 3.141592f;
final int maxsize = 4000000;
1.2.4 Interrogation sur les classes
- getClass ( )
Permet de déterminer la classe d'une instance (utile en cas de typage dynamique).
Class classe = obj.getClass ( );
- getName ( )
Retourne le nom de la classe
String name = obj.getClass ( ).getName ( );
1.3 Instances
1.3.1 Variables d'instances
Cours Java 1.1
8
20/11/00
Les variables d'instances sont référencées au moyen de la notation pointée :
Object myObject;
...
myObject.var = val;
// var est une variable d'instance de la classe Object
myObject.otherObject.otherVar = true;
|
|
variable
| instance
instance
class Vélo extends PersonPoweredVehicle
{
String bikeType;
// var d'instance : vtt, route ou city
...
}
1.3.2 Création
La création d'une instance se fait au travers d'un new => allocation + constructeur.
L'allocation est dynamique et un garbage collector se charge de récupérer la mémoire allouée et
qui n'est plus référencée.
Seules les instances de type String n'ont pas besoin d'un new.
String s = "une chaîne qq";
Mais
String s = new String ();
est possible et générera une chaîne vide.
Pour les autres classes :
Random r = new Random ();
Motorcycle m2 = new Motorcycle ();
Quand on fait appel à un constructeur sans paramètres, une instance de base est créée avec des
valeurs par défaut .
Quand le constructeur attend des arguments, ils déterminent les valeurs initiales des (toutes ou
certaines) variables d'instances.
ATTENTION : certaines classes interdisent la création d'objets sans arguments.
Ex :
import java.util.Date;
class createDates
{
public static void main (String args [] )
// static => méthode de classe
{
Date d1, d2, d3;
d1 = new Date ();
// sans paramètres
System.out.println (" Date 1 " + d1 );
d2 = new Date (71, 7, 1, 7, 30);
System.out.println (" Date 2 " + d2 );
d3 = new Date ("April 3 1993 3:24 PM");
System.out.println (" Date 3 " + d3 );
}
}
1.3.3 This
Cours Java 1.1
9
20/11/00
Le mot clef this référence l'instance courante :
t = this.x;
<=> t = x
x variable de la classe de l'instance courante
this.myMethod (this);
<=> myMethod (this)
méthode de la classe appliquée à
l'instance courante
return this;
retourne l'instance courante
1.3.4 Super
Le mot clef super référence la classe parente de la classe courante (précisé au §2) :
Class Auto extends Vehicule
{
public void imprimer ()
{
...
super.imprimer ();
// fait appel à la méthode imprimer
// de la classe Véhicule
1.3.5 Clones
b
An
mois
d
jour
Day b = new Day (1959, 6, 16);
Day d = b;
...
d.advance (100);
// modifie d ET b
Ici, d et b référencent la même instance (le même objet)
Day d = (Day) b.clone ( ); // clone retourne un objet de classe Object => conversion explicite
...
d.advance (100);
// b inchangé
clone est une méthode "protected" de Object => seul une classe ayant accès à la classe Day peut
cloner une instance de la classe Day.
nom : Bond
Agent 007
date naiss :
jour :
nom : berurier
mois :
New 007
date naiss :
ATTENTION ceci effectue un clonage au premier niveau.
Pour réaliser l'équivalent d'un DeepClone de Eiffel (clonage récursif) il faut implanter l'interface
cloneable, redéfinir la méthode clone avec accès "public".
Pour cloner une classe il faut :
Cours Java 1.1
10
20/11/00
la déclarer cloneable :
public class XXX implements Cloneable
{
// toute donnée de base sera clonée par l'appel de super.clone()
// toute donnée qui est une instance de classe doit être clonée en appelant sa méthode clone propre
// qui doit donc être implantée
// Vector possède de base une méthode clone
Vector donnees = new ....;
......
protected Object clone() throws CloneNotSupportedException
{
XXX copie = (XXX)super.clone();
copie.donnees = (Vector)donnees.clone();
return copie;
}
}
1.3.6 Comparaison : equals
La comparaison simple d'instances de classes non prédéfinies, à l'aide de la méthode equals, est
une comparaison de références qui a rarement un sens.
Pour comparer le contenu de deux instances dont les classes ne sont pas prédéfinies, il faut
redéfinir la méthode equals dans la classe dont on veut comparer les instances.
Comme la méthode equals est définie dans la classe Object, elle est connue par toute classe.
1.3.7 instanceOf
instanceOf s'utilise comme une expression booléenne :
"foo" instanceOf String
--> true
Point pt = new Point (10, 10);
pt instanceOf String
--> false
1.4 Contrôle de la visibilité des variables et des méthodes
public : pas de restriction d'accès, une variable ou méthode est visible à toute classe
Variable RW pour toute classe
package : c'est le niveau de protection par défaut. La visibilité est limitée aux classes du
package courant.
Variable RW pour les classes du package
protected : Visible par toutes classes du package courant ET toutes les sous-classes qu'elles
soient ou non du paquetage.
Variable RW pour les classes du package ET toute sous-classe
Cours Java 1.1
11
20/11/00
private : interne à la classe, pour encapsuler les données => méthodes d'accès publique pour
retourner la valeur d'une variable private.
ATTENTION une méthode et une variable d'instance peuvent avoir le même nom, seules les () les
distinguent.
final : le modificateur final
- pour une classe, interdit d'en hériter
- pour une variable, la rend constante
- pour une méthode, interdit de la redéfinir
constantes :
public static final int aConstantInt = 123;
// const de classe
public final String aConstantStrinf = " une chaîne de carac ";
// const d'instance
ATTENTION les méthodes private sont déjà final
1.5 Méthodes
1.5.1 Déclaration de méthodes
contrôle_de_visibilité returnType
{
...
}
Si returnType est un tableau
public int [] moyenneEtudiants
{
...
}
nomMéthode ( [type arg1, ... , type argn])
( groupe notes[])
1.5.2 Mode de transmission des paramètres
Les types données de base sont transmis par valeur.
Par contre les instances passées en paramètres sont transmises par référence et sont donc
susceptibles d'être modifiées si leur contrôle de visibilité le permet.
Exemple :
public class PassByReference
{
public int OneToZero ( int arg [ ] ) // remplace par 0 les 1 trouvés dans un tableau
{
int count = 0;
for ( int i = 0; i < arg.length; i++ )
{
if ( arg[i] == 1 )
{
count = count + 1;
arg[i] = 0;
}
}
return count;
}
// la méthode principale main ( ) teste la méthode OneToZero ( )
public static void main ( String arg [] )
Cours Java 1.1
12
20/11/00
{
int arr [] = {1, 3, 4, 5, 1, 1, 7 };
PassByReference test = new PassByReference ( );
int numOnes;
System.out.print ("Valeurs du tableau : [ " );
for ( int i = 0; i < arr.length; i++ )
{
System.out.print ( arr [i]
+
" ");
}
System.out.println ("]");
numOnes = test.OneToZero ( arr );
System.out.print ("Nombre de 1 = " + numOnes );
System.out.print ("Nouvelles valeurs du tableau : [ " );
for ( int i = 0; i < arr.length; i++ )
{
System.out.print ( arr [i]
+
" ");
}
System.out.println ("]");
}
}
Résultat de l'exécution :
Valeurs du tableau : [ 1 3 4 5 1 1 7 ]
Nombre de 1 = 3
Nouvelles valeurs du tableau : [ 0 3 4 5 0 0 7 ]
1.5.3 Surcharge des méthodes et Constructeurs
Il est possible de surcharger des méthodes, soit dans une même classe, soit dans une classe
héritière qui surchargera alors des méthodes de ses classes parentes.
La surcharge est effective dès lors qu'il y a modification des arguments de la méthode surchargée.
La modification du type retourné par la méthode n'est pas significative et non testée par le
compilateur.
Exemple de surcharge :
import java.awt.Point;
// utilisation de la classe Point qui se trouve dans le Package
awt
class MyRect
{ Point p1, p2;
void buildRect ( int x1, int y1, int x2, int y2 )
{
this.p1.x = x1;
this.p1.y = y1;
this.p2.x = x2;
this.p2.y = y2;
}
void buildRect ( Point topLeft, Point bottomRight )
{
p1 = topLeft;
// affectation de références
p2 = bottomRight;
Cours Java 1.1
13
20/11/00
}
public static void main (String args [] )
{
MyRect
rect = new MyRect ( );
rect.buildRect (20, 30, 40, 50 );
rect.buildRect (new Point (10,10), new Point (20, 20) );
}
}
On peut également surcharger les constructeurs qui allouent la place nécessaire aux variables
d'instance et qui vont également les initialiser, soit avec les valeurs par défaut, soit avec les valeurs
passées en paramètre.
ATTENTION les constructeurs sont des méthodes particulières qui portent toujours le nom de la
classe, sont des procédures (pas de return) et ne précisent pas de contrôle de visibilité.
Class Person
{ String name;
int âge;
On doit au minimum créer un constructeur sans paramètres si on hérite d'une classe dont on doit
appeler le constructeur à la création d'une instance.
Person ([paramètres])
{
super ([paramètres]);
// en supposant que Person hérite d'une classe
}
Person (String s, int a )
{
name = s;
âge = a;
}
Person (String s )
{
name = s;
// l'âge est initialisé par défaut à 0
}
Public static void main (String args [] )
{
Person p1, p2, p3;
p1 = new Person ("Laura", 20 );
p2 = new Person ("Laurie");
p3 = new Person ( );
}
Mais lorsqu'un constructeur d'une classe est appelé, celui de la classe parente doit l'être aussi et
ainsi de suite => ceci afin d'entraîner l'initialisation de toutes les parties héritées de la classe.
Exemple :
class NamedPoint extends Point
{
String name;
NamedPoint ( int x, int y, String n)
{
name = n;
// this.name = n s'il faut lever une ambiguïté
super (x, y);
// appelle le constructeur de la classe Point
}
}
import java.awt.Point;
class MyRect2
Cours Java 1.1
14
20/11/00
{
int x1 = 0;
int x2 = 0;
int y1 = 0;
int y2 = 0;
MyRect2 ( int x1, int y1, int x2, int y2 )
{
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
}
MyRect2 ( Point topLeft, Point bottomRight )
{
x1 = topLeft.x;
y1 = topLeft.y;
x2 = bottomRight.x;
y2 = bottomRight.y;
}
MyRect2 ( Point topLeft, int w, int h )
{
x1 = topLeft.x;
y1 = topLeft.y;
x2 = x1 + w;
y2 = y1 + h;
}
void printRect ( )
{
System.out.print ( "MyRect : <", + x1 + ", " + y1 );
System.out.println ( ", " + x2 + ", " + y2 + ">" );
}
public static void main ( String args [] )
{
MyRect2 rect;
System.out.println ( " Appel de MyRect2 avec les coord -> 25, 25, 50, 50 : ");
rect = new MyRect2 ( 25, 25, 50, 50 );
rect.printRect ( );
... test des autres appels de constructeurs
}
}
1.5.4 Destructeurs [option]
protected void finalize ( )
{ ...
}
Toutes les libérations sont insérées dans le corps de finalize. Cette méthode est appelée par JAVA
quand une instance n'est plus référencée.
Ceci sert à optimiser la destruction d'un objet en simplifiant le travail du garbage collector.
1.5.5 Appel des méthodes
Une méthode déclarée dans une classe s'applique à une instance de cette classe.
Cours Java 1.1
15
20/11/00
La méthode methode1 (déclarée dans la classe Object dont myObject est une instance) peut être
invoquée par l'instruction :
myObject.methode1 (arg1, arg2, ... , argn);
ATTENTION les ( ) sont obligatoires dans le cas où la méthode n'a pas d'arguments.
Si la méthode invoquée renvoie une instance de classe, on peut y appliquer une méthode :
myObject.getClass( ).getName( );
méthode
méthode qui renvoie une instance de classe
instance de classe
class TestString
{
public static void main ( String args [] )
{
String str = "Mieux vaut tard que jamais.";
System.out.println ( "La chaîne est : " + str );
System.out.println ( "Longueur de cette chaîne : " + str.length ( ) );
System.out.println ( "Le caractère en position 5 : " + str.charAt (5) );
System.out.println ("La sous-chaîne 11 à 18 : " + str.substring (11, 18) );
System.out.println ("L'index du caractère d : " + str.indexOf ( 'd' ) );
System.out.println ("L'index du début de la sous-chaîne \"tard\":" +
str.indexOf ("tard") );
System.out.println ("La chaîne en majuscules : " + str.toUpperCase ( ) );
}
}
1.5.6 Méthodes de classe (mot clef static)
Ces méthodes s'appliquent à la classe entière et non aux instances. Elles sont donc utilisables
même sans instances en écrivant :
NomDeLaClasse.methodeAExecuter ([arg, ... arg]);
Exemple : la classe Math qui se trouve dans le Package java.lang. Il n'existe pas d'instance de la
classe Math qui ne contient que des méthodes appliquées à des valeurs numériques ou des
constantes.
float f = Math.sin ( x );
// sin est une méthode de classe et x une valeur
float root = Math.sqrt (453.0);
int
max = Math.max (x, y);
ATTENTION
les affectations entre instances concernent des affectations de références.
On ne peut pas accéder dans une méthode de classe (static) à une
variable d'instance (non static).
Syntaxe de déclaration des méthodes de classes :
public static ty pe
méthode
([args]){...}
type retourné par la méthode
indique que c'est une méthode de classe
indique que la méthode est disponible pour les clients
Exemple de classe qui compte ses instances :
Cours Java 1.1
16
20/11/00
public class InstanceCounter
{ private static int instanceCount = 0;
// var de classe
private static int instanceCount ( )
{
// méthode d'accès à la variable de classe
return instanceCount;
}
private static void incrementCount ( )
{
instanceCount = instanceCount + 1;
}
InstanceCouter ( )
// constructeur
{
InstanceCounter.incrementCount ( );
// incrémente le compteur à la création
}
// finalize à décrémente
}
Les descendants ont accès à instanceCounter, les instances (clients) sont comptées.
1.5.7 Main
public static void
{
...
}
main ( String arg [] )
arguments sous forme de tableau de chaînes de carac
nom obligatoire de la procédure principale
procédure => ne retourne rien
méthode de la classe principale
accessible pour tous
arg permet de récupérer les arguments en ligne de commande :
java nomProgramme
nomFichier 2
rouge
arg[0]
arg[1]
arg[2]
java nomProgramme
"nomFichier 2
rouge"
arg[0]
=> trois arguments
=> un argument
Il faut traiter les arguments pour récupérer les valeurs réelles à partir des chaînes de caractères.
Ex : Integer.parseInt ( arg[i] );
1.6 Exemple
class Motorcycle
{ String make;
String color;
boolean engineState;
// true ou false
void startEngine ()
{
if (engineState == true)
System.out.println (" déjà démarré ");
else
{
engineState = true;
System.out.println (" démarrage OK ");
}
}
void showAtts ()
{
System.out.println ("affichage du véhicule " + make + color ");
Cours Java 1.1
17
20/11/00
if (engineState == true)
System.out.println (" moteur tourne ");
else
System.out.println (" moteur arrêté ");
}
}
La compilation se fait à l'aide de la commande suivante :
javac Motorcycle.java
Il est nécessaire d'avoir une méthode main () pour toute application, sinon on aura l'erreur
suivante:
class Motorcycle : void main (String argv []) is not defined.
Aussi on va rajouter la méthode main dans la classe Motorcycle :
public static void main (String argv [] )
{ // création d'un nouvel objet de la classe Motorcycle et
// stockage de sa référence dans la variable m
Motorcycle m = new Motorcycle ();
// new = constructeur
m.make = "yamaha 500";
m.color = "yellow";
// initialisation des variables d'instances
System.out.println (" appel de showAtts ");
m.showAtts ();
System.out.println (" démarrage du moteur ");
m.starEngine ();
System.out.println (" appel de showAtts ");
m.showAtts ();
System.out.println (" démarrage du moteur ");
m.starEngine ();
// affichage de l'état de m
// changement d'état
// réaffichage de l'état de m
// redémarrage => message
}
2. Héritage (mot clef extends)
Hiérarchie de classes :
a
b
Super classe de b (classe parente,
ancêt re de b)
Sous classe de a (héritière, descendante)
Les sous classes héritent de toutes les méthodes et variables de leurs super classes.
Une classe héritière b "est" un a dans le cas d'un héritage de classification sinon, c'est un héritage
de construction (cf TD).
La classe Object se trouve à la hiérarchie des classes JAVA. Toutes les classes en héritent. C'est
la classe la plus générale.
Généralement, plus une classe est basse dans la hiérarchie, plus elle est spécialisée.
Cours Java 1.1
18
20/11/00
Si une classe est réellement nouvelle et n'hérite pas d'un comportement au travers d'une autre
classe, elle va hériter directement (implicitement) de la classe Object et sera ainsi intégrée dans la
hiérarchie des classes JAVA (ex. La classe Motorcycle).
Dans ce cas l'héritage n'est pas spécifié.
Toute modification de classe dans une hiérarchie est répercutée dans toutes les classes héritières.
La création de classe est justifiée pour :
- regrouper toutes les informations communes dans une classe parente
- minimiser les modif. à apporter lors de chaque héritage par rapport a la classe parente.
Objet
Ancetre de toute classe
Marque
Couleur
Mode de propulsion
Véhicule
V à moteur
V sans moteur
Cy lindrée
2 roues
Moto
Scooter
4 roues
Mob
Voiture
Vélo
Sulky
Bus
Le "new" attribue un emplacement pour chaque variable définie dans la classe courante et toutes
ses classes parentes.
L'instance à accès à toutes les méthodes de la hiérarchie. La méthode à exécuter est choisie
dynamiquement dans la hiérarchie au moment de l'appel.
Si deux méthodes dans la hiérarchie ont la même signature (même profil), JAVA exécute la
première trouvée en partant de la classe même en en remontant dans les classes parentes =>
!! On peut définir dans une sous classe une méthode avec la même signature que celle d'une classe
parente sans conflit (redefine automatique /= Eiffel).
2.1 Héritage simple
Dans JAVA seul l'héritage simple est possible.
Le concept d'Interface permet de pallier les inconvénients dus à l'héritage simple en permettant
de préciser le comportement d'une classe là où l'héritage lui a conféré sa structure.
2.2 Conversion de types
La conversion de int -> long est implicite (rien à préciser) par contre
la conversion de long -> int doit être explicite => if ( z < (int) (x/y) ) { ...}
2.3 Conversion d'objets (typage dynamique)
Cours Java 1.1
19
20/11/00
A
B
A
B
C
D
aA;
bB;
aA = bB;
// implicite
bB = (B) aA; // à expliciter
if ( aA instanceOf B) {bB = (B) aA;}
Classe
instance
Pour transformer un
type de base en classe, il faut utiliser les classes correspondantes aux types de base. Par exemple la
classe Integer correspond au type de base int et peut s'utiliser ainsi :
Integer
int Objet = new Integer (35);
L'initialisation retourne une référence à une zone mémoire allouée correspondant à un Integer qui
sera affectée à l'instance intObjet de la classe Integer.
Dans l'autre sens on peut écrire :
int
entier = intObjet.intValue ( );
// retourne la valeur 35 qui est affectée à entier
int
count = Integer.parseInt ( "42", 10 ); // renvoie la chaîne transformée en décimal
2.4 Polymorphisme - Redéfinition
Une classe héritière déclarant une méthode de même nom qu'une classe parente a deux
possibilités:
- il y a modification des arguments de la méthode et c'est une surcharge au sens ADA,
- il n'y a pas modification des arguments et c'est une redéfinition au sens Objet.
Le polymorphisme a lieu quand des classes héritières d'une classe parente redéfinissent une
méthode de la classe parente.
Si on désire appeler la méthode de la classe parente dans la méthode redéfinie de la classe
héritière, il faut placer devant le mot clef super :
void myMethod ( type a, type b )
{
...
super.myMethod ( a, b );
// exécutera la méthode de la classe parente
...
}
Dans le cas des constructeurs (qui portent le nom de la classe), ils sont hérités mais ne peuvent
être redéfinis.
3. Méthodes et classes abstraites
Une classe abstraite ne peut pas être instanciée.
Ex :
public abstract class X
// classe abstraite
{ int varInt;
public abstract int methodeAbstraite ([args] ); // doit être implantée par un descendant
public void methodeNormale ([args] ) // déjà définie, peut être redéfinie
{ ...;
}
}
Cours Java 1.1
20
20/11/00
public class Y extends X
{
public int methodeAbstraite ([args] )
{
...
}
}
4. Exceptions
La notion de programmation par contrat n'existe pas et doit être implantée avec les moyens
disponibles, notamment les exceptions.
4.1 Hiérarchie de classes exception
Les exceptions sont toutes dérivées de la classe Throwable :
Throwable
internal error
Exception
/= des exceptions car on
ne peut pas les lever
IOException
Runtime
Exception
null pt access
out of bounds access
bad cast ....
Classification des types d'erreurs
Toute classe exception dérivée de Throwable supporte un constructeur par défaut (sans
paramètres) et un constructeur avec un message de type String en paramètre.
4.2 Créer une nouvelle classe exception
class MyEx extends IOException
// ou toute autre classe dérivée d'Exception
{
public MyEx ( )
{
...
}
public MyEx (arg1 a1, arg2 a2, ...)
{
...
}
}
if (cond)
{
throw new MyEx ( );
}
4.3 Récupérer une exception
Cours Java 1.1
21
20/11/00
try
{
code à exécuter susceptible de lever une exception
}
catch (TypeException nomException)
{
traitement de l'exception
}
catch (AutreTypeException nomException)
// pour tester une autre exception
{
traitement
}
4.4 Debugger
try
{
...
}
catch (Throwable t )
{
t.printStackTrace ( ); // permet d'afficher l'état de la pile d'exécution
throw t;
// pour répercuter l'erreur
}
4.5 Lever une exception
Il y a 4 façons de lever une exception :
- volontairement
- par appel d'une méthode qui en lève une
- programming error
- erreur interne JAVA
On ne lève pas soi-même une run time error (erreur d'exécution).
Une méthode qui est une redéfinition d'une méthode parente ne peut pas lever plus d'exceptions
que sa méthode parente.
Pour lever une exception :
IOException ioe = new IOException ( );
...
throw ioe;
// cela suffit car elle est déclarée et crée avant
throw new MyEx ( );
// pas crée avant : il faut le faire "sur place"
4.6 La clause throws
Toute méthode qui est susceptible de lever une exception elle même ou par appel d'une méthode
susceptible d'en lever une doit :
- soit gérer l'exception dans son code par l'emploi des clauses (try catch),
- soit indiquer dans son entête qu'elle est susceptible de transmettre une ou plusieurs
exceptions à l'appelant :
public String readLine ( ) throws IOException, AutreException, ...
{ ... }
Pour ne pas traiter une exception levée :
Cours Java 1.1
22
20/11/00
• Une application appelle une méthode susceptible de transmettre une exception (methodeB
appelle methodeA () Throws TypeExceptionQuelconque).
• Pour ne pas traiter cette exception, methodeB doit également préciser dans son entête :
Throws TypeExceptionQuelconque.
• Ceci doit être effectué par toutes les méthodes appelantes et ce en remontant jusqu'au Main.
Le traitement explicite de l'exception est OBLIGATOIRE pour les IOException à traitement
explicite, mais implicite pour les Runtime ERROR.
4.7 La clause finally
Exemple :
Graphics g = image.getGraphics ( );
try
{
code sur g
}
catch (IOException e)
{
done = true; // par exemple
}
finally
{
g.dispose ( );
// libération du graphic context
}
Que le code soit ou non exécuté, le code associé à la clause finally sera exécuté. Ici le graphic
context sera libéré quelles que soient les circonstances.
Code try
pas d'exception
exception
finally
géré par catch
pas géré par un catch
suite d'exec du bloc
code du catch
finally
throw une exception
dans la partie catch
pas de throw
finally
finally
renvoie du throw
à l'appelant
suite d'exec du bloc
renvoie du throw
à l'appelant
5. Input / Output
Les opérations d'entrée sont toutes définies à partir de deux classes abstraites : InputStream et
Reader.
InputStream permet de lire un flux d'octets provenant d'une source quelconque et Reader un flux
de caractères.
De la même manière, les sorties sont effectuées à partir de deux classes abstraites : OutputStream
et Writer.
Deux exemples concrets sont fournis : entrées/sorties clavier-écran et dans un fichier.
Pour plus de précision, se reporter à java.io et aux nombres classes spécialisées qui s'y trouvent.
5.1 Affichage à l'écran
Cours Java 1.1
23
20/11/00
La classe System possède le stream de sortie standard appelé simplement : out.
Il est possible d'afficher directement toute variable d'un type de base en le passant en paramètre de
la fonction print ou println (passage à la ligne après affichage).
Pour un objet, l'affichage peut être effectué grâce à la méthode toString () définie dans la classe
Object. Si la méthode ne convient pas il faut la redéfinir dans la classe que l'on désire afficher. Toute
classe héritant de la classe Object, l'affichage d'une structure polymorphe se fera sans problème.
Pour afficher avec un seul appel plusieurs entités, il faut les préciser, dans l'ordre d'affichage,
simplement séparées par un + (symbole de concaténation).
System.out.print ("un certain texte " + unEntier + " ou " + unFloat + " ou " + unObjet.toString ());
5.2 Lecture au clavier
Illustré à partir d'un exemple qui montre l'usage que l'on peut faire des classes de java.io et
java.lang.System.
La classe System possède le stream d'entrée standard appelé simplement : in.
Il est utilisé pour instancier la classe InputStreamReader qui va récupérer les entrées clavier.
L'instance ainsi créée (bien que n'ayant pas été stockée dans une variable d'instance) va être
utilisée pour créer une instance de BufferedReader qui va stocker dans un buffer les entrées clavier.
Il est possible de créer une instance "virtuelle", dont la référence n'est pas stockée pour être
ensuite explicitement libérée, grâce au garbage collector qui assure la libération de la place mémoire
allouée dès que la référence n'est plus utilisée (!!à ne pas faire en C++!!).
import java.io.* ;
import java.lang.*;
public class lecture
{
public static void main(String[] args)
// la méthode main est susceptible d'avoir à transmettre une exception de type IOException
// qu'elle ne va pas récupérer pour la traiter elle même. Elle doit donc le signaler.
throws java.io.IOException
{
// L'instance myInput sait lire au clavier et stocker les informations lues.
// pour pouvoir lire au clavier, il faut instancier l' InputStream avec System.in
// (entrée standard) et instancier BufferedReader avec l' InputStream pour
// pouvoir saisir plus d'un caractère.
BufferedReader myInput=new BufferedReader(new InputStreamReader(System.in));
// Toute saisie est stockée dans un String.
String c=new String();
// Résultat final souhaité pour la saisie.
int resultat = 0;
float autre = 0;
// Programme de lecture, version explicite : à préférer
// récupération de l'entrée clavier dans un String qui sert ici de buffer d'entrée
c = myInput.readLine();
// la chaîne est convertie en Integer (instance de la classe prédéfinie Integer)
// dont on extrait ensuite la valeur entière de type de base int
resultat = Integer.valueOf(c).intValue();
// récupération de l'entrée clavier dans un String qui sert ici de buffer d'entrée
Cours Java 1.1
24
20/11/00
c = myInput.readLine();
// la chaîne est convertie en Float (instance de la classe prédéfinie Float)
// dont on extrait ensuite la valeur réelle de type de base float
autre = Float.valueOf(c).floatValue();
// DEBUG : affichage du résultat pour contrôle
System.out.println("resultat " + resultat + " " + autre);
// Programme de lecture version condensée, pas toujours souhaitable.
resultat = Integer.parseInt(myInput.readLine());
autre = Float.valueOf(myInput.readLine()).floatValue();
// DEBUG : affichage du résultat pour contrôle
System.out.println("resultat " + resultat + " " + autre);
}
}
5.3 Entrées/Sorties dans un fichier
Démonstration par l'exemple :
Voici une classe qui va écrire dans un fichier une structure de données (ici une liste implantée
dans un Vector) et la récupérer.
import java.io.*;
public class ListeStockable extends Liste // implantée à partir d'un Vector
{
// constructeur
ListeStockable ()
{
super ();
}
// pour écrire une liste dans un fichier
public void writeOnFile (String dest_name)
throws IOException
{
File destination_file = new File(dest_name); // création du fichier d'écriture
FileOutputStream ostream = null;
// déclaration du flux de sortie dans un fichier
ObjectOutputStream oos;
// déclaration du flux de sortie d'un Object
int j;
try
{
if (destination_file.exists())
{
if (destination_file.isFile())
{
// pour l'entrée au clavier de la réponse
BufferedReader myInput =
new BufferedReader(new InputStreamReader(System.in));
String reponse = new String ();
Cours Java 1.1
25
20/11/00
if (!destination_file.canWrite())
throw new FileRWException("FileCopy: fichier destination " +
"inaccessible en écriture: " + dest_name);
System.out.print("Fichier " + dest_name +
" déjà existant. Peut-on écraser son contenu ? (Y/N): ");
System.out.flush();
reponse = myInput.readLine();
if (!reponse.equals("Y") && !reponse.equals("y"))
throw new FileRWException("FileCopy: fichier écrasé.");
} else
throw new FileRWException("FileCopy: destination "
+ "n'est pas un fichier: " + dest_name);
}
// Tout est ok, on peut écrire dans le fichier
// on ouvre le flux d'écriture dans le fichier
ostream = new FileOutputStream(destination_file);
// on précise que les données seront des Object
oos = new ObjectOutputStream(ostream);
for (j=0 ; j < taille ; j++)
// on écrit les Object dans le fichier un après l'autre
oos.writeObject(ith(j));
// placer dans le fichier un Object null pour signaler la fin
oos.writeObject(null);
}
// Quoiqu'il arrive, toujours fermer le fichier
finally
{
if (ostream != null)
try { ostream.close(); } catch (IOException e) { ; }
}
}
// pour lire une liste depuis un fichier
public void readFromFile (String source_name)
throws IOException, ClassNotFoundException
{
File source_file = new File(source_name); // création du fichier en lecture
FileInputStream istream = null;
// déclaration du flux d'entrée depuis un fichier
ObjectInputStream ois;
// déclaration du flux d'entrée d'un Object
int j;
Object t;
boolean termine = false;
try
{
// le fichier en lecture existe t'il avec les bons droits d'accès
if (!source_file.exists() || !source_file.isFile())
throw new FileRWException("FileCopy: fichier source inexistant: " +
Cours Java 1.1
26
20/11/00
source_name);
if (!source_file.canRead())
throw new FileRWException("FileCopy: fichier source non accessible en lecture " +
source_name);
// tout est OK on peut lire le fichier
// ouverture du flux d'entrée depuis le fichier
istream = new FileInputStream(source_file);
// on précise que les données lues seront des Object
ois = new ObjectInputStream (istream);
while (!termine)
{
t = ois.readObject();
if (t == null)
termine = true;
else
putLast(t);
}
}
// toujours fermer le fichier
finally
{
if (istream != null)
try { istream.close(); } catch (IOException e) { ; }
}
}
}
// permet de créer sa propre exception accompagnée d'un message
class FileRWException extends IOException
{ public FileRWException(String msg) { super(msg); } }
ATTENTION : la sauvegarde d'instances de classes ne résout pas un problème complexe qui est
illustré par l'exemple suivant :
Employé
Le manager est un employé
La secrétaire également
Manager
Secrétaire
Employé
Staff
Manager
Secrétaire
...
Manager
Secrétaire
Cours Java 1.1
27
20/11/00
Après sauvegarde sur disque et restauration de la structure, on constate qu'une instance de
secrétaire a été crée pour chaque manager alors qu'il s'agit en fait de la même personne.
Staff
Employ é
Miss Hacker
Manager
Secrétaire
Employ é
Miss Hacker
....
Manager
Secrétaire
Employé
Miss Hacker
Comme Miss Hacker ne doit pas avoir le don d'ubiquité, il faut modifier les méthodes pour
pouvoir restaurer la structure telle qu'elle était au départ.
Ce concept de persistance permet d'assurer qu'aucun duplicata non désiré d'instance ne sera crée.
Une méthode "bricolée" permet d'arriver au bon résultat :
1_ Lors de la sauvegarde sur disque, numéroter les objets enregistrés grâce à un label.
2_ Vérifier avant de sauvegarder si l'objet n'a pas déjà été stocké.
3_ Si c'est le cas, remplacer l'objet par un indicateur suivi de son label.
Ce stockage fait en sorte de ne stocker les instances qu'une seule fois et de faire référence au
numéro d'ordre chaque fois qu'une référence vers une instance déjà stockée est détectée.
Lors de la restauration, il faudra rétablir les références vers les instances à la place des labels
stockés sur disque.
Pour implanter le concept de persistance, il faut attendre le concept d'objet transient qui ne sera
pas disponible dans la version 1.1 de java.
6. Packages
Les classes de base de JAVA sont organisées en Packages et on trouvera en particulier le Package
awt qui contient toutes les classes graphiques servant à construire des interfaces utilisateurs.
Une classe désirant utiliser ce Package devra déclarer :
import java.awt.Button;
ou encore
import java.awt.*; // pour importer toutes les classes de awt, utile si on en utilise plusieurs
class useAwt
{ Button b;
// classe présente dans awt
...
}
Les Packages permettent la conception de groupes de classes et d'interfaces. Ainsi on peut limiter
l'accès à des groupes de classes explicitement désignés. Ceci a l'avantage d'éviter des conflits sur les
noms de classes. Des classes appartenant à différents Packages peuvent ainsi avoir le même nom
pour éviter d'avoir à rallonger inutilement les noms de classes avec comme seul but de lever les
ambiguïtés.
L'autre avantage plus classique étant d'effectuer des regroupements thématiques afin d'aider à la
recherche d'informations dans les bibliothèques de classes.
Cours Java 1.1
28
20/11/00
Les Packages permettent donc de regrouper et d'organiser hiérarchiquement des classes.
Il faut pour cela utiliser un fichier par classe.
Avant l'entête des classes du package PackX écrire :
package PackX;
public class ClasseY
{ ...
}
Les classes du même Package sont à mettre dans le même répertoire.
Pour créer une hiérarchie de Packages il faut créer une hiérarchie de répertoires équivalents dont
la racine est le répertoire des classes.
PACK1
PACK2
HOME
REP1
REP2
JAVA
cl1.java
cl2.java
cl3.java
PACK3
PACK4
PACK5
Toutes les classes situées dans le répertoire PACK2 déclarent avant leur entête :Package PACK2;
Pour simplifier l'accès à un élément, on positionne une variable d'environnement appelée
CLASSPATH qui précisera le chemin d'accès jusqu'au répertoire JAVA, sous lequel on doit trouver
tous les répertoires contenant les Packages propres du développeur.
Exemple :
Pour mettre en place les 'package', on suppose les fichiers suivants :
/home/xxx/JAVA/TP1/PointND.java
/home/xxx/JAVA/TP1/Comparable.java
/home/xxx/JAVA/TP2/Ensemble.java
/home/xxx/JAVA/TP2/EnsembleComparable.java
/home/xxx/JAVA/TP2/Main.java
1) Modifier le fichier .env.csh en ajoutant la ligne suivante :
setenv CLASSPATH .:/home/xxx/JAVA
Attention, une erreur ici et rien ne marche !!!
2) sauver et taper :
source .env.csh pour re-exécuter le .env.csh
3) les fichiers qui sont dans TP1 doivent déclarer être dans un package et mettre en première ligne :
package TP1;
donc le package s'appelle TP1.
4) le Main et EnsembleComparable doivent importer les classes du package TP1 :
import TP1.*;
Attention : Le Main ne doit pas se trouver dans un répertoire d'où il importe des classes.
Ainsi, si Ensemble et EnsembleComparable déclarent faire partie du package TP2 et que le main
importe les classes des packages TP1 et TP2, il devra donc se situer hors de ces deux packages, dans
un autre répertoire.
Cours Java 1.1
29
20/11/00
7. Interfaces (mot clef implements)
Une Interface (au sens JAVA et non IHM) est une collection de descriptions (signatures) de
méthodes sans implantations (deffered). Elle propose un modèle de comportement (ex. Cloneable).
Les Interfaces sont déclarées dans des fichiers sources, à raison d'une Interface par fichier.
Une classe hérite d'une seule classe parente mais n'est pas limitée en nombre d'Interfaces qu'elle
peut utiliser.
Une Interface ne peut être instanciée.
Exemple de création d'interface :
package XXX;
public interface interf extends int1, int2 ... ; // "héritage" d'interfaces
{
// toutes les méthodes sont public abstract
// toutes les variables sont public ou static ou final
...
}
Exemple :
public interface sortable
{ public int compare (sortable a);
}
class window extends rectangle /* héritage simple */ implements sortable;
{
public int compare (sortable a)
// retourne -1 0 ou 1 selon < = ou >
{window wa = (window) a;
if (z /* le courant */ < wa.z)
{....}
else
{....}
}
public static main ( String args [] )
{
window w1 = new window (...);
window w2 = new window (...);
if (w1.compare (w2) < 0 )
{...}
...
}
8. AWT et gestion des événements
Les événements du type "java.awt.WindowEvent" permettent de prendre en compte les actions
que l'utilisateur réalise sur une fenêtre. Ainsi, la sélection de la case Quit dans le menu ajouté par le
window manager à chaque fenêtre entraîne un appel de la méthode "void
windowClosing(WindowEvent e)" du WindowListener déclaré pour cette fenêtre.
La fonction System.exit(code) permet de quitter la machine virtuelle java en retournant le code
spécifié au shell.
Cours Java 1.1
30
20/11/00
Les événements du type "java.awt.event.KeyEvent" permettent de prendre en compte les actions
réalisées au clavier. Ainsi, lorsqu'on tape sur une touche du clavier, le focus étant sur un composant
implantant l'interface "java.awt.event.KeyListener", les méthodes suivantes sont appelées (dans
l'ordre) :
public void KeyPressed (KeyEvent e) : lors d'un appui sur la touche.
public void KeyTyped (KeyEvent e) : lors d'une suite appui-relaché sur la touche.
public void KeyReleased (KeyEvent e) : lors du lâché de la touche.
Les événements du type "java.awt.event.MouseEvent" permettent de gérer les actions souris sur
le composant implantant l'interface "java.awt.event.MouseListener". Les méthodes suivantes sont
définies pour cette interface :
public void mouseClicked (MouseEvent e) : lors d'un click souris
public void mousePressed (MouseEvent e) : lors de l'appui sur un bouton de la souris
public void mouseReleased (MouseEvent e) : lors du relâchement d'un bouton de la souris
public void mouseEntered (MouseEvent e) : lors de l'entrée de la souris sur le composant
public void mouseExited (MouseEvent e) : lors de la sortie de la souris sur composant
8.1.1 Identification du bouton cliqué
Exemple :
public void moussePressed (MouseEvent e)
{
// click sur le bouton droit
if ((e.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK) != 0)
{
// action à effectuer quand bouton droit cliqué
} else
{
if ((e.getModifiers() & java.awt.event.InputEvent.BUTTON2_MASK) != 0)
{
// action à effectuer quand bouton du milieu cliqué
} else
{
// action à effectuer quand bouton gauche cliqué
}
}
8.2 Version simple
Illustration par un exemple : Prise en compte des événements clavier :
Cette prise en compte doit être effectuée par la mise en place des éléments suivants :
// Classe définissant les événements clavier
import java.awt.event.KeyEvent;
// interface permettant la mise en œ uvre des sous-programmes de récupération des
// événements.
import java.awt.event.KeyListener;
Cours Java 1.1
31
20/11/00
// classe mise en oeuvre
classX implements KeyListener
{
// constructeur
X (… )
{
…
// permet de préciser que la classe attend les entrées clavier
this.addKeyListener(this);
}
// Implantation de toutes les méthodes abstraites définies dans KeyListener
public void keyTyped (KeyEvent e)
{
//any key
}
public void keyReleased (KeyEvent e)
{
}
public void keyPressed (KeyEvent e)
{
switch(e.getKeyCode())
{…
// pour que le parent puisse informer le window manager de la destruction
// demandée de la fenêtre
case java.awt.event.KeyEvent.VK_ESCAPE :
…
// dans le cas où on récupère l'événement dans une fenêtre qui
// est fille de la fenêtre principale de l'application (seule connue du
// window manager), il faut la transférer pour quitter proprement
// l'application
WindowEvent we = new WindowEvent ((Window) getParent(),
java.awt.event.WindowEvent.WINDOW_CLOSING);
getParent().dispatchEvent(we);
break;
case …
}
}
}
8.3 Version complète (plus complexe)
Le traitement des événements est séparé en deux parties :
- l'objet qui souhaite recevoir un événement donné,
- le récepteur d'événement (Listener).
Un récepteur d'événement est affecté à un certain ensemble d'événements (un pour la souris, un
pour le clavier ...) et doit déclencher des actions en réponse aux événements.
Le code de traitement de l'événement est placé dans le récepteur.
En fait il doit s'agit de l'appel d'une fonction de callback, déclarée dans la classe souhaitant
récupérer l'événement.
Cours Java 1.1
32
20/11/00
Exemple :
import java.awt.*;
public class Fenetre extends Frame {
// attributs
protected Panel centerPanel; // panel : structure qui contient le canvas de tracé
protected MyCanvas canvas; // pour tracer et récupérer des événements
// event adaptor : on declare une instance de la classe
// qui servira à indiquer que le canvas souhaite recevoir les événements
// de type "intéraction à l'aide de la souris"
protected MouseAdaptator mouseAdaptator;
// même chose avec les entrées clavier
protected KeyAdaptator keyAdaptator;
// constructeur
public void Fenetre ()
{ super();
// appel du constructeur de la classe parente
centerPanel = new Panel(); // création du panel et du canvas
canvas = new MyCanvas ();
// on place le canvas dans le panel
centerPanel.setLayout(new GridLayout (1,1));
// 1 ligne 1 colonne
centerPanel.add(canvas);
// le canvas est placé dans la première colonne
this.add("Center", centerPanel);
// la fenêtre contient le panel centré
// il faudrait le faire relativement à la taille de la fenêtre
canvas.setSize(380, 240);
// taille du canvas
canvas.setVisible(true);
// qui sera visible
// ----------> lien entre événement et canvas : réception des événements souris
mouseAdaptator = new MouseAdaptator();
canvas.addMouseListener(mouseAdaptator);
// ----------> lien entre événement et canvas : réception des entrées clavier
keyAdaptator = new KeyAdaptator();
canvas.addKeyListener(keyAdaptator);
show ();
// affichage de la fenêtre
} // Fenêtre
// modification de la structure de données qui contient les points définissant le tracé
public void changerPoints (Point2D tabp [][], int nbPoints, int nbInscrits)
{
// stockage des points décrivant le tracé dans le tableau de points
canvas.setPoints (tabp, nbPoints, nbInscrits);
} // changerPoints
//--------------------------------------------------------------------// la suite du code est liée à la gestion des événements relatifs
// à la Fenêtre
//--------------------------------------------------------------------// mise en correspondance de la fonction de callback (focus) avec
// un événement (événement lié à la souris)
Cours Java 1.1
33
20/11/00
class MouseAdaptator implements java.awt.event.MouseListener
{
// ici on choisit de ne traiter que l'événement "bouton enfonce"
public void mousePressed(java.awt.event.MouseEvent event)
{
focus(event);
}
// ceux non utilisés doivent être quand même implantés même vides
// sinon la classe serait abstraite
public void mouseClicked(java.awt.event.MouseEvent event) {}
public void mouseReleased(java.awt.event.MouseEvent event) {}
public void mouseEntered(java.awt.event.MouseEvent event) {}
public void mouseExited(java.awt.event.MouseEvent event) {}
} // MouseAdaptor
// mise en correspondance de la fonction de callback (exit) avec
// un événement (événement lié à une entrée clavier)
class KeyAdaptator implements java.awt.event.KeyListener
{
public void keyPressed(java.awt.event.KeyEvent event)
{
exit(event);
}
// ceux non utilisés doivent être quand même implantés même vides
// sinon la classe serait abstraite
public void keyTyped(java.awt.event.KeyEvent event) {}
public void keyReleased(java.awt.event.KeyEvent event) {}
} // KeyAdaptor
// fonctions de callback qui seront appelées quand un événement aura lieu
// dans la fenêtre
// on quitte avec la touche ESCAPE
public void exit (java.awt.event.KeyEvent event)
{
// si le code stocké dans la sdd de l'événement correspond
// à la touche ESCAPE alors on quitte l'application
if(event.getKeyCode() == java.awt.event.KeyEvent.VK_ESCAPE)
// tout code nécessaire pour quitter proprement doit être
// inséré ici
System.exit(0);
} // exit
// on provoque un réaffichage avec un click de souris
//(non nécessaire ici : créée juste pour tester)
public void focus (java.awt.event.MouseEvent event)
{
canvas.repaint();
} // focus
Cours Java 1.1
34
20/11/00
} // Fenêtre
La trame de la classe MyCanvas pouvant être la suivante :
import java.awt.*;
class MyCanvas extends Canvas {
// attributs
// stockage des sommets des segments à tracer
public Point2D tabp [ ][ ];
// constructeur
MyCanvas ()
{}
// modification du tableau contenant les sommets des segments à tracer
public void setPoints ( Point2D tabPoints [ ] [ ],
int nbPoints,
int nbInscrits)
{ // récuperation des points à tracer}
public void paint(Graphics g) // contexte graphique
{ // tracé des segments indiqués par les points stockés dans tabp}
}
9. Threads
Multithreading = multitâche en parallèle dans un seul programme.
4 modifications sont à apporter à une applet :
1_ elle doit implanter l'interface Runnable
2_ ajouter une variable d'instance pour recevoir le thread
3_ modifier la méthode strart ( ) pour limiter son rôle au lancement d'un thread
4_ créer une méthode run ( )
Exemple :
class xxx extends java.applet.Applet implements Runnable
{
Thread runner;
// de java.lang ( de base )
public void start ( )
// active le thread runner
{
if ( runner == null )
{
runner = new Thread ( this );
runner.start ( );
}
else if ( runner.isAlive ( ) )
{
runner.resume ( );
}
public void stop ( )
// suspend le thread quand la page est quittée
{
if ( runner != null && runner.isAlive ( ) )
{
runner.suspend ( );
}
}
Cours Java 1.1
35
20/11/00
public void destroy ( )
{
...
// idem stop quand le browser est quitté
}
}
public class MC extends java.applet.Applet implements Runnable
{
Thread runner;
// de java.lang ( de base )
public void strart ( )
{
// crée et démarre le thread
if ( runner == null )
{
runner = new Thread ( this );
runner.start ( );
}
}
// le corps de l'applet doit être mis dans une méthode run
public void run ( )
{
// tout ce qui doit s'exécuter dans le thread
}
public void stop ( )
{
if ( runner != null )
{
runner.stop ( );
runner = null;
}
}
10. Exemple
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
// ou écrire import java.awt.*;
public class HelloAgainApplet extends java.applet.Applet;
// classe parente
// Package
classe
// public obligatoire pour les applets => visible pour les classes du programme JAVA
{
Font f = new font ("TimesRoman", Font.Bold, 36);
// instance de la classe Font de java.awt
public void Paint (Graphics g)
// classe qui fournit des comportement de tracé
{
g.setFont (f);
// police par défaut
g.setColor (Color.red);
// classe Color, couleur définie pour g
g.drawString ("Hello again", 5, 50);
// pos en x et en y dans la fenêtre
}
}
La méthode paint est abstract et définie dans Applet. Si on souhaite l'utiliser il faut donner son
implantation. Elle est public car déclarée comme cela dans Applet.
Pour exécuter une Applet il faut ensuite créer un fichier .html
Cours Java 1.1
36
Téléchargement