Remarques
Les fichiers .class sont des bytecodes qui ne sont exécutables que par la machine virtuelle Java (ils ne sont pas directement exécutables sous Unix). Il faut donc explicitement utiliser l'interpréteur java de la manière suivante:
java MonFichier (sans l'extension .class)
Pour trouver les erreurs, on peut utiliser jdb, le debogueur Java. Des IDEs comme Eclipse faciliteront grandement l'édition et la mise au point du code.
Créer un nouveau répertoire et y copier les fichiers sources se trouvant dans ce fichier zip (NOTE: attention à ne pas écraser vos propres fichiers source si vous rechargez ce fichier zip par la suite !)
Le programme BipBip.java montre une interface graphique minimale (un bouton qui emet un "bip" et affiche un message quand on clique dessus). Exécutez ce programme (voir "Mode d'Emploi" ci-dessus pour la compilation et l'exécution), puis regardez le code source et les commentaires qui suivent.
Le fichier BipBip.java définit une classe unique BipBip qui a le même nom que le fichier à l'extension près. Cette classe doit obligatoirement être publique (voir "Quelques remarques sur les programmes Java").
BipBip est une sous-classe de JFrame, la classe Java Swing qui sert à contruire la fenêtre principale d'une application. Les objects graphiques doivent être ajoutés au JFrame (ou plus exactement à son contentPane: noter qu'avec les versions anciennes de Swing il faut le faire explicitement via la fonction getContentPane())
BipBip implémente l'interface ActionListener. C'est ce qui permettra de gérer le comportement du bouton comme on le verra ci-après (noter que le terme interface fait ici référence aux interfaces de programmation, pas aux interfaces graphiques !)
La classe BipBip définit trois méthodes détaillées ci-après. On remarquera en passant que les méthodes peuvent être définies (et appelées) dans n'importe quel ordre en Java (contrairement au langage C où il faut théoriquement déclarer les fonctions (i.e. spécifier leur signature) avant de les appeler).
Tout programme Java doit obligatoirement définir une méthode main() qui sert de point d'entrée à l'éxecution du programme (à la différence des Applets qui doivent définir la méthode init()). Cette méthode doit être public static (static signifie que c'est une méthode de classe et non d'instance).
main() instancie la classe "BibBip", ce qui a pour effet de créer l'interface graphique. Cette instance est le composant graphique de plus haut niveau de l'application et "contient" donc les autres composants graphiques. En d'autres termes, cette instance est la racine de l'arbre d'instanciation de la GUI.
Il faut enfin calculer la disposition spatiale des de composants graphiques puis les rendre visible. Ceci ce fait en appelant les méthodes pack() et show() sur l'objet de plus haut niveau.
C'est le constructeur de la classe BibBip. Cette méthode:
Remarque:
Quasiment tous les composants graphiques Java doivent avoir un parent (à part JFrame, etc.) pour apparaître et fonctionner correctement. Ceci est généralement fait via la méthode add() du parent. N'oubliez donc pas cette étape (vous pourriez obtenir des résultats etranges ou des NullPointerException dans le cas contraire).
Cette méthode est appelée chaque fois que l'on clique sur le bouton. Elle est héritée de l'interface ActionListener. que la classe BibBip "implémente". Le code montre comment afficher un message sur le Terminal (l'équivalent du printf() du C) et émettre un bip.
L'exemple LesBoutons.java montre une manière élémentaire de disposer plusieurs widgets dans un Container et de gérer leur comportement. On remarquera que:
Associer les comportements suivants aux 3 boutons :
Indications: consulter les méthodes des classes en question dans le manuel de référence. Pensez à utiliser la fonctionnalité "Find in Page" (ou similaire) de Netscape, Mozilla ou IExplorer pour retrouver les méthodes dans les pages décrivant les classes Java).
L'exemple LesComponents.java introduit quelques-uns des composants Swing les plus courants et montre l'utilisation du LayoutManager BorderLayout.
Cette GUI comprend 2 conteneurs intermédiaires (de classe JPanel). Ces conteneurs sont internes et peuvent être emboîtés entre-eux (il ne créent pas de nouvelle fenêtre contrairement aux JFrames, et aux JDialogs que nous verrons ensuite). Leur Layout Manager par défaut est FlowLayout (enfants mis à la suite, passage à la ligne quand il n'y a plus de place).
Cet exemple introduit un nouveau Layout Manager nommé BorderLayout. Celui-ci impose une disposition spatiale de type points cardinaux. Les enfants sont ajoutés au conteneur associé au moyen d'une forme particulière de la méthode add() qui permet de spécifier leur emplacement. Par exemple:
add(BorderLayout.NORTH, panel1);
Il est à noter que BorderLayout ne retaille pas tous les enfants de la même manière quand on retaille la fenêtre. Faites un essai : que constate t-on ?
Remarque: le LayoutManager par défaut du contentPane est déjà BorderLayout. La ligne: contentPane.setLayout(new BorderLayout()) est donc optionnelle dans ce cas.
Cet exemple introduit également les objets JTextField (une ligne de texte), JTextArea (une zone de texte multi-lignes) et JCheckBox (un bouton à états ; attention au "B" majuscule !)
Les trois check boxes crées dans cet exemple sont stockés dans un tableau qui est lui-même créé au début du programme:
JCheckBox[] checkboxes = new JCheckBox[3];
Il est important de noter que cette ligne initialise le tableau mais pas les éléments contenus !. En d'autres termes, on crée un tableau de 3 éléments dont chaque élément "pointe" sur null (c'est-à-dire sur aucun objet). Chaque élément du tableau est initialisé ultérieurement lorsque l'on crée les check boxes :
checkboxes[0] = new JCheckBox("Oui", true); ...etc...
Remarque: la définition:
Checkbox[] checkboxes;
ne serait pas valide en C ou en C++. Pour les nostaliques, Java permet également d'écrire:
Checkbox checkboxes[];
Le programme définit enfin la méthode actionPerformed qui est appelée quand on clique sur le bouton Ok ou quand on frappe la touche ENTER sur le text field (on remarquera que c'est la même méthode du même listener qui est appelés dans les 2 cas bien que les classes soient différentes).
Exécuter ces actions et regarder le code source. Regarder également les messages affichés sur le Terminal (et en particulier la valeur de l'actionCommand).
Compléter la méthode actionPerformed de telle sorte que l'état de chacun des trois check boxes (sélectionné / non sélectionné) s'affiche sur le JTextArea chaque fois que l'on active le JTextField ou le Button.
Remarque: on pourra faire cet exercice en récupérant l'état courant des 3 check boxes (voir la doc. et méthodes isSelected(), getSelected()). Il ne sera pas nécessaire de leur ajouter un ActionListener dans ce cas de figure.
Le programme MaRadio.java reprend l'exemple précédent en introduisant le Layout Manager GridLayout et en montrant comment utiliser des RadioButtons (c'est-à-dire des check boxes exclusifs).
Ces RadioButtons :
Retailler la fenêtre. Que constate t-on ? Noter que le JTextArea et les JPanels ne sont pas agencés de la même faÁon que dans l'exemple précédent par rapport au BorderLayout du JFrame.
Cet exemple montre donc comment on peut emboîter plusieurs conteneurs avec des LayoutManagers différents pour obtenir des changements de taille appropriés lorsque l'on retaille la fenêtre.
Le programme MaRadio.java montre enfin comment utiliser des boucles et des tableaux pour simplifier et compacifier l'écriture du code.
Si l'on clique de nombreuses fois sur les radio buttons, on constatera un comportement qui peut paraître étrange. Que se passe-t'il ? Pourquoi ?
Une solution pour éviter cet effet consisterait à utiliser des ascenceurs. C'est ce que l'on vous demande de faire en utilisant la classe JScrollPane.
La classe JDialog permet de créer des fenêtres secondaires, c'est-à-dire des boîtes de dialogue. Un JDialog ressemble à un JFrame, mais avec quelques particularités. Tout d'abord les JDialogs sont iconifiés et détruits en même temps que la fenetre principale. D'autre part, ils peuvent être rendus modaux (i.e. bloquants) au moyen de la méthode setModal().
Les JDialogs sont des fenêtres vides qu'il convient de compléter (de la même manière que les autres conteneurs Java). Swing permet également de créer des boîtes de dialogue prédéfinies au moyen des classes JFileChooser (pour choisir un fichier), JOptionPane (pour afficher un message) etc.
L'exemple LesDialogs1.java illustre ces différents aspects en reprenant des parties des exemples précédents. On regardera et vérifiera en particulier:
Dans l'exemple précédent on programmé "à la mode C" : les boîtes de dialogue sont crées en appelant une méthode qui joue à peu près le même rÙle qu'une bête fonction C (noter que CreerMonDialog() est d'ailleurs une méthode de classe).
La logique de la programmation orientée objet voudrait plutÙt que l'on définisse une nouvelle classe (qui hérite de JDialog) pour pouvoir créer proprement les boîtes de dialogue. Cette faÁon de faire permet de décomposer un programme en sous-parties clairement identifiées, bien séparées et facilement réutilisables, au lieu d'aboutir à un gigantesque sac de noeuds au bout d'un certain temps de développement.
C'est ce que l'on se propose de faire dans le programme LesDialogs2.java.
Regarder le code correspondant à l'instantiation et à la définition de la nouvelle classe MonDialog. Celle-ci hérite de JDialog et implémente également ActionListener. Il est donc nécessaire de définir la méthode actionPerformed correspondante qui va permettre de coder le comportement des widgets contenus dans ce JDialog. Et ... c'est justement ce que l'on va vous demander de faire dans l'exercice suivant !
Remarques:
super(frame, title, modal);Ceci est nécessaire pour pouvoir spécifier quel constructeur de JDialog on veut utiliser (étant donné qu'il y en a plusieurs). Cet appel doit obligatoirement être la première instruction dans le constructeur.
2. Rajouter une troisième boîte de dialogue qui permettrait de sélectionner un nom de fichier et de l'afficher dans le JTextArea de la fenêtre principale (NB: utiliser JFileChooser).
Il est fréquent qu'une application nécessite l'utilisation d'objets ayant des fonctionnalités dont ne disposent pas les objets standard fournis dans les librairies Java. Plusieurs stratégies sont alors possibles:
Nous allons illustrer cette approche en enrichissant les JButtons de telle sorte qu'ils affichent une bulle d'aide chaque fois que la souris entre dans le bouton (noter que cette fonctionnalité existe en standard mais nous allons la réimplémenter pour les besoins de l'exercice). Le programme TipProg.java montre comment définir une nouvelle classe de boutons, appelée TipButton (dans le fichier TipButton.java) qui effectue (partiellement) ce travail. Les TipButton ont exactement les mêmes fonctionnalités que les JButton standard, sauf que leur couleur change quand la souris passe dessus et un message d'aide est affiché dans la Terminal d'où on a lancé le programme.
Cet exemple, pour l'instant incomplet (le message devrait être affiché dans une bulle d'aide), illustre plusieurs aspects importants :
Pour rendre notre nouvel objet TipButton facilement réutilisable et accessible depuis n'importe quel programme, il est nécessaire de le rendre public et ddonc e le séparer de la classe TipProg en le mettant dans un fichier spécifique (noter qu'un même fichier java ne peut contenir qu'une seule classe publique).
La compilation de TipProg.java entrainera automatiquement celle de TipButton. Il suffira donc de faire :
javac TipProg.java puis: java TipProg(car TipProg.class definit la méthode main)
Ecrivez deux versions : d'abord en utilisant des variables d'instance puis des variables de classe. Quel est l'avantage de la 2eme solution ?
Les 3 Layout Managers les plus courants ont déjà été présentés au cours du TP précédent:
Le programme DesGribouillis1.java montre comment gérer des événements souris pour permettre de faire du dessin à main leveé. Ces programmes nécessitent de travailler avec les Listeners: MouseListener et MouseMotionListener. Contrairement à l'ActionListener vu dans les exemples précédents, ces deux Listeners possèdent plusieurs méthodes qu'il est donc nécessaire d'implémenter même si elle ne font rien (corps vide).
Le programme DesGribouillis2.java montre une version plus élégante du même programme en utilisant les classes imbriquées (inner classes). Ce programme contient deux types de classes imbriquées
Cette section montre comment faire communiquer 2 applications distinctes par des sockets. Plus précisément, on va faire dialoguer:
Ce type d'architecture est tès général et peut être décliné sous diverses formes. Notre exemple (fichiers Client.java, serv.c et Makefile) montre un cas simple où les requêtes envoyées par le client sont traitées en séquence par le serveur. Des architectures plus complexes pourraient permettre de traiter des requêtes en parallèle.
Compléter l'exemple de manière à réaliser une calculette:
Note: la partie C doit être limitée au strict minimum (utiliser la fonction sscanf()).
Le programme LesMenus.java montre comment créer des barres de menus (JMenuBar) et des menus déroulants (JMenu). On notera en particulier que les boutons contenus dans les menus ne sont pas des boutons ordinaires mais des JMenuItem.
Compléter le programme DesGribouillis2.java afin de produire une interface graphique complète, comportant:
Les Applets sont des programmes Java qui sont exécutables depuis un navigateur Web. Ces programmes ont (entre-autres) pour particularité de ne pas posséder de méthode main() (laquelle est obligatoire pour tous les autres programmes Java). A la place, elles doivent comporter une méthodes init() qui sert à initialiser l'applet lorsqu'elle est chargée par le browser.
D'autre part, les Applets sont realisées en dérivant la classe JApplet (et non JFrame) comme pour les applications "normales"). Ceci s'explique par le fait que l'Applet est normalement inclue dans une page Web (JFrame ouvrirait une fenetre en dehors du navigateur Web).
Une applet est spécifée dans une page HTML de la manière suivante:
<APPLET CODE = "MonApplet.class" CODEBASE="MesClasses" WIDTH=150 HEIGHT=25> </APPLET>CODEBASE est une balise optionnelle qui sert à indiquer où se trouve le fichier .class.
Les applets peuvent également être testées au moyen de commande appletviewer. Cette commande prend pour argument une page HTML (un fichier ou une URL)
1) Verifier que votre code compile et s'exécute correctement depuis une salle de TP Unix de l'Ecole.
2) Ecrire un bref fichier README indiquant les questions traitées et contenant les réponses aux questions et tous les commentaires que vous jugerez utiles. Ce fichier doit être en PDF ou en HTML (en UTF-8) ou au format texte (en UTF-8 également). N'oubliez pas de mettre votre nom (au moins dans le README et de préférence aussi dans les autres fichiers)
3) Créer un fichier zip ou tar.gz (pas d'autre format!) contenant votre README et le code source (ne mettez pas l'executable ni les .class)
4) Aller à l'URL http://services.infres.enst.fr/rendutp/, cliquer (le bon ;-) lien puis entrer votre nom et télécharger le fichier zip ou tar.gz
NB: seule la dernière version téléchargée est prise en compte