I. Introduction à Java▲
I-A. Apparition du langage▲
Vers la fin de 1995, le langage de programmation Java surgit sur la grande scène d'Internet et obtient immédiatement un énorme succès. La prétention de Java est de constituer la colle universelle capable de connecter les utilisateurs aux informations, que celles-ci proviennent de serveurs Web de bases de données, de fournisseurs d'informations ou de toute autre source imaginable. Et Java se trouve en bonne position pour accomplir ce pari. Il s'agit d'un langage de conception très performant qui a été adopté par la majorité des fournisseurs. Ses caractéristiques intégrées de sécurité offrent un sentiment de confiance au programmeur comme aux utilisateurs des applications. De plus, Java incorpore des fonctionnalités qui facilitent grandement certaines tâches de programmation avancées comme la gestion des réseaux, la connectivité des bases de données ou le développement d'applications multitâches.
La réputation de Java en tant que langage informatique est exagérée : Java est assurément un bon langage de programmation. Il s'agit, sans aucun doute, de l'un des meilleurs disponibles pour un programmeur sérieux. Java aurait, potentiellement, pu être un grand langage de programmation, mais il est probablement trop tard pour cela. Lorsqu'un langage commence à être exploité se pose le problème de la compatibilité avec le code existant. De plus, même lorsque des modifications sont possibles sans révolutionner le code existant, il est très difficile pour les créateurs d'un langage qui a suscité autant d'intérêt de reconnaître qu'un élément x pourrait être plus mauvais ou meilleur qu'un élément y. Même si nous espérons une amélioration de Java avec le temps, sa structure de demain restera, à la base, très proche de celle d'aujourd'hui.
I-B. Les avantages de Java▲
L'un des avantages évidents de ce langage est une bibliothèque d'exécution qui se veut indépendante de la plate-forme : en théorie, il vous est possible d'utiliser le même code pour Windows 95/98/NT, Solaris, UNIX, Macintosh, etc. Cette propriété est indispensable pour une programmation sur Internet (cependant, par rapport à la disponibilité sur Windows et Solaris les implémentations sur d'autres plates-formes ont toujours un léger décalage).
Un autre avantage de ce langage de programmation réside dans le fait que la syntaxe de Java est analogue à celle de C++ ce qui le rend économique et professionnel.
Le fait de créer une autre version d'un langage C++ n'est cependant pas suffisant. Le point clé est le suivant : il est beaucoup plus facile d'obtenir du code sans erreur à l'aide de Java qu'avec C++. Pourquoi ? Les concepteurs de Java ont beaucoup réfléchi à la raison pour laquelle le code C++ contenait autant d'erreurs. Cette réflexion les a amenés à ajouter dans Java des fonctions destinées à éliminer la possibilité de créer du code contenant les types d'erreurs les plus courants (selon certaines estimations, le code C++ contient au moins une erreur toutes les cinquante lignes).
- Les concepteurs de Java ont supprimé l'allocation et la libération de mémoire manuelles. La mémoire dans Java est allouée et libérée automatiquement. Vous n'avez jamais à vous préoccuper de pertes de mémoire.
- Ils ont éliminé l'arithmétique des pointeurs introduisant du même coup une vraie gestion de tableau. La notion de référence sur une zone mémoire remplace avantageusement celle de « pointeur », car elle supprime la possibilité d'écraser toute zone mémoire à cause d'un compteur erroné.
- Ils ont éliminé toute possibilité de confusion entre une affectation et un test d'égalité dans une instruction conditionnelle. Une instruction if (ntries - 3) ne pourra pas franchir l'étape de la compilation.
- Ils ont supprimé l'héritage multiple en le remplaçant par une nouvelle notion d'interface dérivée d'Objective C. Les interfaces vous offrent tout ce que vous pouvez obtenir à partir de l'héritage multiple, sans la complexité de la gestion de hiérarchie d'héritage multiple.
I-C. Caractéristiques▲
Les créateurs de Java ont écrit un livre blanc qui présente les caractéristiques fondamentales de Java. Ce livre est articulé autour des 11 termes suivants :
- Distribué
Java possède une importante bibliothèque de routines permettant de gérer les protocoles TCP/IP tels que HTTP et FTP. Les applications Java peuvent charger et accéder à des fichiers sur Internet via des URL avec la même facilité qu'elles accèdent à un fichier local sur le système.
« Nous avons trouvé que les fonctionnalités réseau de Java sont à la fois fiables et d'utilisation aisée. Toute personne ayant essayé de faire de la programmation pour Internet avec un autre langage se réjouira de la simplicité de Java lorsqu'il s'agit de mettre en œuvre des tâches lourdes, comme l'ouverture d'une connexion avec un socket. De plus, Java rend plus facile l'élaboration des scripts CGI (Common Gateway Interface), et un mécanisme élégant, nommé servlet, augmente considérablement l'efficacité du traitement côté serveur, assuré par Java. De nombreux serveurs Web, parmi les plus courants, supportent les servlets. Le mécanisme d'invocation de méthode à distance (RMI) autorise la communication entre objets distribués. » - Fiabilité
Java a été conçu pour que les programmes qui l'utilisent soient fiables sous différents aspects. Sa conception encourage le programmeur à traquer préventivement les éventuels problèmes, à lancer des vérifications dynamiques en cours d'exécution et à éliminer les situations génératrices d'erreurs… La seule et unique grosse différence entre C++ et Java réside dans le fait que ce dernier intègre un modèle de pointeur qui écarte les risques d'écrasement de la mémoire et d'endommagement des données. - Orienté objet
Pour rester simples, disons que la conception orientée objet est une technique de programmation qui se concentre sur les données (les objets) et sur les interfaces avec ces objets. Pour faire une analogie avec la menuiserie, on pourrait dire qu'un menuisier « orienté objet » s'intéresse essentiellement à la chaise - l'objet qu'il fabrique - et non à sa conception (le « comment »). Par opposition, le menuisier « non orienté objet » penserait d'abord au « comment »… - Simple
Nous avons voulu créer un système qui puisse être programmé simplement sans nécessiter un apprentissage ésotérique, et qui tire parti de l'expérience standard actuelle. En conséquence, même si nous pensions que C++ ne convenait pas, Java a été conçu de façon relativement proche de ce langage dans le dessein de faciliter la compréhension du système. De nombreuses fonctions compliquées, mal comprises, rarement utilisées de C++, qui nous semblaient par expérience apporter plus d'inconvénients que d'avantages, ont été supprimées de Java. - Sécurité
Java a été conçu pour être exploité dans des environnements serveur et distribués. Dans ce but, la sécurité n'a pas été négligée. Java permet la construction de systèmes inaltérables et sans virus. -
Architecture neutre
Le compilateur génère un format de fichier objet dont l'architecture est neutre - le code compilé est exécutable sur de nombreux processeurs - , à partir du moment où le système d'exécution de Java est présent. Pour ce faire, le compilateur Java génère des instructions en bytecode qui n'ont de lien avec aucune architecture particulière. Au contraire, ces instructions ont été conçues pour être à la fois faciles à interpréter et faciles à traduire en code natif. - Portable
À la différence du C/C++, on ne trouve pas les aspects de dépendance de la mise en œuvre dans la spécification. Les tailles des types de données primaires sont spécifiées, ainsi que le comportement arithmétique qui leur est applicable. -
Interprété
L'interpréteur Java peut exécuter les bytecodes directement sur n'importe quelle machine sur laquelle il a été porté. Dans la mesure où la liaison est un processus plus incrémentiel et léger, le processus de développement peut se révéler plus rapide et exploratoire. -
Performances élevées
En général, les performances des bytecodes interprétés sont tout à fait suffisantes, il existe toutefois des situations dans lesquelles des performances plus élevées sont nécessaires. Les bytecodes peuvent être traduits à la volée en code machine pour l'unité centrale destinée à accueillir l'application. - Multithread
Les avantages du multithread sont une meilleure interactivité et un meilleur comportement en temps réel.
II. Le JDK de Sun▲
Le JDK de Sun (les créateurs de Java) est l'outil essentiel pour programmer en Java. Il permet la compilation, le débogage, et l'exécution d'applications et d'applets Java. Il comprend également des fonctions avancées comme les signatures numériques, la création d'archives et de documentation ou l'intégration de code natif C.
La documentation du JDK est en fait l'API de Java (le détail de toutes les fonctions du langage si vous préférez). Ceci explique sa taille importante (16 Mo). Elle est au format HTML. Vous ne pourrez pas créer de gros programmes sans y avoir recours.
Ces 2 outils sont disponibles dans la rubrique LIENS/RESSOURCES de ce site, à l'adresse http://perso.wanadoo.fr/guillaume/liens.htm
II-A. Installation▲
Après avoir téléchargé le JDK, vous devez l'installer en suivant les indications qui s'affichent à l'écran. L'installation prend environ 60 Mo. Il est important de ne pas avoir d'espace dans le nom des répertoires qui mènent au JDK. Les espaces peuvent causer certaines erreurs (les fonctions basiques fonctionnent quand même). Par exemple il est déconseillé d'installer le JDK dans « program files ». Préférez un chemin simple comme « C:\JDK\ ».
Une fois les fichiers du JDK copiés, il faut définir un CLASSPATH ou « Chemin des classes ». Ce Classpath est la source de nombreuses crises de nerfs chez les débutants (j'en ai souffert…), c'est pourquoi il est important de bien le définir.
POUR WINDOWS 95 : Allez sous DOS, allez à la racine du disque dur (utilisez « cd.. » pour descendre dans l'arborescence). Une fois dans « C:\ », tapez « edit autoexec.bat ». Un éditeur apparaît avec les lignes de l'« autoexec.bat ». Rajoutez cette ligne : « path = C:\JDK\bin\ ». Enregistrez le fichier, redémarrez votre ordinateur.
POUR WINDOWS 98 : Ouvrez le menu Démarrer, allez dans Exécuter, tapez « msconfig », une fenêtre s'ouvre, allez sur le 3e onglet qui correspond à « autoexec.bat », cliquez sur Nouveau et tapez « path = C:\JDK\bin\ ».Vérifiez que la petite case à gauche de cette ligne est bien cochée et redémarrez votre ordinateur.
Note : « path = C:\JDK\bin\ » ne fonctionne que si « C:\JDK\ » est votre répertoire d'installation du JDK. Si ce n'est pas le cas, remplacez-le par votre vrai répertoire.
II-B. Compiler▲
Écrivez votre programme Java avec un éditeur de TEXTE BRUT (ex-: NotePad). Sauvegardez-le avec l'extension « .java ». (ex-: « HelloWorld.java »). Le nom de votre fichier doit être le même que celui de votre classe principale (RESPECTER LA CASSE) :
public
class
HelloWorld {
// code
}
Le nom de votre fichier sera HelloWorld.java
Une fois le fichier enregistré, ouvrez une fenêtre DOS et rendez-vous dans le répertoire où vous avez enregistré votre fichier. (« cd nomDuRépertoire » pour monter d'un niveau et « cd.. » pour descendre). Une fois dans le répertoire où est votre fichier, tapez :
javac nomDuFichier.java
Respectez la casse et tapez toutes les lettres (pas de « nomDe~1 »). Le compilateur Java reconnaît les noms longs.
Normalement vous ne devez avoir aucun message, sinon, c'est que vous avez fait une erreur dans votre programme, vérifiez alors la syntaxe. Vous verrez vite que toutes les erreurs ne sont pas détectées par javac, certains programmes se compilent, mais affichent une erreur à l'exécution… C'est terrible… Mais pour l'instant pas de problème.
Quand javac compile un programme, il crée un fichier « *.class » (ex-: « HelloWorld.class »). Ce fichier est compilé et sera interprété par la machine virtuelle.
II-C. Exécuter▲
Sous DOS, placez-vous dans le répertoire où javac a créé le fichier « *.class » (le même que celui où vous avez au début enregistré votre fichier texte brut « *.java »). Tapez :
java nomDuFichier
Respectez la casse et ne mettez pas l'extension. Java accepte aussi les noms de fichier longs. Le programme s'exécute. Ouf…!!!
III. Initiation à Java : le projet HelloWorld▲
III-A. Débuter un programme▲
Importer les packages nécessaires
Écrire le corps du programme (déclaration de variables, création des méthodes, création de l'IU…)
Écrire la méthode main() :
public
static
void
main (
String x[ ]) {
&
#8230
;// votre code
}
Note : « x » représente la matrice d'« arguments » c'est pourquoi il sera le plus souvent remplacé par « arguments » ou « args ». Vous pouvez cependant choisir n'importe quel nom. Note : tous les programmes (pas les applets…) doivent avoir une méthode « main() », car c'est ce qui les définit en tant que programme !
III-B. Débuter une applet▲
Importer les packages nécessaires.
Déclarer la classe principale :
public
class
x extends
java.applet.Applet {
&
#8230
;// votre code
}
Note : « x » représente le nom de votre programme ainsi que le nom de son fichier source (« x.java » et « x.class »).
Note : pour programmer des applets en Java 2, on remplace « java.applet.Applet » par « JApplet ». Il est cependant recommandé de programmer vos applets en Java 1.1 ou mieux, en Java 1.02, car les dernières versions des principaux navigateurs (IE5, Communicator 4.7) ne supportent pas Java 2. Java 2 est supporté par le navigateur HotJava Browser de SUN (http://www.sun.java.fr), ainsi que par l'appletviewer (!), outil qui vous permettra de tester vos applets (inclus dans les JDK).
III-C. Insérer des commentaires▲
Les commentaires sont des lignes dans le programme qui ne sont pas prises en compte par le compilateur. Ils servent seulement à accroître la lisibilité du code source. Ils sont le plus souvent en vert dans les environnements de développement comme Kawa, JBuilder ou VisualCafé.
Voici comment on crée un commentaire :
- Ce code est pris en compte par le compilateur // ce code n'est plus pris en compte par le compilateur.
- /* Les deux slash ne permettent d'écrire des commentaires que sur 1 seule ligne, alors que cette méthode avec une belle étoile et encore un slash permettent d'écrire sur plusieurs lignes des romans ou des fables de centaines de pages commençant par Il était une fois et finissant par le sempiternel ils se marièrent et eurent beaucoup d'enfants…………………….. */
Résumons :
// sur 1 seule ligne
/* … */
sur plusieurs lignes
III-D. Écrire du texte▲
Le titre de ce paragraphe ne veut rien dire, car en programmation, « on n'écrit pas de texte », on affiche du texte sur un périphérique de sortie (par défaut l'écran de l'ordinateur !) ; on peut aussi afficher du texte dans un composant d'une IU (par exemple, l'intitulé du menu « fichier » de votre navigateur). Dans notre exemple, on affichera du texte dans la zone de sortie : ici, la fenêtre de ligne de commande (MS-DOS pour les PC sous Windows) dans laquelle a été lancée l'application (cf. rubrique JDK/exécution d'un programme).
Pour afficher du texte en ligne de commande, on utilise la méthode :
System.out.println
(
"texte à afficher"
);
System.out.print
(
"les deux méthodes sont équivalentes"
);
Il est plus difficile (c'est relatif…) d'afficher du texte dans une applet, car on doit l'afficher dans un composant (une applet est lancée dans une sorte de cadre inséré dans le navigateur) graphique de l'applet, les deux méthodes ci-dessus ne fonctionnent pas. On utilise la méthode « paint() » de l'applet pour définir l'affichage et la méthode « drawString() » pour écrire le texte :
public
void
paint
(
Graphics screen) {
screen.drawString
(
"Bonjour"
, 5
, 40
);
}
Note : 5 et 40 sont les coordonnées du texte dans un repère qui a pour origine de coin haut gauche de l'écran.
III-E. Application : le programme Hello World !▲
Hello World ! est célèbre : c'est traditionnellement le premier programme que l'on fait faire à une personne qui débute dans un langage de programmation. Il a pour but d'afficher le texte Hello World ! Il faut donc pour l'exécuter créer un programme, avec la méthode « main() », et utiliser la méthode « System.out.println() » pour afficher notre texte. Au travail !
class
HelloWorld {
// début du programme
public
static
void
main (
String args[ ]) {
// début de ma méthode main()
System.out.println
(
"Hello World !"
); // affichage du texte désiré
}
// fin de ma méthode main()
}
Note : pour compiler le programme, vous devez nommer votre fichier « HelloWorld.java », en respectant la casse.
Voici le programme exécuté :
IV. Les Variables : le projet Chocos▲
Il est possible de télécharger les sources du programme.
IV-A. Introduction▲
Il est facile de concevoir ce que sont les variables. Prenons comme exemple des boites de chocolat. Ces boites sont remplies avec plusieurs catégories de chocolats : les Truffes, les MonChéri, les Cœurs et les Mokas. Ce sont les 4 pauvres variétés de chocolats que vend le chocolatier. Vous pouvez choisir par exemple 8 Truffes et 20 MonChéri dans votre première boite et 4 Cœurs, 10 Mokas et 14 MonChéri dans votre seconde boite. Imaginons maintenant en programmation : on crée des objets boite (cf. chapitre sur la POO pour les objets) avec pour variables : Truffes, MonCheri, Cœurs, Moka. Dans le cas de la première boite, on va associer la valeur 8 à la variable Truffe, et la valeur 20 à la variable MonCheri.
IV-B. Types de variables▲
Il y a différents types de variables en Java, qui ne stockent pas les mêmes valeurs. Regardez le tableau ci-dessous regroupant les variables les plus utilisées :
NOM |
PLACE EN BITS |
VALEURS STOCKEES |
COMMENTAIRES |
byte |
8 |
De -128 à 127 |
Vous ne l'utiliserez pas souvent |
short |
16 |
-32 768 à 32 767 |
|
int |
32 |
-2x109 à 2x109 |
Appelée INTEGER (entier en français), très utilisée |
long |
64 |
-9x1018 à 9x1018 |
|
boolean |
1 |
booléennes |
Valeurs binaires : true ou false |
String |
chaînes |
Considéré à ce stade comme une variable bien que cela n'en soit pas une. Ne pas oublier la majuscule. |
|
BigInteger |
+ de 64 |
? |
Importer java.math.BigInteger |
double |
Pratique pour les décimales. Très utilisé. |
||
float |
Virgule flottante |
Pi, e… |
Note : vous pouvez créer vos propres types de variables, nous verrons plus tard…
IV-C. Déclaration de variables▲
La création d'une variable est appelée « déclaration ». On va donc déclarer nos variables en chocolat, elles stockeront le nombre de chocolats de chaque type contenus dans une boite. Elles seront du type integer.
int
Truffes;
int
MonCheri;
int
Moka;
int
Coeur;
On peut également déclarer toutes ces variables d'un seul coup, car elles appartiennent au même type, c'est-à-dire les entiers (integer).
int
Truffes, MonCheri, Moka, Coeur;
IV-D. Initialisation des variables▲
Initialiser une variable signifie lui donner une valeur de départ (cette valeur peut changer au cours du programme, normal, c'est variable !). Prenons le cas de la première boite de chocolats :
int
Truffes =
8
;
int
MonCheri =
20
;
Note : ceci déclare les variables avant de les initialiser. Ces lignes regroupent donc chacune deux opérations en une seule.
IV-E. Opérateurs d'affectation▲
On a une variable x, déclarée avec une valeur bien précise. On veut lui ajouter la valeur de y (qui est aussi déclarée et initialisée). On écrit alors : x = x + y. Et x prend alors une nouvelle valeur (son ancienne ajoutée à celle de y, qui, elle ne change pas). On peut aussi multiplier, diviser… :
OPERATION A REALISER |
OPERATION DEVELOPPEE |
OPERATION SIMPLIFIEE |
Addition |
x = x + y |
x += y |
Soustraction |
x = x - y |
x -= y |
Multiplication |
x = x * y |
x *= y |
Division |
x = x / y |
x /= y |
IV-F. Incrémentation et décrémentation▲
Incrémenter c'est augmenter de 1 la valeur d'une variable et décrémenter, diminuer de 1. Ces procédés sont particulièrement utiles dans les boucles (cf. chapitre sur les bouclesBoucles et conditions : le projet NamesLoop). On incrémente à l'aide de ++ et on décrémente à l'aide de --.
int
x =
7
; // déclaration de x, initialisée avec 7 pour valeur
x++
; // on incrémente x, x a maintenant la valeur 8
IV-G. Comparaison de variables▲
Le titre est assez parlant… on regarde si deux variables sont égales, différentes, si la première est supérieure à la seconde, si la seconde est inférieure ou égale à la première…
OPERATEUR |
DESCRIPTION |
== |
Egal à |
!= |
Différent de |
< |
Inférieur à |
> |
Supérieur à |
<= |
Inférieur ou égal à |
>= |
Supérieur ou égal à |
Note : ceci ne fonctionne qu'avec les variables et pas avec les objets (dans ce cas le programme compare si c'est le même objet, pas s'il a la même valeur). Cela ne fonctionne donc pas avec String qui est un objet…
IV-H. Les constantes▲
Les constantes sont des variables constantes (!) (si, si, je vous jure…). En fait elles sont utilisées pour les mêmes choses que les variables ; stocker des valeurs, mais une fois initialisée, la valeur ne peut plus changer… Elles sont déclarées avec le mot clé final.
final
float
pi =
3.14159
;
Vous n'allez quand même pas essayer de changer la valeur de pi ? ;-)
IV-I. Blocs et portée▲
En Java, les programmes sont très structurés. Ils sont organisés en blocs. Par exemple tout ce qui est contenu dans la méthode main() est un seul et même bloc (souvent subdivisé en autres petits blocs). De même, les instructions de la méthode paint() d'une applet sont dans un seul et même bloc. Pour les reconnaître : ils commencent par une accolade ouvrante { et finissent par une fermante }.
Les variables classiques ont une portée dans le bloc qui les contient. Si vous faites référence dans un bloc à une variable déclarée dans un autre bloc, le compilateur générera une erreur. (Ne dites pas « bogue » pour l'instant… Il y a une grosse différence entre un bogue et l'erreur décrite ci-dessus.) Mais il est possible en Java de créer des variables spéciales qui ont pour portée tout le programme (ou la classe, c'est un synonyme de programme). Ces variables bien pratiques sont appelées variables de classe. On les déclare à l'aide du mot clé static.
static
int
nombreDeBilles =
200
; // ce garçon a beaucoup de billes !
static
String surnom =
"Drizzt"
; /* comme il s'appelle Djkelimbfastlichtz, on le surnomme
Drizzt, la valeur de type String (chaîne de caractères) de la variable « surnom » est donc
Drizzt*/
IV-J. Application : le programme Chocos▲
Le programme Chocos va déclarer plusieurs variables. Les valeurs de ces variables vont changer puis être affichées sur le périphérique de sortie, ligne de commande. On utilisera : System.out.println() pour afficher la valeur des variables.
class
Chocos {
// début du programme
static
String mangeur =
"Gargantua"
; //variable statique. portée = tout le programme
public
static
void
main
(
String args[]) {
// début de la méthode main()
int
nombreDeChocolats =
40
; //variable non statique. portée = ce bloc main()
System.out.println
(
mangeur +
" a "
+
nombreDeChocolats +
" chocolats"
);
System.out.println
(
"Il en mange 3 d'un coup"
);
nombreDeChocolats =
nombreDeChocolats -
3
; // changement de valeur de la variable
System.out.println
(
"Il en reste : "
+
nombreDeChocolats);
System.out.println
(
"Il renverse la boite, 15 sont perdus"
);
nombreDeChocolats =
nombreDeChocolats -
15
;
System.out.println
(
"Il en reste : "
+
nombreDeChocolats);
System.out.println
(
"Pour se venger,"
+
mangeur +
" finit la boite"
);
nombreDeChocolats =
nombreDeChocolats -
22
;
System.out.println
(
"Il en reste : "
+
nombreDeChocolats);
System.out.println
(
"Mais "
+
mangeur +
" a encore une boite…"
);
}
}
V. Les Matrices : le projet ArrayTest▲
Il est possible de télécharger les sources du programme.
V-A. Définition▲
Les matrices sont des sortes de conteneurs à variables. Toutes les données dans une même matrice doivent être du même type, on parle ainsi de matrices d'entiers, de matrices de chaînes, etc.
V-B. Utilité▲
On peut déclarer 200 variables de type int en 200 lignes et une matrice de 200 int en 1 ligne… On gagne ainsi en rapidité, lisibilité et légèreté du code. De plus les matrices sont utiles si l'on doit par exemple stocker les prénoms de plusieurs personnes, puis leur nom de famille, puis leur âge… On crée à cet effet 3 matrices. Enfin, il est plus utile de travailler avec les matrices, car on connaît le nombre d'éléments qu'elles contiennent (on peut donc par exemple créer une matrice de prénoms puis une autre de noms de famille sans oublier aucune entrée.
V-C. Syntaxe▲
Déclaration d'une matrice :
String mots[];
String [] mots;
Dans les deux cas, le programme crée une matrice de chaînes ayant pour nom mots. On note la syntaxe très proche des déclarations de variables.
Initialisation d'une matrice :
String[] nomDesJoueurs =
new
String[10
];
nomDesJoueurs[0
] =
"franck"
;
nomDesJoueurs[1
] =
"john"
;
Ces commandes créent une matrice de chaînes de nom nomDesJoueurs et contenant 10 « cases ». Elles donnent ensuite la valeur franck à la première de ces « cases » et john à la seconde.
Note : les valeurs des matrices sont numérotées à partir de 0.
String[] prenoms =
{
"franck"
, "john"
, "gerthrud"
, "moloss"
, "grota"
}
;
Cette commande crée un tableau de String prenoms et lui attribue directement des valeurs. La matrice contient donc 5 « cases ».
V-D. Application : Projet ArrayTest▲
Le programme ArrayTest crée une matrice contenant les prénoms de programmeurs célèbres. Il affiche cette matrice, puis crée une autre matrice de la même grandeur (avec le même nombre de « cases »). Cette seconde matrice contient les noms de famille correspondant à chaque prénom. Le résultat est affiché.
class
ArrayTest {
// classe principale
// création de la première matrice de prénoms
String[] firstNames =
{
"Dennis"
, "Grace"
, "Bjarne"
, "James"
}
;
// la seconde matrice contient le même nombre d'arguments que la première
String[] lastNames =
new
String[firstNames.length];
void
printNames
(
) {
// méthode pour afficher le contenu de la 2de matrice
int
i =
0
; // i du type integer et égal à 0
// afficher la valeur i+0=0 de la matrice 1 et de la matrice 2
// ceci consiste donc à afficher le contenu de la première case
//des 2 matrices
System.out.println
(
firstNames[i] +
" "
+
lastNames[i]);
// (i=0)i=i+1, donc de la seconde case des matrices
i++
;
System.out.println
(
firstNames[i] +
" "
+
lastNames[i]);
// (1=1) 1=1+2, donc de la seconde case des matrices
i++
;
System.out.println
(
firstNames[i] +
" "
+
lastNames[i]);
i++
;
System.out.println
(
firstNames[i] +
" "
+
lastNames[i]);
}
public
static
void
main (
String arguments[]) {
ArrayTest a =
new
ArrayTest
(
); // appel de la classe
a.printNames
(
); // applet de la méthode printNames()
System.out.println
(
"-----"
);
// définition des valeurs des cases de la 2de matrice
a.lastNames[0
] =
"Richie"
;
a.lastNames[1
] =
"Hopper"
;
a.lastNames[2
] =
"Stroustrup"
;
a.lastNames[3
] =
"Gosling"
;
a.printNames
(
); // appel de la méthode printNames()
}
}
VI. Boucles et conditions : le projet NamesLoop▲
Il est possible de télécharger les sources du programme.
VI-A. Introduction, les conditions if…else▲
Les conditions utilisent des données booléennes, true ou false. Elles vérifient si une condition est remplie. Si oui, elles effectuent un bout de code prédéfini, sinon, elles exécutent au autre bout de code prédéfini ou passent directement au reste du programme. Elles ont la forme if … else …
if
(
BeaucoupDeFric ==
true
)
Restaurant =
"Jardin des sens"
;
else
Restaurant =
"McDo"
Si la personne est riche, elle ira manger dans un certain restaurant, sinon, elle ira ailleurs…
Note : on peut en faire à plusieurs possibilités : if… else if … else if… else if… else…
if
(
Fric ==
100
)
Resto =
McDo;
else
if
(
Fric ==
200
)
Resto =
Quick;
else
if
(
Fric ==
300
)
Resto =
Flunch;
else
Resto =
chezMoi;
VI-B. Switch…Case▲
Les conditions switch…case remplacent les conditions if…else if…else quand le nombre de else if est trop important. Elles sont en effet plus rapides à écrire :
switch
(
note) {
case
'A'
&
#160
;:
System.out.println (
"Très Bien"
); break
;
case
'B'
&
#160
;:
System.out.println (
"Bien"
); break
;
case
'Z'
&
#160
;:
System.out.println (
"Lobotomisé !"
); break
;
default
&
#160
;: System.out.println (
"Tricheur !"
);
}
Note : pour sortir de la condition, on utilise le mot break, regardez bien l'utilisation du « ; » pour terminer les instructions (et pas les lignes !).
VI-C. Boucles for▲
Les boucles for testent une condition et exécutent le bout de code attaché à la boucle tant que la condition n'est pas remplie. Leur syntaxe officielle est la suivante :
for
(
initialization ; test ; increment) {
statement ; }
Ceci ne vous évoque certainement rien, alors examinez le code suivant :
String [] salutation =
new
String[10
];
int
i;
for
(
i =
0
; i <
salutation.length ; i++
)
salutation[i] =
"M."
;
Le programme crée une matrice du nom de salutation qui peut contenir 10 éléments. Il crée ensuite une variable i de type Integer. La boucle for commence : la valeur de i est 0, tant que la valeur de i est inférieure à la taille de la matrice (taille obtenue par la commande salutation.length), le code de la dernière ligne est exécuté. i est incrémenté de 1, puis la condition est revérifiée, ainsi de suite jusqu'à i = 10.
VI-D. Boucles while▲
Les boucles while sont très semblables aux boucles for. Elles fonctionnent ainsi :
while
(
i <
10
) {
// corps de la boucle
i++
;
}
Tant que i < 10, le corps de la boucle est exécuté, puis i est incrémenté et la condition est retestée.
VI-E. Boucles do…while▲
Les boucles do…while sont des variantes des boucles while. Leur particularité réside dans le fait que la condition est testée après la première exécution de la boucle. Le code est exécuté tant que la condition n'est pas satisfaite, mais il sera dans tous les cas exécuté au moins une fois.
{
// corps de la boucle
}
while
(
i <
10
)
Voici un exemple plus concret sur l'utilisation des boucles :
class
BoucleDo {
public
static
void
main
(
String args [ ]) {
int
x =
1
;
do
{
System.out.println
(
"La boucle est bouclée; passage"
+
x);
x++
;
}
while
(
x <=
100
) ;
}
}
Vous pouvez compiler ce programme, il fonctionne ! Nommez le fichier source « BoucleDo.java ».
VI-F. Break et Continue▲
break sert à interrompre une instruction. Dans un switch case, il permet d'en sortir sans passer dans les case suivants. Dans une boucle, il permet de sortir de la boucle sans réaliser les itérations suivantes.
continue permet de passer directement à l'itération suivante d'une boucle sans exécuter le code qui est entre le continue et la fin de la boucle.
VI-G. Application : Projet NamesLoop▲
Ce programme, une fois de plus de ligne de commande, crée une matrice contenant des prénoms de programmeurs célèbres et les associe à leur nom de famille. On utilise donc les matrices, les boucles for, la création d'une méthode, l'affichage de texte. Ce programme est extrait de l'excellent ouvrage Java2 (Roger Cadenhead & Laura Lemay) Ed. CampusPress.
class
NamesLoop {
// Création de la classe
String[] firstNames =
{
"Dennis"
, "Grace"
, "Bjarne"
, "James"
}
; // matrice des
//prénoms
String[] lastNames =
new
String[firstNames.length]; //matrice des noms (vide)
void
printNames
(
) {
// méthode pour afficher
for
(
inti =
0
; i <
firstNames.length; i++
) // boucle for
System.out.println
(
firstNames[i] +
" "
+
lastNames[i]); //instruction
}
public
static
void
main (
String arguments[]) {
// remplissage de la seconde matrice avec les prénoms
// appel de la méthode d'affichage
NamesLoop a =
newNamesLoop
(
);
a.printNames
(
); // méthode d'affichage
System.out.println
(
"-----"
);
a.lastNames[0
] =
"Ritchie"
;
a.lastNames[1
] =
"Hopper"
;
a.lastNames[2
] =
"Stroustrup"
;
a.lastNames[3
] =
"Gosling"
;
a.printNames
(
); // méthode d'affichage
}
}
Note : Ici la boucle for sert à déterminer la taille de la matrice des noms de famille. Elle compte le nombre d'éléments dans la matrice des prénoms, ce nombre d'éléments est associé à la matrice des noms de famille (car chaque personne a un prénom et un nom de famille)
VII. Objets ou Instances : le projet EgaliteTest▲
Il est possible de télécharger les sources du programme.
VII-A. Introduction▲
Dans le chapitre sur les variables, nous avions défini les différentes sortes de chocolats dans une boite. Nous avions utilisé par commodité les notations première et seconde boites, mais l'ordinateur, lui, ne sait pas que les chocolats sont contenus dans une boite, et encore moins qu'il y a deux boites différentes ! En termes informatiques, ces boites seraient des objets, également appelés instances. À ce niveau vous pourriez confondre un objet avec une matrice… Conteneurs de chocolats… Mais les matrices sont des sortes d'objets. On parle de langage de programmation orienté objet pour Java, ce qui signifie qu'il travaille avec des objets, leur assignant des propriétés (par exemple contenir des chocolats au lait et noirs) et des comportements (se re-remplir automatiquement de chocolats une fois vide…). La pratique vous aidera à éclaircir ce concept flou.
VII-B. Déclaration (ou création de nouveaux objets)▲
String teamName =
new
String
(
) ;
Dinosaure Trex =
new
Dinosaure
(
);
BoiteChocos auLait =
new
BoiteChocos
(
);
Si vous ajoutez ces lignes dans un de vos programmes, il refusera de se compiler. Lui ne sait pas ce qu'est un Dinosaure() ou un BoiteChocos(). Pouvez-vous me décrire un szertysprzchutde la planète sakasksproucht ? Non. Pouvez-vous me décrire … un chien … oui. De même pour l'ordinateur qui connaît la classe String, car ses propriétés et son comportement ont été préalablement définis. (Dans l'API de Java.)
Il est défini dans les propriétés de String qu'il reçoit comme argument (ce qui vient entre les parenthèses) une chaîne. Si vous essayez de lui assigner autre chose qu'une chaîne comme argument, il générera une erreur et le programme ne se compilera pas.
De même, par exemple, pour Point qui admet comme arguments ses coordonnées en abscisse et ordonnée. (Dans (O, i, j), O situé en haut à gauche de l'écran et les coordonnées des vecteurs i et j exprimées en pixels).
Point A =
new
Point
(
10
, 3
) ; // fonctionne
Point B =
new
Point
(
"Bonjour"
) ; // ne fonctionne pas
Le compilateur nous dit qu'il ne peut pas convertir une valeur de type chaîne (String) en argument pour Point.
VII-C. Accès aux valeurs▲
On peut par l'intermédiaire de méthodes (fonctions, ou série d'actions qui définissent un comportement) avoir accès aux valeurs des objets. On prendra pour exemple le composant TextField de l'interface utilisateur AWT de Java et lui assigner une valeur.
Le nom de cet objet est textField1. Il a été déclaré comme ceci :
TextField textField1 =
new
TextField
(
);
On peut définir le texte qu'il affichera en utilisant la méthode setText() :
textField1.setText
(
"Bonjour !"
);
On a ainsi eu accès à sa valeur d'affichage de texte qui était auparavant fixée nulle.
VII-D. Comparaison d'objets▲
On utilise les mêmes opérateurs que pour les variables, par exemple == pour égal ou!= pour différent.
Point A =
new
Point
(
10
, 3
) ;
Point B =
new
Point
(
11
, 4
);
System.out.println
(
"Même objet ?"
+
(
A ==
B));
On compare ainsi les objets : « est-ce que A est B ? » et non pas « est-ce que A a la même valeur que B ? ». Pour savoir s'ils ont la même valeur, on utilise la méthode equals().
VII-E. Application : le programme EgaliteTest▲
Dans ce programme nous allons revenir sur la comparaison des objets et la comparaison de leur valeur.
Note : souvenez-vous dans le chapitre sur les variables : String n'en était pas une…
class
EgaliteTest {
public
static
void
main
(
String args[]){
String str1, str2; // 2 objets de type String
str1 =
"Voila un exemple !"
; // valeur du premier
str2 =
str1; // le second est le premier
System.out.println
(
"Chaine 1 "
+
str1);
System.out.println
(
"Chaine 2 "
+
str2);
System.out.println
(
"Même objet ? "
+
(
str1 ==
str2));
// on re-crée le second objet
str2 =
new
String
(
str1); // le second a la valeur du premier
System.out.println
(
"Chaine 1 "
+
str1);
System.out.println
(
"Chaine 2 "
+
str2);
System.out.println
(
"Même objet ? "
+
(
str1 ==
str2));
System.out.println
(
"Même valeur ? "
+
str1.equals
(
str2));
}
}
La partie concernant les objets est énorme : c'est normal, java est un langage orienté objet… Nous verrons de nouvelles applications dans d'autres chapitres.
VIII. Méthodes : le projet ReHello▲
Il est possible de télécharger les sources du programme.
VIII-A. Définition▲
Nous avons créé des objets. Nous avons assigné des propriétés à ces objets. Il ne nous reste plus qu'à leur associer un comportement, car s'ils se contentaient de rester plantés sur place on tomberait vite dans le très descriptif HTML ;-).
On peut aussi appeler les méthodes des fonctions ou des routines (ce terme est peu usité en Java, il vient du C++).
Note concernant ce chapitre : plusieurs paragraphes de ce chapitre concernant des fonctions plus ou moins évoluées ne sont pas développés ; je trouve que c'est préférable ainsi, et qu'après une brève définition pour vous informer sur l'existence de la chose, il vaut mieux ne pas vous noyer sous des exemples qui devraient faire appel à des concepts qui ne vous sont pas encore familiers et dont vous n'aurez pas l'utilité immédiate.
VIII-B. Généralités▲
La création de la méthode elle-même n'est pas compliquée, ce qui est plus délicat est de lui assigner un comportement. Les méthodes sont reconnaissables à leurs parenthèses, elles sont délimitées comme les classes par des accolades. Vous êtes libre du choix de leur nom (choisissez quand même un truc intelligent…).
Si une méthode ne retourne pas de valeur, (les System.out.print() ne sont pas considérés comme retournant des valeurs), il faut la déclarer à l'aide du mot clé void. Si elle retourne une valeur, on la déclare avec le mot clé du type de valeur qu'elle retourne. Pour qu'une méthode retourne une valeur, on emploie return. On peut assigner à une méthode des arguments (sous la forme de variables classiques, par opposition aux variables de classe), on place ces éléments entre les parenthèses. Ainsi dans une classe, 2 méthodes peuvent avoir la même nom, seuls leurs arguments respectifs les différencieront aux yeux du compilateur. On appelle ce concept surcharge de méthodes.
// ne retourne pas de valeur
void
imprime
(
) {
int
i =
10
+
20
;
System.out.println
(
"Résultat : "
+
i);
}
// retourne une valeur
int
imprime
(
) {
int
i =
10
+
20
;
return
i;
}
// admet un argument
int
imprime
(
int
i) {
i =
10
+
i;
return
i;
}
On notera que l'habituel public static void main(String args[]) {…} déclare en fait une méthode publique (voir chapitre sur les modificateursLes Modificateurs), statique (voir aussi ce très utile chapitre), qui ne retourne pas de valeur, qui se nomme main et qui a pour argument une matrice de chaînes nommée args. Ouf…
VIII-C. Constructeurs▲
Les constructeurs sont des méthodes particulières qui servent à créer des objets à partir d'une classe. Elles portent exactement (toujours la casse…) le même nom que la classe qui les contient. Elles n'ont pas de type de retour.
VIII-D. Le mot clé this▲
Ce mot clé est utile pour la lisibilité du code. Il sert dans le cas où une variable d'instance et une variable de classe portent le même nom. this est alors employé pour faire référence à la variable de classe. Vous pouvez ainsi attribuer plusieurs fois le même nom de variable.
this
.nomDeLaVariable =
nomDeLaVariable;
VIII-E. Le mot clé super▲
Le mot clé super permet d'accéder à l'implémentation d'une méthode de la super classe.
public
class
Mere {
public
void
methode
(
) {
System.out.println
(
"méthode mere"
);
}
}
public
class
Fille extends
Mere {
public
void
methode
(
) {
super
.methode
(
); // Appel à la méthode de la classe Mere
System.out.println
(
"méthode fille"
);
}
}
VIII-F. Finaliser▲
La méthode finalize() peut être appelée lorsque qu'un objet est détruit (retiré de la mémoire vive), mais ce n'est pas obligatoire. C'est le garbage collector qui décide de la destruction d'un objet. Il est possible de provoquer une exécution du garbage collector avec System.gc().
protected
void
finalize
(
) throws
Throwable {
...
}
VIII-G. Application : ReHello▲
Le programme ReHello est la seconde mouture de HelloWorld, il crée un méthode qui sert à afficher du texte. Ce très court programme est plus simple que plusieurs des chapitres précédents et il n'utilise pas de concept évolué. C'est donc un jeu d'enfant…
class
ReHello {
// déclaration de la classe principale
public
static
void
imprime
(
) {
// création de la méthode qui affiche le texte
// ci-dessous les instructions de la méthode
System.out.println
(
"HelloWorld ! Encore une fois…"
);
}
// fin de la méthode imprime()
public
static
void
main
(
String args[]) {
// la méthode main()…
imprime
(
); // … qui fait appel à la méthode imprime()
}
}
On note que notre méthode imprime() est statique (déclarée ainsi par le mot clé static), car on ne peut faire référence dans une première méthode déclarée statique à une seconde méthode que si cette dernière est statique. C'est le cas de la méthode main() qui est statique est qui ne peut contenir que des références à des méthodes statiques. (voir le chapitre sur les modificateursLes Modificateurs pour plus amples informations)
IX. Classes et Héritage▲
IX-A. Définition▲
Chaque logiciel Java, qu'il s'agisse d'une applet ou d'une application, se compose toujours d'au moins une classe. Toutes les variables, méthodes et lignes d'instructions doivent toujours se trouver dans une classe. Les seules exceptions sont les instructions d'importation de classes, ainsi que celles qui définissent une classe comme appartenant à une bibliothèque de classes.
Une classe dont vous programmez le code source peut se représenter comme un plan de construction de l'objet. Elle se compose de données et de méthodes qui ont un quelconque rapport conceptuel. Définition du Grand Livre Java 2 chez Micro Application.
On retient ici qu'une classe est un programme Java (ce sont quasiment des synonymes). Par exemple, si MSOffice était écrit en Java, on aurait une classe pour Word, une autre pour Excel et encore une autre pour Outlook, etc. MSOffice serait alors le package (paquetage en français) ou le rassemblement de plusieurs classes. Cette vision est naïve, car NotePad à lui seul regrouperait plusieurs classes (on pourrait tout faire dans la même classe, mais ce serait incompréhensible, imaginez que vous vous retrouvez devant 300 pages de programme à la suite !), mais elle permet de comprendre le concept de classe.
IX-B. Héritage▲
Une classe est donc un programme qui définit des objets, variables, méthodes, etc. Disons que dans Word 1, il existe une classe (composée de plusieurs méthodes) pour ouvrir un fichier. Dans sa version 2, M… veut améliorer la gestion de l'ouverture des fichiers, tout en gardant les méthodes - qui fonctionnaient parfaitement - de la version 1. La classe de la version 2 doit alors hériter des propriétés de la classe de la version 1. Ceci est comme un héritage génétique : une même base avec certaines choses qui changent.
Si vous avez déjà examiné le code source d'une applet, vous avez eu l'occasion de voir une commande d'héritage. On déclare la classe principale d'une applet ainsi :
public
class
NomDeLaClasse extends
java.applet.Applet {&
#8230
;}
Votre classe (ici, NomDeLaClasse) étend la classe Applet. Ceci signifie qu'elle hérite des propriétés de cette classe. Une de ces propriétés est par exemple la création d'une zone d'affichage graphique (dans votre navigateur). Sans ceci le programme n'est pas une applet. java.applet est le chemin d'accès (classpath) qui dit au programme d'aller chercher la classe Applet dans le package java, puis dans le répertoire applet de celui-ci. Dans la bibliothèque de classes de Java, les classes sont classées (!) dans des répertoires.
La classe NomDeLaClasse est une sous-classe de la classe Applet du package java.applet qui est elle-même sa superclasse.
En Java, une classe ne peut pas hériter de plusieurs classes. Java ne supporte donc pas l'héritage multiple. Java est donc moins flexible que d'autres langages, mais il évite ainsi nombre d'erreurs. Ceci est compensé en partie par les interfaces.
Note : sur le graphique, JApplet remplace Applet,car il s'agit de la classe de Java2 (non supporté par les navigateurs actuels).
Si vous souhaitez interdire l'héritage d'une de vos classes, vous devez la déclarer final.
final
class
NonHeritable {&
#8230
;
Si vous voulez un schéma d'héritage complet de Java 1.1, téléchargez le PDF (157Ko) à cette adresse : http://perso.wanadoo.fr/guillaume/Ressources/api_java1.pdf
IX-C. Création de classes▲
Les classes sont déclarées avec le mot clé class, le code est enfermé entre deux accolades. On utilise le mot clé extends pour l'héritage.
IX-D. Classes imbriquées▲
On peut créer une classe dans une autre classe (sauf si elle est déclarée statique avec le mot clé static, voir chapitre sur les modificateurs). Voici un beau petit exemple :
Comme une classe ne peut hériter que d'une seule autre classe, on peut créer des classes imbriquées qui vont résoudre le problème. Les classes imbriquées dans vos programmes devront être gérées avec la plus grande attention, car on se mélange facilement les pinceaux ! sans parler des problèmes de portée de variables…
Ce qui nous amène à aborder un nouveau concept : le polymorphisme. Si on appelle une méthode dans une classe, le programme regarde si cette méthode existe (nom + arguments). Si elle existe, elle est exécutée. Si cette méthode n'existe pas, le programme la cherche dans la superclasse de la classe qui fait appel à elle. Et on monte ainsi les niveaux jusqu'à ce qu'une méthode adéquate soit trouvée ou que la « remontée » se termine (dans ce cas, le compilateur générera une erreur). Lorsqu'une méthode définie dans une sous-classe a le même nom ou les mêmes paramètres qu'une méthode d'une des classes ancêtres (superclasse), elle cache la méthode de la classe ancêtre à la sous-classe. Ceci est très important : une méthode de « bas niveau » cache une méthode de « haut niveau » quand on redéfinit son comportement.
IX-E. Classes abstraites▲
À mesure que l'on remonte dans la hiérarchie des classes, celles-ci deviennent plus générales et souvent plus abstraites. À un certain moment, la classe ancêtre devient tellement générale qu'on la considère surtout comme un moule pour des classes dérivées et non plus comme une véritable classe dotée d'instances. Une classe abstraite définit donc une « ligne de conduite » pour ses méthodes. Elle vous met « sur la voie » pour définir plus précisément votre propre classe. Cette classe abstraite ne peut donc pas être instanciée (adaptée en objet). Elle peur contenir des méthodes abstraites, mais ce n'est pas une obligation. Les classes abstraites sont déclarées à l'aide du mot clé abstract.
public
abstract
class
NomDeLaClasse {&
#8230
;}
Il est surtout important de retenir qu'il est avantageux de placer le plus de fonctionnalités possible dans une superclasse, abstraite ou non.
IX-F. Importation de classes▲
On ne va pas s'éterniser là-dessus : vous connaissez la commande import qui permet au début du programme de rendre des classes accessibles. Par exemple pour, dans une applet, travailler avec des images, on importera java.awt.image avec la commande suivante :
import
java.awt.image.*;
IX-G. Les packages JDK les plus utiles▲
Package |
Description |
java.applet |
Contient la classe Applet et 3 interfaces. Elles servent d'intermédiaires entre une applet et le navigateur. |
java.awt |
Interface utilisateur issue de Java 1. Également chargement de graphiques, impression, distribution d'éléments graphiques… |
java.awt.datatransfer |
Support du presse-papier (copier/coller…) |
java.awt.event |
Gestionnaire d'événements AWT |
java.awt.image |
Gestion des images |
java.beans |
Gestion des beans |
java.io |
Gestion des entrées/sorties (écriture et lecture de données) |
java.lang |
Contient la classe racine Object, types de données avancés… |
java.math |
Fonctions mathématiques |
java.net |
Client/serveur |
java.rmi |
Modules RMI (Remote Method Invocation) pour invoquer des méthodes à distance |
java.security |
Fonctions de sécurisation des transmissions |
java.sql |
Permet l'accès aux bases de données relationnelles par l'intermédiaire du langage SQL |
java.text |
Formatage des chaînes de texte |
java.util |
Conversions, structures de données, gestion d'événements |
javax.swing(le x est volontaire) |
Tous les composants de l'interface utilisateur SWING de Java 2 |
issu de Au cœur de Java 2 par Cay S. Horstmann & Gary Cornell aux éditions Sun (Campus Press).
X. Transmission d'arguments : le projet Palindrome▲
X-A. Introduction▲
Dans ce chapitre, nous allons transmettre des arguments à une application et à une applet Java, c'est-à-dire leur donner des valeurs, chiffres ou lettres, qu'elles attendent pour leur bonne exécution. Par exemple, le programme doit savoir s'il y a plus ou moins de 100 g de chocolats dans la boite, il attendra alors un argument spécifié par l'utilisateur. Cet argument est susceptible de changer à chaque exécution du programme, c'est pourquoi il ne peut être directement spécifié dans le code source.
Capter un argument de ligne de commande est pénible en Java, heureusement c'est quasiment inutile, car la plupart de vos programmes posséderont une Interface Utilisateur et ne se contenteront pas de s'exécuter dans une fenêtre de ligne de commande (DOS pour Microsoft…) (la procédure pour récupérer un argument à partir d'une IU étant beaucoup plus simple).
Par contre, pour les applets, c'est bien utile et moins compliqué.
X-B. Transmettre un argument à une application▲
Un argument se transmet à une application à l'exécution :
// sans transmission d'argument
java NomDuProgramme
// avec transmission d'argument
java NomDuProgramme PremierArgument SecondArgument TroisiemeArgument, EtCaetera
On note que les arguments sont séparés d'un espace. Dans le cas d'un argument qui comprend plusieurs mots qui doivent être séparés, on utilise les guillemets : "Federico Garcia Lorca" est considéré comme 1 seul argument.
X-C. Récupérer un argument à partir d'une application▲
On doit créer une boucle for qui parcourt le programme à la recherche d'arguments :
//partie théorique
for
(
int
i =
0
; i <
arguments.length ; i++
) {&
#8230
;}
//partie pratique
class
MesArguments {
public
static
void
main
(
String args[ ]) {
for
(
int
i =
0
; i <
arguments.length ; i++
) {
System.out.println (
"Arguments "
+
i +
" : "
+
arguments[ i ];
}
}
}
Le petit exemple présenté ci-dessus affiche les arguments avec leur numéro. Vous pouvez compiler ce programme, il fonctionne.
X-D. Transmettre un argument à une applet▲
On transmet un argument à une applet par l'intermédiaire du code HTML :
Les * symbolisent les valeurs que vous devez spécifier, la première le nom du paramètre et la seconde sa valeur.
X-E. Récupérer un argument à partir d'une applet▲
Pour récupérer à partir d'une applet les arguments transmis par le HTML, on utilise la méthode getParameter().
TypeDeDonnée NomDeLaVariable =
getParameter (
"nomDuParamètre"
);
String theFont =
getParameter
(
"font"
);
X-F. Applet : Palindrome▲
L'applet Palindrome vient du livre Java 2 plate-forme de Roger Cadenhead et Laura Lemay. Elle récupère et affiche le texte spécifié par …
import
java.awt.Graphics; //importation de la classe qui gère les graphismes
import
java.awt.Font; // "" qui gère les polices
import
java.awt.Color; // "" qui gère les couleurs
public
class
Palindrome extends
java.applet.Applet {
// c'est une applet !
Font f =
new
Font
(
"TimesRoman"
, Font.BOLD, 36
); // définition de la police f
String palindrome; // déclaration de la chaîne "palindrome"
public
void
paint
(
Graphics screen) {
// méthode qui servira à fixer les paramètres d'affichage
screen.setFont
(
f); // attribuer la police f à tous les textes de l'applet
screen.setColor
(
Color.red); // "" la couleur rouge
screen.drawString
(
palindrome, 5
, 50
); // écrire le texte contenu dans palindrome aux coordonnées …
}
public
void
init
(
) {
// équivalent de main() dans les applications: le prog débute
palindrome =
getParameter
(
"palindrome"
); // on récupère le paramètre
if
(
palindrome ==
null
) // s'il n'y en a pas …
palindrome =
"Spécifiez un argument, SVP"
; // … afficher ceci
}
}
XI. Les exceptions▲
XI-A. Définition▲
La cause du mauvais fonctionnement d'un programme peut être la conséquence de deux types d'erreurs : une erreur de programmation ou une erreur pendant l'exécution du programme. Si le programmeur commet une erreur de programmation, le programme ne se compilera généralement pas, mais il existe des erreurs de programmation qui surviennent après la compilation, à l'appel de la machine virtuelle par java.exe (pour je JDK 1.2 de Sun). Toutes ces erreurs peuvent et doivent être corrigées par le programmeur. Dans les deux cas précédents, le programme ne démarre pas.
Le second type d'erreur survient pendant l'exécution du programme. Ce sont en quelque sorte des « bogues ». On distingue deux catégories : les erreurs de la machine virtuelle (vous ne pouvez quasiment rien y faire), et les exceptions que vous devez gérer. Ces exceptions peuvent se produire dans beaucoup de cas, elles ont cependant plus de chance de survenir lors d'un transfert de données. Par exemple, si un programme essaie d'écrire sur un disque plein ou protégé en écriture, une exception de type IOException (input/output ou entrée/sortie de données) sera générée. La gestion de cette exception permettra au programme de ne pas « planter ». Vous pouvez spécifier ce que le programme doit faire lors de l'apparition d'exceptions.
XI-B. try…catch▲
try…catch peut être expliqué comme : « essaye ce bout de code (try), si une exception survient, attrape-la (catch) et exécute le code de remplacement (s'il y en a un) ».
try
{
//code susceptible de produire des exceptions
}
catch
(
Exception e) {
// code de remplacement, se limite souvent à un System.out.println(“Une erreur : “+e);
}
Exception est la superclasse de toutes les exceptions, elle capte toutes les exceptions. Elle fonctionne dans tous les cas, cependant il est préférable de bien canaliser l'exception en spécifiant le type d'exception le plus précis possible (voir le schéma ci-dessus). On doit spécifier un nom à cette exception créée, ici c'est e, on choisit généralement e ou ex. Vous pouvez, en raison de la portée de variables, spécifier le même nom pour toutes vos exceptions (ce nom n'est reconnu qu'à l'intérieur de catch).
XI-C. Finally▲
La clause finally permet d'exécuter le code qu'elle renferme quoiqu'il arrive. Qu'il y ait une exception ou pas, les instructions de la clause finally sont exécutées. Elle fonctionne également avec try.
try
{
// instructions à essayer de réaliser
return
;
}
finally
{
// instructions à réaliser absolument
}
return
;
XI-D. Déclarer des méthodes susceptibles de générer des exceptions▲
On utilise la clause throws dans la déclaration de méthode. Exemples :
public
boolean
myMethod (
xxx) throwsAnException {&
#8230
;}
public
boolean
myMethod (
xxx) throwsAnException, ASecondException, AThirdException {&
#8230
;}
public
void
myMethod
(
) throwsIOException {&
#8230
;}
XI-E. Générer des exceptions▲
Ceci sert à faire croire au programme qu'une exception d'un certain type est apparue.
NotInServiceException nis =
new
NotInServiceException
(
"Exception : DataBase out of use"
);
throw
nis;
On note qu'il s'agit de throw et pas de throws.
XI-F. Créer des exceptions▲
Dans des programmes complexes, il se peut que les exceptions standard de Java ne soient pas suffisantes et que vous ayez par conséquent besoin de créer vos propres définitions. Dans ce cas, vos exceptions devront hériter d'une exception plus haute dans la hiérarchie.
public
class
SunSpotException extends
Exception {
public
SunSpotException (
) {}
public
SunSpotException
(
String msg) {
super
(
msg);
}
}
XI-G. En Pratique▲
Au début, vous ne saurez pas quand utiliser ou ne pas utiliser les exceptions. Les automatismes viennent avec la pratique… Il faut savoir que les exceptions ralentissent les programmes, n'en usez donc pas trop souvent… De toute façon, le compilateur générera un message d'erreur si à un endroit vous avez oublié d'intercepter une exception, et en plus, il vous indiquera quelle exception vous devez intercepter !
XII. Applets : quelques généralités▲
XII-A. Introduction▲
Ce chapitre présente des généralités sur les applets (principalement les méthodes d'une applet). Mais, d'abord, il faut expliquer ce qu'est une applet : une applet est un programme qui définit automatiquement (sans action du programmeur ni de l'utilisateur) une zone graphique dans laquelle le programme s'exécute. Une applet est exécutable par l'intermédiaire de la machine virtuelle d'un navigateur Web. Elle doit donc être insérée dans une page HTML.
XII-B. Restrictions▲
On dit souvent que Java ne permet pas de lire ou d'écrire sur un disque dur. C'est faux. Les applets exécutées par les navigateurs comme IE5 ou Communicator 4.7 subissent des restrictions dans la mesure ou certaines des potentialités de JAVA ne sont pas prises en compte par défaut. L'utilisateur doit l'accepter (en validant manuellement dans une boite de dialogue) pour que ces fonctionnalités soient disponibles. Ceci permet notamment de garantir une certaine sécurité. Ainsi, par défaut les applets ne peuvent pas lire/écrire sur un disque dur, un serveur autre que celui où elles sont stockées (elles ne peuvent donc pas avoir accès à vos programmes ou formater votre disque ;-) sauf si vous les y autorisez). Un système de signature numérique a été mis en place pour les applets nécessitant des niveaux de liberté supérieurs à celui par défaut. Vous pouvez obtenir ces certificats auprès d'entreprises comme VerySign et signer vos archives jar. Enfin, tout ceci concerne uniquement les applets et nullement les applications.
XII-C. Création d'une applet▲
La classe principale doit étendre la classe Applet. Les importations de classes se font comme pour les applications. Il n'y a pas de méthode main().
public
class
*
extends
java.applet.Applet {&
#8230
;}
// création d'applet Java 1.1 et antérieur
public
class
*
extends
Japplet {&
#8230
;}
// création d'applet Java 2
XII-D. Méthodes d'une applet▲
XIII. Applets : classes Graphics : le projet Floride▲
Il est possible de télécharger les sources du programme.
XIII-A. Introduction▲
Ce chapitre présente les rudiments graphiques disponibles pour une applet. Nous verrons comment dessiner des lignes, rectangles, ovales, arcs de cercle, chaînes de texte… Avant de commencer, il faut savoir qu'une applet est en gros une application exécutée par l'intermédiaire d'un navigateur web, qui définit automatiquement un cadre de travail. Les dimensions de ce cadre sont définies par le code HTML accompagnant l'applet. La plupart de ces procédés appartiennent à Java 1.1. Dans Java 2, on a une classe Graphics2D beaucoup plus performante, mais dans la mesure où elle n'est pas utilisable pour les applets destinées à IE5 ou Netscape 4.7, la classe Graphics vous sera bien utile pour des graphiques simples.
XIII-B. Système de coordonnées▲
On place des éléments dans le cadre d'une applet en définissant leur position par des coordonnées. Le repère a pour origine le point le plus en haut et le plus à gauche du cadre.
XIII-C. Segments de droites▲
Pour tracer le segment de droite [AB], on utilise la commande drawLine(xA,yA,xB,yB).
XIII-D. Rectangles▲
Il existe 4 types de rectangles : rectangle aux angles droits vide ou plein, rectangle aux angles arrondis vide ou plein.
drawRect
(
x,y,L,h); //
fillRect
(
x,y,L,h);
drawRoundRect
(
x,y,L,h,&
#946
;,&
#955
;);
fillRoundRect
(
x,y,L,h, &
#946
;,&
#955
;);
(x,y) sont les coordonnées de l'angle supérieur gauche du rectangle.
L et h sont la largeur et la hauteur du rectangle.
β et λ sont les valeurs de largeur et de hauteur de l'angle.
XIII-E. Polygones▲
Les polygones sont des ensembles de segments de droites joints. Il y a 2 types de polygones : les vides et les pleins (comme les rectangles). On peut les construire de 2 manières : soit en définissant manuellement tous les segments qui définissent le polygone soit en créant une matrice de coordonnées x et une autre de y.
polygon
(
int
[], int
[], int
);
Le 3e entier représente le nombre de points du polygone. Un petit exemple (pas tout à fait fonctionnel) :
int
x[] =
{
10
, 20
, 30
, 40
, 50
}
;
int
y[] =
{
50
, 60
, 70
, 80
, 90
}
;
int
points =
x.length;
Polygon poly =
new
Polygon
(
x, y, points);
*
.drawPolygon
(
poly);
L'astérisque peut changer de valeur, on trouve souvent screen ou g. Nous verrons cela plus tard.
XIII-F. Ovales▲
Soient (x,y) les coordonnées du point supérieur gauche,
drawOval
(
x,y,largeur,hauteur);
fillOval
(
);
XIII-G. Arcs de cercle▲
Là, il faut un schéma…
drawArc
(
x,y,largeur,hauteur,angle,nombreDeDegres);
fillArc
(
);
(x,y) les coordonnées du point haut gauche
angle = l'angle à partir duquel l'arc commence (ici, 90°)
nombreDeDegres = nombre de degrés que parcourt l'arc (ici, 180°)
XIII-H. Copier/Couper▲
Ce n'est pas vraiment un copier/coller mais on peut s'en servir comme… Ces commandes copient ou coupent une zone rectangulaire.
copyArea
(
);
clearRect
(
);
XIII-I. Texte et polices▲
Pour écrire du texte, on utilise la commande drawString(texte, x, y). On peut mettre une police en état normal, italique, ou gras :
Font.PLAIN ; //état normal
Font.BOLD ; // état gras
Font.ITALIC ; // état italique
Un petit exemple (encore pas tout à fait fonctionnel) :
Font f =
new
Font (
"TimesRoman"
, Font.BOLD +
Font.ITALIC, 24
) ; // 24 est la taille
Screen.setFont
(
f) ;
Screen.drawString
(
"Bonjour !"
, 30
, 30
);
Pour obtenir des informations sur du texte :
stringWidth
(
String) // largeur totale de la chaîne
charWidth
(
char
) // largeur du caractère
getHeight // hauteur de la police
XIII-J. Applet : Floride▲
import
java.awt.Graphics;
import
java.awt.Polygon;
public
class
Floride extends
java.applet.Applet {
public
void
paint
(
Graphics screen) {
screen.drawString
(
"Florida"
, 185
, 75
);
screen.drawLine
(
185
,80
,222
,80
);
screen.drawRect
(
2
, 2
, 345
, 345
);
screen.drawRoundRect
(
182
,61
,43
,24
,10
,8
);
int
x[] =
{
10
, 234
, 253
, 261
, 344
, 336
, 295
, 259
, 205
, 211
,
195
, 191
, 120
, 94
, 81
, 12
, 10
}
;
int
y[] =
{
12
, 15
, 25
, 71
, 209
, 278
, 310
, 274
, 188
, 171
, 174
,
118
, 56
, 68
, 49
, 37
, 12
}
;
int
pts =
x.length;
Polygon poly =
new
Polygon
(
x, y, pts);
screen.drawPolygon
(
poly);
screen.fillOval
(
235
,140
,15
,15
);
screen.fillOval
(
225
,130
,15
,15
);
screen.fillOval
(
245
,130
,15
,15
);
for
(
int
ax =
50
; ax <
150
; ax +=
10
)
for
(
int
ay =
120
; ay <
320
; ay +=
10
)
screen.drawArc
(
ax, ay, 10
, 10
, 0
, -
180
);
}
}
Une petite explication : les codes de ce chapitre n'étaient pas fonctionnels, car ils n'étaient pas dans la méthode paint() de l'applet. Ici la méthode paint est déclarée avec l'objet Graphics nommé screen, on aurait pu l'appeler g. screen. g.screen doit être mis avant chaque instruction qui trace une ligne ou une chaîne. Le fichier class généré par la compilation doit être lancé par l'intermédiaire d'un navigateur compatible Java 2 (disons que l'appletviewer et toujours la meilleure alternative), avec le code HTML suivant :
<body bgcolor
=
"#c4c4c4"
>
<div align
=
"center"
>
<applet code
=
"Floride.class"
height
=
350 width
=
350>
</applet>
</div>
</body>
Cet exemple est tiré de l'excellent livre JAVA 2 de Roger Cadenhead & Laura Lemay aux éditions Campus Press (titre original : Teach yourself Java in 21 days).
XIV. Applets : Java2D (Graphics2D) : le projet Floride2D▲
Il est possible de télécharger les sources du programme.
XIV-A. Introduction▲
En Java 2, Java2D remplace les classes Graphics de Java 1. Java2D est plus performant et gère les couleurs.
XIV-B. Convertir un objet en 2D▲
Pour créer des graphiques avec Java 2D, on déclare la méthodepaint() de l'applet comme avant, mais dans les instructions qui accompagnent cette méthode, on doit convertir l'objet Graphics en objet Graphics2D.
public
void
paint (
Graphics screen) {
Graphics2D screen2D =
(
Graphics2D) screen;
// suite des instructions
}
XIV-C. Couleurs▲
Pour colorer quelque chose, on doit d'abord créer un objet Color et ensuite attribuer cet objet à la chose que l'on veut colorer.
Color c1 =
new
Color
(
0.807
F, 1
F, 0
F) ; // nombres à virgule flottante
Color c2 =
new
Color
(
255
, 204
, 102
); // nombres normaux
screen2D.setColor
(
Color.yellow); // couleur basique prédéfinie
La 3e instruction indique que toutes les opérations de dessin se feront dans la couleur définie (ici, le jaune). Pour modifier les couleurs de fond d'écran (background) et de dessin (foreground), on utilise ces méthodes :
setBackground
(
Color.white);
setForeground
(
Color.black);
Voici un tableau avec les principales couleurs :
Nom de la couleur en Java |
Valeur RVB |
En français |
black |
(0,0,0) |
Noir |
blue |
(0,0,255) |
Bleu |
cyan |
(0,255,255) |
Cyan (bleu primaire) |
darkGray |
(64,64,64) |
Gris foncé |
gray |
(128,128,128) |
Gris |
green |
(0,255,0) |
Vert |
lightGray |
(192,192,192) |
Gris clair |
magenta |
(255,0,255) |
Magenta (rouge primaire) |
orange |
(255,200,0) |
Orangé |
pink |
(255,175,175) |
Rose |
red |
(255,0,0) |
Rouge (scarlet) |
white |
(255,255,255) |
Blanc |
yellow |
(255,255,0) |
Jaune |
Les couleurs RVB représentent les valeurs entre 0 et 255 de rouge, vert et bleu. En fonction de leur concentration, les couleurs se nuancent. La capture d'écran de Macromedia Freehand illustre le choix d'une couleur Camel (189,156,82).
XIV-D. Dégradés de couleurs▲
Le titre est très parlant…
GradientPaint
(
x1,y1,Color1,x2,y2,Color2,boolean
);
x1,x2 et Color1 représentent les coordonnées et la couleur du point de départ du dégradé.
x2,y2 et Color2 représentent les coordonnées et la couleur du point d'arrivée du dégradé.
boolean est true si le dégradé est cyclique, sinon, il n'est pas nécessaire de le préciser.
XIV-E. Définir un type de trait▲
Une des nouveautés de Java2D est la possibilité de faire de beaux traits. Ce qui est beau, ce sont les extrémités ou les raccords entre deux traits.
Traits :
- CAP_BUT
- CAP_SQUARE
- CAP_ROUND
Jointures
- JOIN_MITER
- JOIN_ROUND
- JOIN_BEVEL
Vous remarquerez qu'il existe une différence de longueur entre les traits 1 et 2. C'est l'unique différence entre CAP_BUT (le classique) et CAP_SQUARE.
Pour créer un trait, il faut utiliser la méthode setStroke() de l'objet BasicStroke(). Elle admet trois arguments :
- Valeur float pour la largeur de la ligne (en pixel).
- Valeur int pour le style d'ornement, extrémité de ligne.
- Valeur int pour le style d'ornement, jonction entre deux lignes.
BasicStroke pen =
BasicStroke (
2.0
f,
BasicStroke.CAP_BATT,
BasicStroke.JOIN_ROUND);
screen2D.setStroke
(
pen);
XIV-F. Créer des objets à dessiner▲
Les arguments sont les mêmes que pour des objets classiques (allez donc voir le chapitre Graphics pour plus d'informations). Tous ces objets font partie de java.awt.geom.
Lignes :
Lines2D.Float ligne =
new
Line2D.Float
(
);
Rectangles :
Rectangle2D.Float rectangle =
new
Rectangle2D.Float
(
);
Ellipses :
Ellipse2D.Float ellipse =
new
Ellipse2D.Float
(
);
Arcs :
Arcs2D.Float =
new
Arc2D.Float
(&
#8230
;&
#8230
;.Arc2D.OPEN);
- Arc2D.OPEN
- Arc2D.CHORD
- Arc2D.PIE
Polygones :
GeneralPath polly =
new
GeneralPath
(
); // création d'un "chemin" encore "vide"
polly.moveTo
(
5
f,0
f); // premier trait
polly.moveTo
(
205
f,0
f); // deuxième trait
polly.moveTo
(
5
f,90
f); // troisième trait
polly.closePath
(
); // on referme automatiquement par un quatrième "plus court possible" trait
XIV-G. Applet Floride2D▲
Cette applet est une amélioration de Floride présentée au chapitre précédent. Bien sûr, elle fait également partie de l'excellent livre Java 2 Plate-Forme de Roger Cadenhead et Laura Lemay aux éditions CampusPress.
import
java.awt.*;
import
java.awt.geom.*;
public
class
Floride2D extends
java.applet.Applet {
public
void
paint
(
Graphics screen) {
Graphics2D screen2D =
(
Graphics2D)screen;
setBackground
(
Color.blue);
// dessine les vagues
screen2D.setColor
(
Color.white);
BasicStroke pen =
new
BasicStroke
(
2
F,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
screen2D.setStroke
(
pen);
for
(
int
ax =
10
; ax <
340
; ax +=
10
)
for
(
int
ay =
30
; ay <
340
; ay +=
10
) {
Arc2D.Float wave =
new
Arc2D.Float
(
ax, ay,
10
, 10
, 0
, 180
, Arc2D.OPEN);
screen2D.draw
(
wave);
}
// dessine la Floride
GradientPaint gp =
new
GradientPaint
(
0
F,0
F,Color.green,
50
F,50
F,Color.orange,true
);
screen2D.setPaint
(
gp);
GeneralPath fl =
new
GeneralPath
(
);
fl.moveTo
(
10
F,12
F);
fl.lineTo
(
234
F,15
F);
fl.lineTo
(
253
F,25
F);
fl.lineTo
(
261
F,71
F);
fl.lineTo
(
344
F,209
F);
fl.lineTo
(
336
F,278
F);
fl.lineTo
(
295
F,310
F);
fl.lineTo
(
259
F,274
F);
fl.lineTo
(
205
F,188
F);
fl.lineTo
(
211
F,171
F);
fl.lineTo
(
195
F,174
F);
fl.lineTo
(
191
F,118
F);
fl.lineTo
(
120
F,56
F);
fl.lineTo
(
94
F,68
F);
fl.lineTo
(
81
F,49
F);
fl.lineTo
(
12
F,37
F);
fl.closePath
(
);
screen2D.fill
(
fl);
// dessine les ovales
screen2D.setColor
(
Color.black);
BasicStroke pen2 =
new
BasicStroke
(
);
screen2D.setStroke
(
pen2);
Ellipse2D.Float e1 =
new
Ellipse2D.Float
(
235
,140
,15
,15
);
Ellipse2D.Float e2 =
new
Ellipse2D.Float
(
225
,130
,15
,15
);
Ellipse2D.Float e3 =
new
Ellipse2D.Float
(
245
,130
,15
,15
);
screen2D.fill
(
e1);
screen2D.fill
(
e2);
screen2D.fill
(
e3);
}
}
Ce code HTML est à joindre :
Et voilà !
XV. Les Modificateurs▲
XV-A. Définition▲
Les modificateurs sont des mots clé qui permettent de définir l'accessibilité de méthodes, variables ou classes dans le programme dans lequel ils sont utilisés ou dans d'autres programmes ayant une interaction avec le programme dans lequel ils sont utilisés (héritage…).
XV-B. Accessibilité▲
En Java, il y a 4 niveaux de restriction d'accessibilité : public, protected, par défaut, private (du moins au plus restrictif).
XV-B-1. Public▲
Les méthodes et les variables sont accessibles (et modifiables pour les variables) par n'importe quelle classe.
XV-B-2. Protected▲
Limite l'accès aux sous-classes de la classe ou aux autres classes du même package ; les autres ne peuvent pas y accéder.
XV-B-3. Par défaut▲
Pareil à protected sauf l'accès par une sous-classe d'un package différent qui est restreint.
XV-B-4. Private▲
Les méthodes et variables déclarées ne sont visibles qu'à l'intérieur de leur propre classe.
XV-C. Résumé▲
XV-D. D'autres modificateurs▲
Sur un point, la définition proposée plus haut est fausse : les modificateurs ne font pas que modifier l'accessibilité. Ils modifient en général les propriétés des classes, méthodes et variables. Certains doivent vous être familiers :
- static : crée des méthodes et variables de classe (voir chapitre sur les variablesLes Variables : le projet Chocos)
- final : finalise les méthodes, variables et classes (voir chapitre sur les méthodesMéthodes : le projet ReHello)
- abstract : déclare une classe ou méthode abstraite (voir chapitre sur les classesClasses et Héritage)
- synchronized : accès à une donnée par 1 seul Thread
- volatile
XVI. Insérer des sons dans un programme (exemple pour une applet)▲
Il est possible de télécharger les sources du programme.
XVI-A. Introduction▲
Destinées au web, les applets sont le plus souvent utiles de par leurs fonctionnalités multimédias. Nous allons voir dans ce chapitre comment jouer un son dans une applet. Ce cours n'a pas beaucoup de points techniques, c'est plutôt une « recette ».
XVI-B. Accéder aux fichiers▲
Les fichiers de sons lisibles par la JVM sont au format AIFF, WAV, AU, RMF, MIDI(1 et 2). Sous les versions antérieures à Java 2, seul le format AU était supporté.
L'accès aux fichiers se fait grâce à l'appel d'une URL :
AudioClip clip =
getAudioClip
(
getCodeBase
(
), "*.*"
) ; // pour applets
AudioClip clip =
new
AudioClip
(
"*.*); // pour applications
Les *.* représentent le nom du fichier et son extension. (ex-: « son.wav »).
Sur les clips audio, on peut appeler les méthodes suivantes : play(), stop(), loop().
XVI-C. Exemple concret▲
Cet exemple est tiré du grand livre JAVA 2 plate-forme de Roger Cadenhead & Laura Lemay ed. Campus Press
// importation des classes nécessaires à la lecture des sons
import
java.awt.Graphics;
import
java.applet.AudioClip;
public
class
AudioLoop extends
java.applet.Applet implements
Runnable {
// voir chapitre sur les Threads
// création des 2 objets AudioClip
AudioClip bgSound;
AudioClip beep;
Thread runner;
// voir le chapitre sur les Threads
public
void
start
(
) {
if
(
runner ==
null
) {
runner =
newThread
(
this
);
runner.start
(
);
}
}
// l'applet s'arrête arrêt de tous les sons en cours de lecture
public
void
stop
(
) {
if
(
runner !=
null
) {
if
(
bgSound !=
null
)
bgSound.stop
(
);
runner =
null
;
}
}
// initialisation de l'applet
public
void
init
(
) {
// on indique quels sont les fichiers à lire
bgSound =
getAudioClip
(
getCodeBase
(
),"loop.au"
);
beep =
getAudioClip
(
getCodeBase
(
), "beep.au"
);
}
// l'applet débute
public
void
run
(
) {
if
(
bgSound !=
null
) // le fichier loop.au n'est pas en cours de lecture…
bgSound.loop
(
); // … alors, il est lu en boucle
Thread thisThread =
Thread.currentThread
(
);
while
(
runner ==
thisThread) {
try
{
Thread.sleep
(
5000
); // 5 secondes d'arrêt du programme
}
catch
(
InterruptedException e) {
}
if
(
beep !=
null
) // si le fichier beep.au n'est pas en cours de
//lecture…
beep.play
(
); // … le lire
}
}
// méthode d'affichage du texte accompagnant la lecture des sons
public
void
paint
(
Graphics screen) {
screen.drawString
(
"Playing Sounds …"
, 10
, 10
);
}
}
Les 2 fichiers sonores sont disponibles à l'adresse suivante : http://perso.wanadoo.fr/guillaume/Exemples/AudioLoop/
À insérer accompagné du HTML suivant :
Pas d'image… c'est du son !
XVII. Animations (exemple pour une applet)▲
Il est possible de télécharger les sources du programme.
XVII-A. Introduction▲
Ce chapitre a pour but de montrer comment créer des séquences animées et surtout comment réduire l'effet de vacillement présent dans certaines animations. Pour créer une animation, on affichera une suite d'images à grande vitesse (méthode de création des GIF animés). Pour cela, il faudra utiliser les threads (voir chapitre sur les Threads pour plus de renseignements), les méthodes de dessin Graphics de l'applet, les méthodes de l'applet (init(), update()…) et la mise en mémoire tampon.
XVII-B. Réduire les vacillements▲
Pour créer une animation, il suffit donc d'afficher une première image, de l'effacer, d'afficher une seconde, de l'effacer, d'en afficher une troisième et de l'effacer et ainsi de suite à très grande vitesse. Se pose alors le problème du rafraîchissement de l'écran : Java va redessiner toute la zone de l'applet, ce qui nous donne une impression d'affichage saccadé. Pour résoudre ce problème, on peut avoir recours à deux méthodes : utiliser la méthode repaint() (synthèse de paint() et de update()) en le redéfinissant pour qu'elle n'efface que les zones concernées par le changement. Cette solution est lourde et incommode. La seconde solution consiste à redéfinir paint() et update() en utilisant une double mise en mémoire tampon (Double-buffering), les images et seulement les images seront stockées en mémoire tampon, ensuite on affichera cette mémoire tampon (donc seulement les images et pas le reste du cadre).
XVII-C. 1re méthode▲
À tout hasard, voici une redéfinition de update() :
public
void
update
(
Graphics g) {
g.setColor
(
getBackground
(
)) ;
g.fillRect
(
0
,0
,size
(
).width, size
(
).height);
g.setColor
(
getForeground
(
));
paint
(
g);
}
public
void
update
(
Graphics screen) {
// utilisation de la méthode précédemment définie
paint
(
screen);
}
XVII-D. 2e méthode▲
- Créer des variables d'instance pour stocker les images ;
- créer les images et le contexte graphique au moment d'initialisation de l'applet ;
- effectuer les opérations de dessin dans le tampon ;
- dessiner le tampon à l'écran à la fin de la méthode paint().
// 1
Images offScrenImage ;
Graphics offScreen ;
// 2
offScreenImage =
createImage
(
size
(
).width, size
(
).height);
offscreen =
offscreenImage.getGraphics
(
);
// 3
offscreen.drawImage
(
bug, 10
, 10
, this
);
screen.drawImage
(
offscrenImage, 0
, 0
, this
);
// 4
public
void
update
(
Graphics g) {
paint
(
g);
}
XVII-E. Application : applet Neko▲
L'applet Neko est issue de JAVA 2 le programmeur par Roger Cadenhead et Laura Lemay aux éditions Campus Press, elle représente un petit chat parcourant la fenêtre de l'applet. La technique utilisée est celle des threads. La technique du programme est simple : pour chaque action du chat on écrit une méthode qui appelle l'image correspondante un certain nombre de fois. On spécifie ensuite ce nombre en fonction de la durée de l'animation.
import
java.awt.Graphics;
import
java.awt.Image;
import
java.awt.Color;
public
class
Neko extends
java.applet.Applet
implements
Runnable {
// nécessaire pour les threads
Image nekoPics[] =
newImage[9
]; // matrice d'images
Image currentImg; // image courante
Thread runner; // déclaration du thread
int
x; // abscisse de l'image
int
y =
50
; // son ordonnée
public
void
init
(
) {
// initialisation de l'applet
String nekoSrc[] =
{
"right1.gif"
, "right2.gif"
,
"stop.gif"
, "yawn.gif"
, "scratch1.gif"
,
"scratch2.gif"
,"sleep1.gif"
, "sleep2.gif"
,
"awake.gif"
}
; // on remplit la matrice avec les images
for
(
int
i=
0
; i <
nekoPics.length; i++
) {
nekoPics[i] =
getImage
(
getCodeBase
(
),
"images/"
+
nekoSrc[i]);
}
}
public
void
start
(
) {
//méthode start de l'applet, opérations sur les threads
if
(
runner ==
null
) {
runner =
newThread
(
this
);
runner.start
(
);
}
}
public
void
stop
(
) {
// comment arrêter l'animation
runner =
null
;
}
public
void
run
(
) {
// lancer l'applet
setBackground
(
Color.white);
// part d'un côté de l'écran vers le milieu
nekoRun
(
0
, size
(
).width /
2
);
// pause
currentImg =
nekoPics[2
];
repaint
(
);
pause
(
1000
);
// baille 3 fois
currentImg =
nekoPics[3
];
repaint
(
);
pause
(
1000
);
// se gratte 4 fois
nekoScratch
(
4
);
// dort 5 "temps"
nekoSleep
(
5
);
// se réveille et s'en va
currentImg =
nekoPics[8
];
repaint
(
);
pause
(
500
);
nekoRun
(
x, size
(
).width +
10
);
}
void
nekoRun
(
int
start, int
end) {
// méthode qui permet d'exécuter les
//mouvements
// définis précédemment ici: courir et bailler)
for
(
int
i =
start; i <
end; i +=
10
) {
x =
i;
// images pour le bâillement
if
(
currentImg ==
nekoPics[0
])
currentImg =
nekoPics[1
];
else
currentImg =
nekoPics[0
];
repaint
(
);
pause
(
150
);
}
}
void
nekoScratch
(
int
numTimes) {
// pour se gratter…
for
(
int
i =
numTimes; i >
0
; i--
) {
currentImg =
nekoPics[4
];
repaint
(
);
pause
(
150
);
currentImg =
nekoPics[5
];
repaint
(
);
pause
(
150
);
}
}
void
nekoSleep
(
int
numTimes) {
// … dormir
for
(
int
i =
numTimes; i >
0
; i--
) {
currentImg =
nekoPics[6
];
repaint
(
);
pause
(
250
);
currentImg =
nekoPics[7
];
repaint
(
);
pause
(
250
);
}
}
void
pause
(
int
time) {
// une pause dans l'animation
try
{
Thread.sleep
(
time);
}
catch
(
InterruptedException e) {
}
}
public
void
paint
(
Graphics screen) {
// affichage de l'animation
if
(
currentImg !=
null
)
screen.drawImage
(
currentImg, x, y, this
);
}
}
XVIII. AWT - Interface Utilisateur▲
XVIII-A. Introduction▲
AWT (Abstract Windowing Toolkit) est une série de classes Java permettant de construire une interface utilisateur (UI en anglais ou IU). AWT fut la première UI de Java, elle est maintenant largement remplacée par Swing (sauf pour les applets, car Swing est une nouveauté de Java 2). Une interface utilisateur se compose principalement de :
- une fenêtre de travail ;
- une zone où afficher les composants, dans cette fenêtre de travail ;
- une mise en page des composants (en ligne, en colonne…) ;
- des composants insérés dans cette fenêtre (boutons, cases à cocher, menus, barre de tâches…) ;
- des gestionnaires d'événements qui répondent par un comportement particulier aux actions de l'utilisateur.
Tout ceci est un peu compliqué à première vue et il peut paraître maladroit de dire qu'il faut définir une mise en page des composants avant de dire qu'il faut des composants, mais en Java, les opérations se font généralement dans cet ordre.
Dans la mesure où AWT est utilisé majoritairement pour les applets, vous n'aurez le plus souvent pas à vous occuper de la création de la fenêtre de travail (il s'agit du navigateur) ni de la zone d'affichage des composants (il s'agit de l'applet elle-même). Ces deux étapes sont cependant nécessaires à l'utilisation d'une UI dans une application.
Nous commencerons par étudier les composants, puis leur mise en page, car même si ces opérations sont inversées en programmation, il est plus facile de les concevoir dans cet ordre, et finalement les cadres…
XVIII-B. Les Composants▲
La bibliothèque de composants AWT est assez limitée, Swing la complète. Nous ne verrons donc que les composants « classiques ».
XVIII-B-1. Boutons▲
Il n'y a pas beaucoup d'explications à donner sur un bouton…
Button leNomDuBouton =
new
Button
(
"Texte du bouton ici !"
);
add
(
leNomDuBouton);
XVIII-B-2. Label▲
Un label est une zone d'affichage d'un texte. C'est le programmeur qui définit le texte et l'utilisateur ne peut pas le changer.
label
(
) // un label tout simple (et vide)
label
(
String) // la chaîne String représente le texte à afficher dans ce label
label
(
String, int
) // int peut être label.RIGHT, label.CENTER ou label.LEFT, ce qui détermine
//où le texte devra être affiché dans le label.
Pour le créer :
label leNomDuLabel =
new
label
(
"Bonjour! "
, label.######);
add
(
leNomDuLabel);
leNomDuLabel.setText
(
"Zoubida !!!!!!!!!!! "
);
Note : pour insérer un composant, la méthode est toujours la même, elle ne sera donc par répétée.
On peut utiliser la méthode setText()pour redéfinir le texte du label (par exemple en résultat d'une action de l'utilisateur)
XVIII-B-3. Cases à cocher▲
On coche une case pour valider l'option correspondante. On peut cocher toutes les cases, certaines, ou aucune.
Checkbox
(
) // case toute simple
Checkbox
(
String) // String est le libellé de la case
// Méthode à appeler sur un Checkbox pour cocher par défaut une option :
setState
(
boolean
)
XVIII-B-4. Boutons Radio▲
Les boutons radio sont des sortes de cases, on ne peut cocher qu'une seule case dans tout le groupe.
Un exemple :
CheckboxGroup p =
new
CheckboxGroup
(
);
Checkbox p1 =
new
Checkbox
(
"Manger"
, p, true
);
Checkbox p2 =
new
Checkbox
(
"Boire"
, p, false
);
// On rattache chaque bouton radio à un groupe, dans ce groupe, un seul est sélectionnable.
// p1 est cochée par défaut (boolean = true)
XVIII-B-5. Listes de choix▲
Les listes de choix sont des menus déroulants, on ne peut sélectionner qu'une seule option.
Choice c =
new
Choice
(
) ; // création du menu
c.addItem
(
"Bonjour! "
); // ajout d'une entrée avec Java 1.02
c.add
(
"Au revoir!"
); // ajout d'une entrée avec Java 2
Voici les méthodes que l'on peut employer avec Choice :
getItem
(
int
) // renvoie le numéro de la case sélectionnée par l'utilisateur
countItems
(
) // renvoie le nombre de cases, pour Java 2
getItemsCount
(
) // même chose pour Java 1.02
getSelectedItem
(
) // renvoie la position de l'objet sélectionné
Select
(
int
) // sélectionne l'élément n°x
Select
(
String) // sélectionne l'élément ayant le nom indiqué par String
XVIII-B-6. Champs de texte▲
Ceci devient intéressant : ce composant permet de capturer un texte (court) entrépar l'utilisateur.
TextField
(
) // vide
TextField
(
int
) // spécifie la largeur (déconseillé en Java 2)
TextField
(
String) // la chaîne entrée dans le TextField
TextField
(
String, int
) // les 2 combinés
Méthodes utiles :
getText
(
) // retourne le texte contenu dans le champ
setText
(
) // définit un texte
setEditable
(
boolean
) // définit si l'utilisateur peut éditer le texte du champ, true = il peut
isEditable
(
) // indique si le champ est éditable (retourne un boolean)
setEchoCharacter
(
'*'
) // remplace les caractères tapés par une *, pour Java 1.02
setEchoChar
(
) // même chose pour Java 2
XVIII-B-7. Zones de texte▲
Ce sont de grands champs de texte permettant à l'utilisateur de raconter sa vie ;-).
Les méthodes sont les mêmes que celles du champ de texte (sauf setEchoChar()).
TextArea
(
) // tout simple
TextArea
(
int
, int
) // nombre de lignes et largeur d'une ligne
TextArea
(
String) // avec une valeur de départ …
TextArea
(
String, int
, int
) // les 2 combinés
XVIII-B-8. Listes à défilement▲
Ce sont des listes de choix dans lesquelles on peut sélectionner plusieurs entrées.
List
(
)
List
(
int
, boolean
) // nombre d'entrées visibles en même temps, si plusieurs éléments peuvent
//être sélectionnés (true), ou non (false)
XVIII-B-9. Barres de défilement▲
Elles permettent de « scroller » ou de faire défiler le texte pour voir le bas d'une page (les barres à droite dans les traitements de texte, par exemple).
ScrollBar
(
int
, int
, int
, int
, int
)
Dans l'ordre, les int correspondent à :
- l'orientation : Scrollbar.VERTICAL ou Scrollbar.HORIZONTAL ;
- valeur initiale du niveau de la barre de défilement ;
- largeur globale du curseur, 0 = valeur de départ ;
- valeur minimale de la barre ;
- valeur maximale de la barre.
XVIII-C. Layouts▲
Il existe plusieurs types de layouts qui correspondent à différentes techniques de disposition des composants. AWT possède par défaut 5 layouts : FlowLayout, GridLayout, BorderLayout, CardLayout, GridBagLayout. Si vous utilisez une IDE de développement graphique comme Borland JBuilder, Symantec VisualCafé ou IBM VisualAge, vous rencontrerez de nouveaux layouts, plus performants que ceux fournis par défaut. Ils possèdent cependant plusieurs défauts : premièrement il faut que l'utilisateur possède le package duquel est issu le layout. Deuxièmement, les proportions dans le placement des composants ne sont souvent pas conservées lors du redimensionnement de la fenêtre. Par exemple, un XYLayout spécifie les coordonnées du composant dans un cadre, si ce cadre est redimensionné, les proportions ne sont pas gardées ; alors qu'elles sont conservées avec un layout qui placerait un composant à 50 % par rapport à la hauteur de la fenêtre et 40 % en fonction de sa largeur.
XVIII-C-1. FlowLayout▲
Ce layout dispose tous les composants à la suite, en ligne, de gauche à droite.
FlowLayout flow =
new
FlowLayout
(
FlowLayout.LEFT) ;
setLayout
(
flow);
XVIII-C-2. GridLayout▲
GridLayout dispose les composants à la suite, sur 1 seule ligne.
BridLayout grid =
new
GridLayout
(
a,b,c,d) ;
SetLayout
(
grid);
// a = nombre de lignes
// b = nombre de colones
// c = espacement horizontal
// d = espacement vertical
XVIII-C-3. BorderLayout▲
Ce layout dispose les éléments en 5 parties : Nord, Sud, Est, Ouest, Centre.
BorderLayout bd =
new
BorderLayout
(
a,b) ;
setLayout
(
bd);
// a = espacement horizontal
// b = espacement vertical
Button b =
new
Button
(
"BBBB!"
);
add
(
"NORTH"
, b);
// Au choix: NORTH, SOUTH, EAST, WEST, CENTER
XVIII-C-4. CardLayout▲
C'est un layout un peu particulier : « à onglets ».
XVIII-C-5. GridBagLayout▲
C'est le plus intéressant des layouts proposés par AWT. Il est cependant plus compliqué d'utilisation.
- Concevoir une grille, placer au moins 1 élément par case (1 élément peut prendre plusieurs cases.)
Numéroter cette grille selon le schéma suivant : -
Créer la méthode buildConstraints() ;
Sélectionnezvoid
buildConstraints
(
GridBagConstraints gbc,int
gx,int
gy,int
gw,int
gh,int
wx,int
wy){
gbc.gridx=
gx; gbc.gridy=
gy; gbc.gridwidth=
gw; gbc.gridheight=
gh; gbc.weightx=
wx; gbc.weighty=
wy;}
// gw et gh = le nombre de cellules sur lesquelles le composant s'étend
// gx, gy = les coordonnées du composant, par exemple 0.2 pour le bouton OK
// wx et wy = largeur et profondeur des lignes.
-
Ajouter les composants ;
Sélectionnez// Création du layout
GridBagLayout gridbag=
new
GridBagLayout
(
); GridBagConstraints constraints=
new
GridBagConstraints
(
);SetLayout
(
gridbag);// Exemple pour le label NOM
buildConstraints
(
constraints,0
,0
,1
,1
,10
,40
); constraints.fill=
GridBagConstraints.NONE; constraints.anchor=
GridBagConstraints.EAST; Label label1=
new
Label
(
"Nom "
, Label.LEFT); gridbag.setConstraints
(
label1, constraints);add
(
label1);// Exemple pour le textfield du mot de passe
buildConstraints
(
constraints,1
,1
,1
,1
,0
,0
); constraints.fill=
GridBagConstraints.HORIZONTAL; constraints.anchor=
GridBagConstraints.CENTER; TextField tpas=
new
TextField
(
); tpas.setEchoChar
(
'*'
); gridbag.setConstraints
(
tpas, constraints);add
(
tpas);// Faire de même pour les autres composants
- Fill détermine dans quel sens l'étirement des composants doit se faire (vers la droite, gauche, haut, bas…) BOTH (2 sens), NONE (plus petite taille possible), HORIZONTAL (étirement horizontal), VERTICAL (…).
Anchor définit comment les composants qui ne remplissent pas toute une cellule doivent être disposés. NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTH, SOUTHEAST, WEST, NORTHWEST.
XVIII-C-6. Insets▲
La méthode insets() (ou getInsets() en Java 2) détermine les espacements en HAUT, BAS, GAUCHE, DROITE (dans cet ordre) entre le bord de la fenêtre et le layout. (On l'utilise généralement avec GridLayout).
public
Insets insets
(
) {
return
new
Insets
(
haut, bas, gauche, droite);
}
XVIII-C-7. Exemple complet▲
Vous devez maintenant être en mesure de comprendre pratiquement tout le code écrit pour mon applet Convert. Cette applet est disponible à l'adresse suivante : http://perso.wanadoo.fr/guillaume/Programmes/Convert/.
Elle ne fonctionne pas avec IE5 ni Communicator 4.7, cependant vous pouvez l'utiliser avec appletviewer ou Netscape 6.
Les lignes générales de cette applet :
- BUT : convertir des Francs en Euros et vice-versa ;
- UI : AWT, GridBagLayout, 4 Labels, 4 TextFields, 1 Bouton ;
- DONNEES : type double pour le taux de conversion : 6,55957 ;
-
MÉTHODES :
- Conversion d'euros en francs,
- Conversion de francs en euros ;
- MÉTHODES UTILISÉES SUR LES COMPOSANTS : getText() et setText(.)
Voici le code source :
import
java.awt.*;
/****************************************************************
* Bonjour ! *
* Ceci est ma première applet. Sa fonction est de convertir des*
* francs français en euros et vice-versa. *
* guillaume.florimond@wanadoo.fr *
***************************************************************/
public
class
Convert extends
java.applet.Applet{
// Définition des variables du programme
String labelBouton =
new
String
(
"Convertir !"
);
// Le bouton contenant le texte "Convertir !"
Button bouton =
new
Button
(
labelBouton);
// Case où taper le nombre * d' euros à convertir
TextField textEuro =
new
TextField
(
11
);
// Case où taper le nombre * de francs à convertir
TextField textFranc =
new
TextField
(
11
);
// Case où lire le résultat de la conversion
TextField textResultat =
new
TextField
(
26
);
// franc vers euro
TextField textResultat2 =
new
TextField
(
26
);// Case où lire le résultat de la conversion
// euro vers franc
// Définition de la police par défaut du programme
Font f =
new
Font
(
"Helvetica"
, Font.BOLD, 15
);
Label titre =
new
Label
(
"Convertisseur de francs français en euros"
,Label.LEFT);
Label labelEuro =
new
Label
(
"Valeur en euros:"
,Label.RIGHT);
Label labelFranc =
new
Label
(
"Valeur en francs:"
,Label.RIGHT);
Label labelResultat =
new
Label
(
"Résultat de la conversion (en euros):"
,Label.RIGHT);
Label labelResultat2 =
new
Label
(
"Résultat de la conversion (en francs):"
,Label.RIGHT);
String FrancChaine =
new
String
(
); // Valeur entrée par l'utilisateur dans le TextField "textFranc"
String EuroChaine =
new
String
(
); // Valeur entrée par l'utilisateur dans le TextField "textEuro"
double
taux =
6.55957
; // Taux définitif de conversion de l'euro en franc au 1er Janvier 2000
double
FrancEntier; // Valeur convertie en "double" que l'utilisateur a entrée dans "textFranc"
double
EuroEntier; // Valeur convertie en "double" que l'utilisateur a entrée dans "textEuro"
Label copyright =
newLabel
(
"Copyright Guillaume Florimond 1999"
, Label.RIGHT); // (…) ;-)
void
buildConstraints
(
GridBagConstraints gbc, int
gx, int
gy, int
gw, int
gh, int
wx, int
wy) {
gbc.gridx =
gx;
gbc.gridy =
gy;
gbc.gridwidth =
gw;
gbc.gridheight =
gh;
gbc.weightx =
wx;
gbc.weighty =
wy;
/* Les lignes précédentes représentent la définition des variables nécessaires
pour la création d'une interface GridBagLayout */
}
public
void
init (
) {
/* Les lignes suivantes représentent le paramétrage et l'insertion sur le
container principal Applet
de la seule police utilisée, des couleurs de premier et second plan, ainsi que
des éléments propres
à l'interface AWT tels que les TextArea et les Labels créés plus haut. */
setFont
(
f); // police
setBackground
(
Color.cyan); // couleur arrière-plan
setForeground
(
Color.magenta); // couleur de la police
GridBagLayout gridbag =
new
GridBagLayout
(
);
GridBagConstraints constraints =
new
GridBagConstraints
(
);
setLayout
(
gridbag);
// Titre
buildConstraints
(
constraints, 1
,0
,4
,1
,0
,5
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.CENTER;
gridbag.setConstraints
(
titre, constraints);
add
(
titre);
// labelFranc
buildConstraints
(
constraints, 0
,1
,1
,1
,30
,20
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.EAST;
gridbag.setConstraints
(
labelFranc, constraints);
add
(
labelFranc);
// labelEuro
buildConstraints
(
constraints, 0
,2
,1
,1
,30
,20
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.EAST;
gridbag.setConstraints
(
labelEuro, constraints);
add
(
labelEuro);
// bouton
buildConstraints
(
constraints, 0
,3
,2
,1
,0
,0
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.CENTER;
gridbag.setConstraints
(
bouton, constraints);
add
(
bouton);
// textFranc
buildConstraints
(
constraints, 1
,1
,1
,1
,20
,20
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.WEST;
gridbag.setConstraints
(
textFranc, constraints);
add
(
textFranc);
// textEuro
buildConstraints
(
constraints, 1
,2
,1
,1
,20
,20
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.WEST;
gridbag.setConstraints
(
textEuro, constraints);
add
(
textEuro);
// labelResultat
buildConstraints
(
constraints, 2
,1
,1
,1
,30
,20
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.EAST;
gridbag.setConstraints
(
labelResultat, constraints);
add
(
labelResultat);
// labelResultat2
buildConstraints
(
constraints, 2
,2
,1
,1
,30
,20
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.EAST;
gridbag.setConstraints
(
labelResultat2, constraints);
add
(
labelResultat2);
// textResultat
buildConstraints
(
constraints, 3
,1
,1
,1
,20
,20
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.WEST;
gridbag.setConstraints
(
textResultat, constraints);
add
(
textResultat);
// textResultat2
buildConstraints
(
constraints, 3
,2
,1
,1
,20
,20
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.WEST;
gridbag.setConstraints
(
textResultat2, constraints);
add
(
textResultat2);
// Copyright
buildConstraints
(
constraints, 3
,3
,2
,1
,0
,0
);
constraints.fill =
GridBagConstraints.NONE;
constraints.anchor =
GridBagConstraints.CENTER;
gridbag.setConstraints
(
copyright, constraints);
add
(
copyright);
}
public
void
convertir (
Button b) {
/* ma méthode convertir() qui permet de
convertir des euros en francs et vice-versa appelée quand une action sur le bouton b
se produit */
if
(
b ==
bouton) {
// si le bouton * est le bouton b
FrancChaine =
textFranc.getText
(
); // prendre la chaîne tapée par l'utilisateur
//dans textFranc
FrancEntier =
Double.parseDouble
(
FrancChaine); // convertir cette valeur en
//Double
FrancEntier =
FrancEntier /
taux; // diviser par le taux de conversion officiel
String resultat =
new
String
(
FrancEntier +
""
); // convertir la valeur Double
//retournée en String
textResultat.setText
(
resultat); // afficher cette valeur dans textResultat
EuroChaine =
textEuro.getText
(
);
EuroEntier =
Double.parseDouble
(
EuroChaine);
EuroEntier =
EuroEntier *
taux;
String resultat2 =
new
String
(
EuroEntier +
""
);
textResultat2.setText
(
resultat2);
}
}
// les lignes suivantes définissent le gestionnaire d'événement
public
boolean
action
(
Event evt, Object arg) {
if
(
evt.target instanceof
Button) {
convertir
((
Button)evt.target); // appeler la méthode convertir()
return
true
;
}
else
return
false
;
}
}
XVIII-C-8. Cadres▲
Nous avons vu que dans le cas des applets, un cadre où afficher les composants est par défaut le cadre d'affichage de l'applet. Pour l'instant, toutes les applications présentées dans ce cours étaient de ligne de commande, c'est-à-dire sans Interface Utilisateur. Nous allons maintenant en créer avec une UI, en définissant un cadre d'affichage grâce à un objet Frame. Voici un petit schéma d'héritage de la classe Frame. Un cadre (Frame) est une sorte de fenêtre (Window), une fenêtre est un conteneur (Container) à composants, les cadres, fenêtres et conteneurs sont des composants Java.
Voici un exemple de création de fenêtre :
// Crée une nouvelle fenêtre du nom de Win
// "Ma fenêtre" est affiché comme intitulé de la fenêtre
win =
new
Frame
(
"Ma fenêtre"
);
// Assigner un Layout à cette fenêtre
win.setLayout
(
new
BorderLayout
(
10
, 20
);
// Ajouter 2 boutons à cette fenêtre
win.add
(
"North"
, new
Button
(
"Bonjour"
));
win.add
(
"South"
, new
Button
(
"Au revoir"
));
// La réduire aussi petite que possible en fonction des composants
// qu'elle contient
win.pack
(
);
// La redimensionner à la taille voulue (en pixels)
win.resize
(
100
, 200
);
// Afficher la fenêtre précédemment créée
win.show
(
);
// La masquer
win.hide
(
);
XVIII-C-9. Gestion d'événements▲
Vous savez maintenant créer une nouvelle fenêtre et y insérer des composants suivant le mode de mise en page désiré. Cependant, ces composants ne servent strictement à rien tant que vous ne leur assignez pas un comportement en réponse aux actions de l'utilisateur.
Avec AWT, cette gestion d'événements se fait en 2 temps : on crée une méthode qui exécute les opérations données avec pour argument, par exemple, un bouton. Ensuite, on crée une seconde méthode qui répond aux actions d'un composant spécifié (pour continuer sur le même exemple, le bouton).
Pour donner un exemple concret, on peut reprendre l'applet Convert :
public
void
convertir (
Button b) {
/* ma méthode convertir() qui permet de convertir
des euros en francs et vice-versa appelée quand une action sur le bouton b se
produit */
if
(
b ==
bouton) {
// si le bouton * est le bouton b
// les lignes suivantes définissent le gestionnaire d'événement
public
boolean
action
(
Event evt, Object arg) {
if
(
evt.target instanceof
Button) {
convertir
((
Button)evt.target); // appeler la méthode convertir()
return
true
;
}
else
return
false
;
}
Ce bouton réagit à toutes les actions de la même façon : il exécute le méthode convertir(). Cependant, on peut définir d'autres comportements en fonction du type d'action effectué (RollOver, RollOut…)
boolean
mouseDown
(
Event evt, int
x, int
y) // clic
boolean
mouseDrag
(
) // déplacement avec bouton de souris enfoncé
boolean
mouseMove
(
) // souris déplacée
boolean
mouseEnter
(
) // souris entre dans une zone
boolean
mouseExit
(
) // souris sort de cette zone
boolean
KeyUp
(
) // touche du clavier relâchée
boolean
KeyDown
(
) // touche appuyée
//, etc…
Il existe bien d'autres comportements, mais je ne vais pas les détailler, car il ne sont que rarement utiles. Je ne vais pas non plus parler de l'utilisation des événements précités, car la gestion d'événements est complètement remaniée avec Swing (celle d'AWT n'est vraiment pas performante). Je vous conseille pour de petits projets d'utiliser une méthode passe-partout comme action(Event ev, Object arg) accompagnée d'une instruction de reconnaissance du composant qui a subi l'action de l'utilisateur :
if (evt.target instanceof Button) {} (= si l'élément qui a subi l'action est une instance de la classe Button, exécuter le code entre accolades).
XVIII-C-10. Schéma général d'héritage d'AWT▲
XIX. SWING - Interfaces Utilisateur : les Bases▲
XIX-A. Introduction▲
Swing est la 2e bibliothèque de classes, après AWT, qui permet de créer une Interface Utilisateur et de la gérer. La procédure de construction d'une interface Swing est similaire à celle d'AWT : créer un cadre, des composants dans ce cadre, une mise en page pour ces composants, des méthodes en réponse aux actions de l'utilisateur. Il n'est pas possible de faire le tour de Swing en un seul chapitre, c'est pourquoi ce chapitre s'intéresse seulement aux principes de base et à la construction d'une UI simple.
XIX-B. Différences entre Swing et AWT▲
Du côté de l'utilisateur, la différence est majeure : l'apparence des composants est totalement différente (bien que celle-ci soit paramétrable). Du côté du concepteur, Swing présente plus de composants qu'AWT, ces composants commencent par un J (ex-: JButton, JLabel…), la gestion des événements est complètement différente. Les layouts, eux, restent les mêmes.
XIX-C. Composants▲
Comme dit précédemment, les composants sont presque les mêmes que ceux d'AWT. Pour une description des composants et plus d'informations, se reporter au chapitre sur AWT.
- JButton ;
- JLabel ;
- JTextArea ;
- JTextField ;
- JRadioButton ;
- JCheckBox ;
- JPasswordField ;
- JComboBox ;
- JList ;
- JScrollBar.
D'autres composants avancés seront traités dans les chapitres suivants concernant Swing.
XIX-D. Conteneurs▲
Les conteneurs sont les objets dans lesquels sont incorporés les composants de l'UI. Un cadre (JFrame) est un conteneur. On peut citer : JFrame, JDialog (c'est un peu différent…), JPanel, JScrollPane, JTabbedPane, JSplitPane…
- JFrame, JPanel : classiques, une JFrame est un JPanel dans un cadre spécifique à l'environnement (le cadre contenant par exemple la X pour fermer la fenêtre) ;
- JDialog : boite de dialogue qui surgit en plein milieu de l'écran (les utilisateurs de Windows connaissent sûrement celle de type Warning qui contient les habituelles Fatal Errors) ;
- JScrollPane : barres de défilement. Ajouter un JScrollPane à votre JFrame, ajoutez ensuite un JTextArea (ou autre composant nécessitant des barres de défilement) l'intérieur de ce JScrollPane ;
- JtabbedPane : cadre à onglets.
XIX-E. Gestion d'événements▲
Les gestionnaires d'événements permettent d'intercepter les actions des utilisateurs et d'assigner au programme un comportement adapté en réponse. Il existe de nombreuses manières de gérer les événements. Ce chapitre propose une manière classique, c'est celle qui est utilisée par défaut par JBuilder. Elle se met en œuvre en trois temps : création d'un « écouteur » d'actions qui attend et capte les actions de l'utilisateur, d'une méthode qui met en œuvre la réponse adaptée, de la classe qui définit cette méthode.
// 1°
// assigne un écouteur d'événements basique à un composant nommé composantX
composantX.addActionListener
(
new
java.awt.event.ActionListener
(
) {
public
void
actionPerformed
(
ActionEvent e) {
// quand une action sera captée, on devra exécuter la méthode ci-dessous, implémentée dans la partie 2°
composantX_actionPerformed
(
e);
}
}
);
// 2°
void
jButton1_actionPerformed
(
ActionEvent e) {
// code à insérer
}
// 3°
class
nomDeLaClasse implements
java.awt.event.ActionListener {
NomDeLaClasseOuSeTrouveLeComposant adaptee;
nomDeLaClasse
(
NomDeLaClasseOuSeTrouveLeComposant adaptee) {
this
.adaptee =
adaptee;
}
public
void
actionPerformed
(
ActionEvent e) {
adaptee.jButton1_actionPerformed
(
e);
}
}
Le code présenté ci-dessus est exactement celui créé par JBuilder, d'autres manières de capter les actions de l'utilisateur et d'appeler un code en réponse seront étudiées plus tard. Si vous possédez JBuilder, il suffit de double-cliquer sur un composant en mode Conception pour que soit automatiquement généré le code ci-dessus.
XIX-F. Construction d'une UI▲
Cette partie a pour fonction de créer une application à l'aide de Swing.
XIX-F-1. Comment sera le programme ? / Que fera-t-il ?▲
Le programme sera une petite fenêtre avec un bouton et un label. Au clic sur le bouton, le texte « Hello World again ! » s'affichera dans le label. Pour cela, l'application sera composée de 2 classes : une définissant l'interface, une autre contenant la méthode main() et appelant l'autre classe.
XIX-F-2. Interface graphique▲
- Créer la première classe en la définissant comme un cadre ;
public
class
Cadre1 extends
JFrame {
// définition du cadre
public
Cadre1
(
) {
// méthode constructeur
}
}
- Ajouter les composants ;
jLabel1.setText
(
""
); // création du label
jButton1.setText
(
"Cliquez ICI !"
); // création du bouton
this
.getContentPane
(
).setLayout
(
flowLayout1); // mise en place d'un layout
this
.getContentPane
(
).add
(
jLabel1, null
); // ajout du label du cadre
this
.getContentPane
(
).add
(
jButton1, null
); // ajout du bouton au cadre
- Créer le gestionnaire d'événement pour le bouton.
// 1° partie: "quand une action est effectuée sur le bouton, appeler la méthode
// JButton1_actionPerformed()"
jButton1.addActionListener
(
new
java.awt.event.ActionListener
(
) {
public
void
actionPerformed
(
ActionEvent e) {
jButton1_actionPerformed
(
e);
}
}
);
// 2° partie: création de la méthode jButton1_actionPerformed()
void
jButton1_actionPerformed
(
ActionEvent e) {
jLabel1.setText
(
"Hello World again !"
); // afficher ce texte dans le label
}
XIX-F-3. Classe principale▲
public
class
Application {
//Construire l'application
public
Application
(
) {
Cadre1 frame =
new
Cadre1
(
);
}
//Méthode principale
public
static
void
main
(
String[] args) {
new
Application
(
);
}
}
XX. I/O : Les Flux : les Bases▲
Il est possible de télécharger les sources du programme.
XX-A. Introduction▲
Les flux permettent de travailler avec des données - des fichiers - provenant de l'extérieur. Toutes les commandes de type Ouvrir, Enregistrer, Enregistrer sous … des programmes classiques font appel aux flux. Les flux sont aussi appelés I/O : en anglais, Input/Output, entrées/sorties. Nous allons voir dans ce chapitre les flux de base, permettant de lire et d'écrire du texte (on différencie les caractères et le texte en général). Nous verrons également comment utiliser la mise en mémoire cache du contenu d'un flux (en fait des données qu'il transporte) pour accélérer ses performances (vitesse, fiabilité). Le programme final définira une petite interface Swing, un gros bouton qui, quand on le pressera fera charger un fichier dans un JTextArea.
XX-B. Ligne de commande▲
Vous connaissez déjà un type de flux basique de ligne de commande : System.out. Sachez qu'il existe pour les entrées System.in et pour les erreurs System.err. Dans la mesure où les applications de ligne de commande uniquement se font très rares, nous n'étudierons pas ces méthodes.
XX-C. Flux d'entrée / flux de sortie▲
La création d'un flux de base se fait en 2 étapes : création d'un flux de support d'entrée ou de sortie, création d'un flux adapté à l'opération que l'on désire obtenir.
// flux de support (valable dans tous les cas)
FileInputStream fis =
new
FileInputStream
(
"fichier.extension"
) ;
// flux particulier (exemple)
*
InputStream zis =
new
*
InputStream
(
fis);
On crée un flux de support fis grâce à FileInputStream, ce flux (ici, d'entrée) travaille avec le fichier fichier.extension (exemple : Readme.txt), à ce flux, on associe un flux particulier. L'étoile représente tous les types de flux : ZipInputStream, DataInpuStream, GzipInputStream…
Ici sont présentés des flux d'entrée, pour les flux de sortie, on remplace « Input » par « Output ».
Exemple concret :
FileOutputStream fos =
new
FileOutputStream
(
"fichier.txt"
);
ZipOutputStream zout =
new
ZipOutputStream
(
fos);
XX-D. Classes de flux d'entrée/sortie▲
XX-D-1. Entrée▲
public
int
available
(
) throws
IOException
Permet de retourner le nombre d'octets que le flux peut lire. (rarement nécessaire)
public
long
skip
(
long
n) throws
IOException
Permet d'ignorer les n prochains caractères. (rarement nécessaire)
XX-D-2. Sortie▲
public
void
flush
(
)
Vide immédiatement le contenu d'un flux (vide le tampon et distribue ce qu'il contient). (utile)
public
void
close
(
) throws
IOException
Permet de fermer un flux. Même si vous ne fermez pas un flux, aucune erreur ne sera (normalement) provoquée. Cependant, chaque flux devrait être fermé.
XX-E. Mise en mémoire tampon▲
La mise en mémoire tampon d'un flux permet d'accélérer les performances, voici la procédure à adopter :
// création du support
FileInputStream fis =
new
FileInputStream
(
"fichier.txt"
);
// création du flux de mise en tampon
BufferedInputStream bis =
new
BufferedInputStream
(
fis);
// on joint le BufferedInputStream à un flux particulier, par exemple:
DataInputStream dis =
new
DataInputStream
(
bis);
XX-F. Readers/writers▲
Les readers et writers sont un sujet assez long à traiter. Il serait hors sujet de les traiter dans leur intégralité dans ce chapitre présentant les concepts clés de I/O. Nous allons donc voir uniquement une partie basique.
Les readers et writers permettent de lire et d'écrire des données dans des fichiers. Ils sont très utiles pour travailler avec des fichiers de texte. Ils sont utilisés en remplacement des méthodes FileInputStream et FileOutputStream. Par exemple, pour utiliser un FileWriter et un FileReader :
// FileWriter:
// déterminer le texte à écrire dans le fichier en le prenant, par exemple, dans un TextArea
String texte =
new
String
(
jTextArea1.getText
(
));
// ouvrir le FileWriter avec pour argument le nom du fichier de sortie
FileWriter lu =
new
FileWriter
(
"fichier.txt"
);
// procédure de mise en cache
BufferedWriter out =
new
BufferedWriter
(
lu);
// écrire dans le FileWriter les informations du String texte
out.write
(
texte);
// fermer le flux
out.close
(
);
// FileReader :
//ouvre un FileReader
FileReader fr =
new
FileReader
(
"fichier.txt"
);
// procédure de lecture des caractères…
while
(
true
) {
// lire les caractères
int
i =
fr.read
(
);
// -1 représente le moment où il n'y a plus de caractères à lire, la boucle while doit alors s'
// arrêter
if
(
i ==
-
1
) break
;
}
XX-G. Projet : afficheur▲
Ce programme permet de capturer un texte d'une zone de texte et de l'écrire dans un fichier, de le lire d'un fichier pour l'écrire dans la zone de texte.
Il utilise 2 classes Swing, un FileWriter et un FileInputStream…
1re classe :
package
afficheur;
import
javax.swing.UIManager;
public
class
Application {
boolean
packFrame =
false
;
//Construire l'application
public
Application
(
) {
// appel à la classe 'afficheur'
afficheur frame =
new
afficheur
(
);
//Valider les cadres ayant des tailles prédéfinies
//Compacter les cadres ayant des infos de taille préférées - ex. depuis leur disposition
if
(
packFrame) {
frame.pack
(
);
}
else
{
frame.validate
(
);
}
frame.setVisible
(
true
);
}
//Méthode principale
public
static
void
main
(
String[] args) {
try
{
// pour l'apparence 'Windows'
UIManager.setLookAndFeel
(
UIManager.getSystemLookAndFeelClassName
(
));
}
catch
(
Exception e) {
e.printStackTrace
(
);
}
newApplication
(
);
}
}
2de classe :
// le programme comprend 2 classes regroupées dans 1 package:
package
afficheur;
// importation de packages nécessaires
import
java.awt.*;
import
java.awt.event.*;
import
javax.swing.*;
import
java.io.*;
// début du programme, la classe afficheur doit étendre (extends) de JFrame
// pour définir un cadre Swing à l'écran
public
class
afficheur extends
JFrame {
// Conteneur
JPanel contentPane;
// Layout
BorderLayout borderLayout1 =
new
BorderLayout
(
);
// Composant 1 : le bouton
JButton jButton1 =
new
JButton
(
);
// barres de défilement pour le composant 2
JScrollPane jScrollPane1 =
new
JScrollPane
(
);
// Composant 2 : la zone de texte
JTextArea jTextArea1 =
new
JTextArea
(
);
JButton jButton2 =
new
JButton
(
);
//Construire le cadre
public
afficheur
(
) {
enableEvents
(
AWTEvent.WINDOW_EVENT_MASK);
try
{
// essayer d'exécuter la méthode jbInit()
jbInit
(
);
}
catch
(
Exception e) {
e.printStackTrace
(
);
}
}
//Initialiser le composant
private
void
jbInit
(
) throwsException {
// texte du bouton
jButton1.setText
(
"Charger"
);
// écouteur d'actions (fait partie du gestionnaire d'événements)
jButton1.addActionListener
(
new
afficheur_jButton1_actionAdapter
(
this
));
// définition du conteneur courant
contentPane =
(
JPanel) this
.getContentPane
(
);
// assignation à ce conteneur d'un layout précis
contentPane.setLayout
(
borderLayout1);
// taille de la fenêtre
this
.setSize
(
newDimension
(
400
, 300
));
// label de la fenêtre
this
.setTitle
(
"Exemple pour les flux"
);
// texte qui apparaît quand on laisse la souris immobile un certain temps
// sur la zone de texte
jTextArea1.setToolTipText
(
"Exemple d'un chapitre de JGFL"
);
// ajout des composants
jButton2.setText
(
"Enregistrer"
);
jButton2.addActionListener
(
new
afficheur_jButton2_actionAdapter
(
this
));
contentPane.add
(
jButton1, BorderLayout.SOUTH);
contentPane.add
(
jScrollPane1, BorderLayout.CENTER);
contentPane.add
(
jButton2, BorderLayout.NORTH);
jScrollPane1.getViewport
(
).add
(
jTextArea1, null
);
}
//Remplacé, ainsi nous pouvons sortir quand la fenêtre est fermée
protected
void
processWindowEvent
(
WindowEvent e) {
super
.processWindowEvent
(
e);
if
(
e.getID
(
) ==
WindowEvent.WINDOW_CLOSING) {
// pour fermer 'proprement' la fenêtre au clic sur la croix (sous Win95)
System.exit
(
0
);
}
}
// gestionnaire d'événements, 2de partie
void
jButton1_actionPerformed
(
ActionEvent e) {
// appeler cette méthode
charger
(
);
}
// méthode qui permet de prendre le texte dans la zone de texte et de le
// transmettre au FileWriter
public
void
enregistrer
(
) {
try
{
String texte =
new
String
(
jTextArea1.getText
(
));
FileWriter lu =
new
FileWriter
(
"fichier.txt"
);
BufferedWriter out =
new
BufferedWriter
(
lu);
out.write
(
texte);
out.close
(
);
}
catch
(
Exception err) {
;}
}
// ma méthode qui permet de lire les informations du fichier 'fichier.txt'
// et de les imprimer dans la zone de texte
public
void
charger
(
) {
// les exceptions doivent être interceptées ('catchées')
try
{
// Flux d'entrée
FileInputStream fis =
new
FileInputStream
(
"fichier.txt"
);
// nombre de caractères dans le fichier
int
n;
// tant que ce nombre de caractères est supérieur à 0…
while
((
n =
fis.available
(
)) >
0
) {
// chaque caractère associé à 1 byte
byte
[] b =
new
byte
[n];
int
result =
fis.read
(
b);
// fin du flux = plus rien à lire = sortie de la boucle
if
(
result ==
-
1
) break
;
String s =
new
String
(
b);
jTextArea1.setText
(
s);
}
}
catch
(
IOException err) {
System.out.println
(
"Erreur: "
+
err);
}
}
// classes pour la gestion d'événements.
class
afficheur_jButton1_actionAdapter implements
java.awt.event.ActionListener {
afficheur adaptee;
afficheur_jButton1_actionAdapter
(
afficheur adaptee) {
this
.adaptee =
adaptee;
}
public
void
actionPerformed
(
ActionEvent e) {
adaptee.jButton1_actionPerformed
(
e);
}
}
void
jButton2_actionPerformed
(
ActionEvent e) {
enregistrer
(
);
}
}
class
afficheur_jButton2_actionAdapter implements
java.awt.event.ActionListener {
afficheur adaptee;
afficheur_jButton2_actionAdapter
(
afficheur adaptee) {
this
.adaptee =
adaptee;
}
public
voidactionPerformed
(
ActionEvent e) {
adaptee.jButton2_actionPerformed
(
e);
}
}
XXI. Note et remerciement du gabarisateur▲
Cet article a été mis au gabarit de developpez.com. Dans la mesure du possible, l'esprit d'origine de l'article a été conservé. Cependant, certaines adaptations ont été nécessaires. Voici les liens vers les documents PDF d'origine :
- Introduction à Java : java.pdf ;
- Le JDK de Sun : jdk.pdf ;
- Initiation à Java : le projet HelloWorld : Bases.pdf ;
- Les Variables : le projet Chocos : Variables.pdf ;
- Les Matrices : le projet ArrayTest : Matrices.pdf ;
- Boucles et Conditions : le projet NamesLoop : Boucles et Conditions.pdf ;
- Objets ou Instances : le projet EgaliteTest : objets.pdf ;
- Méthodes : le projet ReHello : methodes.pdf ;
- Classes et Héritage : classes.pdf ;
- Transmission d'arguments : le projet Palindrome :arguments.pdf ;
- Les Exceptions : exceptions.pdf ;
- Applets : quelques généralités :generalites.pdf ;
- Applets : classes Graphics : le projet Floride :graphics.pdf ;
- Applets : Java2D (Graphics2D) : le projet Floride2D : graphics2D.pdf ;
- Les Modificateurs : modificateurs.pdf
- Insérer des sons dans un programme (exemple pour une applet) : sons.pdf ;
- Animations (exemple pour une applet) : Animations.pdf ;
- AWT - Interfaces Utilisateur : awt.pdf ;
- SWING - Interfaces Utilisateur : les Bases : swing.pdf ;
- I/O : Les Flux : les Bases : flux.pdf.
Le gabarisateur remercie Philippe DUVAL pour sa correction orthographique.