Introduction

Horaires

Le lundi à 10h30.

Équipe enseignante

Responsable du cours – Olivier Chapuis Chargés de TD – Oleksandr Zinenko, Arnaud Prouzeau

Note finale

50% cours 50% projet

Travaux dirigés

Les exercices ont été conçus par Nicolas Roussel et ont été adaptés plusieurs fois par les membres de l’équipe HCC. Vous pouvez en trouver les solutions sur Internet, mais elles contiennent de subtiles différences. Vous êtes invités à écrire vos solutions vous-même pour apprendre les techniques nécessaires pour le projet.

1a. Mise en page des interfaces

Les diaporamas présentés en TD.

Le but de cet exercice est de créer un convertisseur de température contenant :

  • deux labels “Celsius” et “Fahrenheit”,
  • deux champs textuels qui servent à la fois pour l’entrée et pour la sortie des valeurs de température,
  • deux boutons, l’un effaçant les valeurs des champs textuels; l’autre fermant la fenêtre.

Déroulement de l’exercice :

  1. Téléchargez le fichier TempConverter.java.

  2. Complétez la fonction init() dans ce fichier en utilisant la classe JPanel et les gestionnaires de mise en page (layout managers) afin d’obtenir la fenêtre ci-dessous. N’oubliez pas d’initialiser les champs et les boutons. Layout

  3. Vérifiez que les éléments de l’interface (widgets) sont bien alignés et que leurs positions restent consistants quand vous redimensionnez la fenêtre.

1b. Réaction aux entrées de l’utilisateur

Les diaporamas présentés en TD.

Continuez de travailler sur le convertisseur de température. Après la mise en page des éléments de l’interface graphique, vous pouvez rajouter des interactions. Pour le faire, suivez les étapes suivantes :

  1. Le textFieldCListener lit une valeur flottante dans le champ Celsius quand l’utilisateur appuie sur la touche “Entrée”, l’interprète comme température Celsius et la convertit en Fahrenheit. Finalement il met le résultat dans le champ Fahrenheit. Associez ce listener au champ textuel contenant la valeur Celsius.

  2. Complétez le textFieldFListener de sorte qu’il fasse la conversion de Fahrenheit en Celsius. Associez-le au champ textuel contenant la valeur Fahrenheit.

  3. Le buttonCloseListener ferme la fenêtre. Associez-le au bouton “Close”.

  4. Complétez le buttonResetListener de sorte qu’il efface le texte dans les champs Celsius et Fahrenheit. Associez-le au bouton “Reset”.

  5. La conversion de température se passe quand l’utilisateur appuie sur la touche “Entrée”. Utilisez un KeyListener plutôt qu’un ActionListener pour refaire la conversion après chaque symbole entré par l’utilisateur.

2. Menus, Listes

Dans cet exercice, vous allez de nouveau utiliser les différents layout managers ainsi que les listeners pour développer un dialogue de sélection des fichiers.

FileSelector

Le dialogue affiche le contenu du dossier sélectionné. Les noms des sous-dossiers sont suivis par un slash (/) alors que ceux de fichiers simples restent inchangés. Le “menu” en haut de la fenêtre contient une liste des dossiers dans lesquels les programme se trouve actuellement, par exemple /, home/, etudiant/, td2/ pour représenter le chemin /home/etudiant/td2. Les boutons en bas servent à sélectionner un fichier ou à ouvrir un sous-dossier.

Déroulement de l’exercice :

  1. Téléchargez le fichier FileSelector.java.

  2. Modifiez ce fichier en utilisant les classes JComboBox, JList, JScrollPane et JButton afin d’obtenir une fenêtre ci-dessus. Vérifiez que leur positions restent consistants quand vous redimensionnez la fenêtre.

  3. Vérifiez que la sélection d’un sous-dossier met à jour le “menu” et la liste des fichiers.

  4. Faites le bouton “Open” actif si un fichier ou un sous-dossier est sélectionné dans la liste.

  5. Vérifiez que la fenêtre ferme quand l’utilisateur clique sur le bouton “Cancel”, ou quand il clique sur le bouton “Open” après avoir sélectionné un fichier (contrairement aux dossiers).

  6. Rajoutez la possibilité d’ouvrir un dossier par une double clique sur son nom dans la liste.

  7. N’oubliez pas de mettre à jour la liste et le “menu” quand un dossier est sélectionné dans le “menu”.

Pour les application réelles, on vous conseille d’utiliser la classe standard JFileChooser.

3. MVC : Modèle-Vue-Contrôleur

Les diaporamas présentés en TD.

L’objectif de cet exercice est de réaliser une interface permettant de choisir une couleur en manipulant ses composantes Rouge, Verte et Bleue à l’aide de potentiomètres ou en spécifiant leur valeur en hexadécimal. La couleur choisie est affichée dans un Panel dedié.

ColorChooser

Le code de selecteur des couleurs doit être séparé en trois parties selon le modèle MVC. Le but de ce modèle est de séparer les données, la méthode dont ces données sont visualisés et la technique d’interaction.

  1. Téléchargez le fichier ColorChooser.java.

  2. Complétez la méthode init() dans ce fichier en utilisant JPanel de sorte que l’interface corresponde à l’image. Vous venez de créer la Vue de MVC.

  3. Créez le Modèle et le Contrôleur. Faites les liens entre les trois composants du MVC.

  4. Assurez-vous que tous les widgets sont connectés l’un à l’autre : quand l’utilisateur deplace un potentiomètre, les champs textuels sont mis à jour ainsi que le panel de couleur ; quand l’utilisateur change les valeurs textuelles directement, les potentiomètres changent leur position.

Vous pouvez utiliser les méthodes Color.getRGB() et Integer.toHexString pour récuperer la représentation textuelle d’une couleur et la méthode Color.decode pour trouver la couleur définie par la valeur hexadécimal.

4. Dessin 2D

L’objectif de cet exercice est de créer un éditeur graphique 2D très simplifié afin de se familiariser avec le dessin 2D.

GraphicalEditor

  1. Téléchargez l’archive GraphicalEditor.zip qui contient les classes pour cet exercice : GraphicalEditor.java est l’interface graphique ; PersistentCanvas.java est une classe permettant de stocker les éléments du dessin ; CanvasItem.java est un élément abstrait du dessin ; RectangleItem.java est un élément réctangulaire qui hérite de la classe CanvasItem.

  2. Modifiez la classe GraphicalEditor afin qu’elle permette à l’utilisateur de choisir le mode en sélectionnant un bouton radio.

  3. Modifiez les classes GraphicalEditor et PersistentCanvas et rajoutez la possibilité de sélectionner un élément du dessin quand l’utilisateur clique dessus (mode Select/Mode). Pour cela, il est nécessaire de réaliser une méthode PersistentCanvas.getItemAt(Point p) qui gére la recherche d’élément couvrant les coordonnées du point.

  4. Rajoutez les actions aux boutons “Delete” et “Clone” pour effacer ou dupliquer l’élément sélectionné.

  5. Modifiez le MouseMotionListener dans la classe GraphicalEditor afin de permettre le déplacement des éléments du dessin.

  6. Rajoutez les widgets pour choisir la couleur du tracé et de remplissage des éléments graphiques. Utilisez une fenêtre de dialogue standard.

  7. Rajoutez les classes pour les formes autres qu’un rectangle (ellipse, ligne et une trace générique). Elles doivent avoir la même fonctionnalité que celle du rectangle en ce qui concerne le déplacement et les couleurs.

Projet

Modalités et dates limites

Le but de ce projet est de réaliser un Desktop simplifié dans lequel on peut ajouter/supprimer/manipuler des icônes avec des techniques d’interaction différentes.

Le projet sera réalisé en binôme, vous devrez présenter ce projet lors d’une soutenance, le mercredi 13 mai à 9h.

Vous devez impérativement communiquer aux chargés de TD la composition des binômes et les fonctionnalités choisies avant le 16 avril à 18h.

Votre code et un rapport devront être envoyés avant le 12 mai à 18h aux adresses mail suivantes :

Le sujet

Le but de ce projet est de réaliser un Desktop Interactif à l’image de celui que vous utilisez tous les jours sur votre ordinateur (en simplifié). La fonctionnalité principale est la gestion d’icône, mais d’autres fonctionnalités peuvent être ensuite intégrées.

Desktop Windows

Exemple d’un Desktop Windows

Composition du projet et notation

Les fonctionnalités obligatoires (12 points maxi) :

  • Affichage d’icônes des différents types
  • Ajout, suppression, déplacement d’icônes
  • Menu contextuel basique
  • Undo/Redo

Les fonctionnalités recommandées (+4 points maxi) :

  • Gestion des dossiers
  • Gestion des fenetres

Les fonctionnalités avancées au choix (+4 points et bonus) :

  • Menu contextuel avancé (Pie Menu, Marking Menu, Control Menu, …)
  • Séléctions et déplacements élaborés d’icônes (Lasso, Drag’n’Pop)
  • Utilisation de commandes gestuelles
  • Intégration avec le système des fichiers réel

Les quatre fonctionnalités obligatoires doivent être présentes dans chaque projet accepté. Chaque fonctionnalité recommandé permet de rajouter 2 points à la note finale. Vous pouvez choisir une ou plusieurs fonctionnalités avancées, chacune desquelles vaut 4 points supplémentaires. Si la note atteint 20 points, les fonctionnalités avancées comptent comme bonus.

Précision. Seules les fonctionnalités obligatoires sont, comme indique leur nom, obligatoires pour rendre le projet. Celui-ci sera alors noté sur la base de 12 points ; vous recevrez une note de 0 à 12 inclus en fonction de la présence et de la qualité de ces fonctionnalités ainsi que de la présentation du projet pendant la soutenance et de la structuration du code.

La soutenance

La soutenance se déroulera le 13 mai à 9h. Vous devez faire une présentation de maximum 5 minutes, expliquant ce que vous avez implémenté dans votre projet, et expliquant rapidement votre processus de conception. Suite à cette présentation vous devrez aussi faire une démonstration de votre Desktop.

Le rapport

Le rapport doit présenter brièvement votre application et le processus de conception. Il est demandé de présenter une des étapes suivantes :

  • La réalisation de prototypes basse-fidelité
  • L’évaluation à l’aide d’une méthode vue en cours

Le rapport doit être rendu par e-mail au deux chargés de TD avant le 12 mai 18h.

Le code

La programmation se fera en Java. Il est interdit d’utiliser la classe JDesktopPane fourni par Swing ou toute autre classe permettant de gérer l’affichage des fenêtres y compris JFrame et JInternalFrame ainsi que toute autre classe qui permet la création de la fenêtre gérée par le système d’exploitation à l’exception de la fenêtre principale de votre application. A part cette restriction, vous pouvez utiliser les librairies de votre choix à condition qu’elles soient compatibles avec les principaux systèmes d’exploitation : Windows, Linux et Mac OS. En cas de doutes, vérifiez avec votre chargé de TD.

Le package principal devra s’appeler avec les deux noms du binôme : Nom1Nom2, et ne contenir qu’une classe avec la fonction main().

Galerie

Voici une liste non-exhaustive de projets dont vous pouvez vous inspirer :

Foire aux questions

Mon programme n’affiche rien

Mon programme compile sans erreur, mais n’affiche qu’une fenêtre vide.

Le simple fait de compiler sans erreur ne suffit pas à vérifier qu’il n’y a pas d’erreur sémantique telle qu’une référence nulle est passée à une fonction. Vérifiez la sortie que votre programme a faite dans la ligne de commande (“Console” en Eclipse). Souvent, vous y trouverez un message d’erreur tel que “NullPointerException” et une liste des appels des fonctions. Trouvez la première fonction dans cette liste qui est définie dans votre code en utilisant le nom de fichier et le numéro de la ligne problématique. Commencez votre mise à point dès cette ligne.

Je n’ai pas de message dans la ligne de commande, mais le programme n’affiche toujours rien.

Vérifiez que vous avez rajouté vos éléments de l’interface au panel de contenu de la fenêtre accessible via la fonction JFrame.getContentPane. Vous ne pouvez pas mettre les éléments graphiques directement dans la fenêtre sans passer par contentPane. Par contre vous pouvez le remplacer par un autre et unique élément.

Quelle est la différence entre AWT et Swing?

Pourquoi certaines fonctions accèptent Container au lieu de JPanel ? Qulle est la différence entre Frame et JFrame ?

AWT (Abstract Windowing Toolkit) est un ensemble de classes Java présent depuis les versions très anciennces du langage qui fournit une interface commune aux systèmes de fenêtrage. Ces classes permettent d’utiliser les fenêtres et les widgets natifs du système d’exploitation à travers les mêmes méthodes. Swing est un ensemble des classes écrit en Java fournissant plusieurs widgets standard sans avoir recours aux ceux du système d’expoitation. Il ne depend pas des particularités du système bien que, souvent, il soit plus lent à l’exécution. Pour ce faire, il duplique la fonctionnalité présente dans le système. Afin que cette dernière reste accéssible, les classes Swing sont différentes de celles de AWT. Le plupart des classes Swing commence par la lettre J. Vous êtes encouragés d’utiliser Swing dans vos exercices. Mélanger les classes Swing et AWT dans la même interface peut avoir des conséquence imprévisible puisque le système d’exploitation traite les widgets Swing comme des image alors que ceux de AWT sont les “vrais” widgets.

Pourquoi l’utilisation de vraies fenêtres dans le projet est interdite ?

Pourquoi il est interdit d’utiliser JFrame, JInternalFrame ou JDesktop ?

Quelle est la fonctionnalité pricnipale du gestionnaire des fenêtres ?

La fonctionnalité principale du gestionnaire des fenêtres et d’assurer l’affichage correcte des celles-ci, notamment en cas de chevauchement si une fenêtre bloque en partie l’affichage d’une autre. Pour ce faire, il est nécessaire de stocker la position, la taille et l’ordre d’affichage des fenêtres. Ce dernier change quand l’utilisateur interagit avec une fenêtre en cliquant dessus par exemple ; la fenêtre active devient première par ordre tandis que toutes les autres sont poussées au fond tout en gardant leur ordre relatif précédent. Cette fonctionnalité est déjà présente dans le gestionnaire des fenêtres du système d’exploitation, et elle s’applique automatiquement aux toutes les fenêtres système que vous créez en utilisant JFrame, JInternalFrame etc. Vous êtes demandés des réaliser cette fonctionnalité vous-même, et il est donc interdit d’utiliser celle fornie par le système d’exploitation.

Comme l’IHM s’interesse aux interactions de base dans les interfaces graphiques, il est souvent nécessaire de remplacer la fonctionnalité système par la vôtre afin de pouvoir innover et tester des differentes techniques d’interaction. Par exemple le chargé de cours l’a fait pour son papier de recherche Metisse is not a 3D desktop!. Ce projet à pour but de vous apprendre à la fois la programmation des interfaces et les bases de conception des interactions avancées remplacant celles disponibles par défaut.