Les interfaces utilisateurs sont souvent décomposées en écrans, c'est à dire en vues qui sont concues pour exposer les informations et actions utiles durant une phase précise de l'interaction. Par exemple, le menu principal d'un logiciel peut être complètement différent de son interface habituelle, car il joue un rôle spécifique.
Typiquement, un écran sera une fenêtre (JFrame, ou JDialog pour une version modale). Elle peut être affichée ou cachée par la méthode setVisible, et fermée définitivement par la méthode dispose.
Une transition d'un écran à un autre reviendra souvent à cacher ou fermer l'écran actif, puis montrer l'écran suivant. Alternativement, pour souligner que l'écran actif n'est abandonné que momentanément, on peut le figer sans le cacher et afficher par dessus le nouvel écran de façon modale.
Régulièrement, une transition ne nécessite de changer qu'une partie de l'écran. Dans ce cas un changement de fenêtre est inapproprié.
Si la transition ne change pas la disposition des composants de la fenêtre, en termes de code ce n'est pas vraiment une transition mais seulement un rafraîchissement. Par exemple, changer le texte d'une étiquette ou désactiver un bouton ne nécessite qu'un équivalent de la méthode repaint.
Si la transition ajoute, enlève ou redimensionne un JComponent, alors la transition sera plus coûteuse et demande un appel à la méthode revalidate.
Pour ajouter un composant, on peut invoquer la méthode add d'un Container comme d'habitude (à la différence que ceci se produit après que la fenêtre ait été rendue visible). Pour en enlever un autre, on emploie remove, toujours sur le Container. Pour changer les dimensions, on change simplement les propriétés du JComponent, du Container ou de son LayoutManager. Tout ceci n'aura aucun effet visible sur la fenêtre, jusqu'à ce que vous appeliez pour conclure la méthode revalidate.
Attention Un composant qui a été rendu visible puis retiré (par la méthode remove) ne peut plus jamais devenir visible à nouveau. Un nouvel objet devra être créé pour le remplacer.
Le problème avec une transition partielle est qu'elle est relativement lente car elle doit recalculer la géométrie de toute la fenêtre. Il peut également s'avérer difficile de faire collaborer le code de plusieurs transitions qui modifient la même fenêtre. Une solution plus élégante consiste à préparer à l'avance chaque version de la fenêtre (ou d'une partie de celle-ci), afin de passer de l'une à l'autre sans effort.
Il est utile de considérer chaque version comme un onglet : on ne peut en voir qu'une à la fois, mais les autres sont déjà prêtes, cachées juste en dessous. La différence dans notre cas est que l'onglet visible est sélectionné par le code et nous n'avons donc pas besoin d'afficher les contrôles d'onglets dont vous avez l'habitude.
Dans AWT comme dans Swing, ceci est rendu possible par le biais du gestionnaire de mise en page CardLayout. Lorsqu'un Container est géré de la sorte, tous ses enfants occupent la totalité de sa surface, mais un seul est visible (celui qui est « dessus »). Le choix de l'onglet visible est modifié par les méthodes first, last, next, previous et show.
Remarque Ces méthodes ont besoin de la référence au Container, ce qui n'est normalement pas difficile à obtenir. Cependant, dans le cas de JFrame il y a un piège. Cette classe se comporte comme un conteneur mais elle délègue en fait ce rôle à un autre objet. Pour obtenir la référence au véritable conteneur, il faut appeler la méthode getContentPane.
Galerie. Écrivez une application qui affiche une image parmi une série. En cliquant dans la moitié droite de la fenêtre, on passe à l'image suivante. En cliquant dans la moitié gauche, on passe à l'image précédente. La dernière image et la première seront reliées pour former une boucle.
Aucune redéfinition de paintComponent n'est autorisée dans cette question : les images seront affichées dans des JLabel.
image = new JLabel(new ImageIcon("cute_overload.gif"));
Deux versions de cette application sont demandées :
Confirmation. Modifiez le programme de la question précédente de façon à ce qu'un clic sur le bouton système de fermeture provoque l'apparition d'une fenêtre modale qui demande si l'utilisateur veut effectivment quitter le programme. En cas de réponse positive les deux fenêtres se ferment et le programme se termine. Dans le cas contraire, seule la fenêtre modale se ferme et on revient à la fenêtre principale.
La fenêtre modale devra être créée de toutes pièces par vos soins en partant de la classe JDialog.