Tout d'abord, il faut rappeler que la librairie AWT a été developpée pour la première sortie de Java version 1.0 du jdk alors que Swing n'est apparue qu'à la version 1.2 du jdk (soit Java 2). Il en résulte donc des différences fondamentales de conception entre les deux librairies.
Composant AWT :
Un composant AWT lors de sa création est associé à une fenêtre distincte (un homologue, peer en anglais) gérée par le systeme d'exploitation sous-jacent. Et c'est cet homologue qui est responsable de son apparence. Cette "manière" de faire, bien qu'elle ait fait ses preuves et qu'elle ait permis au langage Java de s'imposer, est très lourde (perte de performance, et consommation excessive de mémoire). C'est pour cette raison que l'on qualifie les composants AWT par heavyweight (littéralement, poids lourds)
Composant Swing :
Par opposition, les composants Swing sont simplement dessinés à l'intérieur de leur conteneur comme s'il s'agissait d'une image, et aucun homologue du système sous jacent ne leur est affecté. C'est pourquoi ils sont qualifiés de lightweight (composants allégés).
Nous noterons également que lors du développement avec AWT il suffit d'ajouter les composants directement au Top-level Container (Conteneur de Haut Niveau) tel que Frame, Applet, ..., alors que sous Swing il est nécéssaire de les ajouter à un volet de contenu (Cf : javax.swing.JRootPane). De manière plus parlante je veux parler du :
jframe.getContentPane().add(monComposant);
Voila, ces quelques différences ne sont bien sûr pas exhaustives, Swing posséde bien d'autres avantages, je ne citerai que : la gestion de bordure, les info-bulles, le défilement, les Look And Feel, de nouveaux LayoutManager, ainsi que l'architecture MVC (Model-View-Control). Maintenant que l'on a conscience de ces différences, une question reste tout de meme en suspens... Peut-on mélanger Awt et Swing ?
Il est impossible d'obtenir un rendu graphique correct dans une application qui mélange AWT et SWING. Des problèmes de superposition empêchent toute collaboration.
Le composant JFrame comprend un objet fils qui prend en charge tout ce qui concerne le graphique, il s'agit d'une instance de JRootPane. Le composant JRootPane est lui même structuré. Il contient un volet structuré en couche (instance de JLayeredPane) et un volet structuré en pellicule (GlassPane).
Le composant LayeredPane permet d'insérer une barre de menu ainsi que tout autre composant (cela fait référence au fameux contentPane de jframe.getContentPane ()). il est également chargé du Z-ordering (algorithme permettant de ne dessiner que les parties non cachées, suite aux superpositions de composant).
Le composant GlassPane représente une pellicule qui recouvre tout et qui par exemple peut intercepter tous les événements souris de l'interface graphique.
Lorsque l'on ouvre le menu contextuel du <javaClass class="JComboBox"/>, ce dernier est caché par le composant bouton de type <javaClass class="java.awt.Button"/>.
Le rendu graphique du composant "bouton" issu de la librairie AWT est délégué à son homologue (peer), par conséquent la position Z est la même que celle de la Frame (soit de haut niveau)
Alors que le composant "combo" de type JComcoBox (Swing) n'est que "dessiné" comme une image sur le conteneur (soit de bas niveau)
La seule solution envisageable est d'uniformiser le code sur la librairie graphique utilisée, soit tout AWT, soit tout Swing !
Ce problème est très classique lors d'un long traitement dans une application graphique. En Java, un processus est chargé de toutes les opérations liées à l'affichage et à la gestion des évènements, le processus "the event dispatching thread". Si une application utilise ce processus pour faire un traitement de plusieurs minutes, c'est autant de temps où l'application ne sera plus réactive aux actions de l'utilisateur, ni aux mise à jour graphiques (d'une barre de progression par exemple).
Solution :
La solution est assez simple à comprendre : tout traitement long doit être effectué par un autre processus.
Voici deux codes sources Java commentés. <file href="JProgress.java"/> : la mauvaise méthode (la vôtre ?) <file href="JProgress2.java"/> = une solution
Les classes <javaClass class="java.awt.Frame"/> et <javaClass class="javax.swing.JFrame"/> correspondent aux fenêtres du système d'exploitation, il n'est pas possible de changer l'apparence de la barre des titres ni des boutons de fermeture et d'aggrandissement.
Window & JWindow
Contrairement aux 2 classes precédentes, <javaClass class="java.awt.Window"/> et <javaClass class="javax.swing.JWindow"/> définissent une fenêtre sans aucun cadre ni barre de titre. Elle sont donc idéales pour faire des écrans de démarrage ou des interfaces personalisées.
A partir du JDK1.4
Le jdk1.4 défini une nouvelle méthode <javaMethode methode="setUndecorated(boolean)" class="java.awt.Frame" /> pour les classes <javaClass class="java.awt.Frame" /> et <javaClass class="java.awt.Dialog" />. Attention: cette méthode doit être appelé avant le première affichage de la fenetre à l'écran.
Avant d'utiliser une police de caractères, il est fortement recommandé de vérifier qu'elle est présente sur le système. Les systèmes alternatifs disposent rarement des mêmes polices que Windows.
<comment>Liste de toutes les polices :</comment>Font[ ] polices = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();<comment>Liste des noms de toutes les polices :</comment>String[ ] nomPolices = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
L'icone d'une application apparait à divers endroits en fonction du système d'exploitation. Sous windows, on la retrouve en haut à gauche de la fenêtre, et dans la barre des taches. Par defaut il s'agit de la tasse de café de Java, il est très facile de la personnaliser en utilisant la méthode <javaMethode methode="setIconImage(java.awt.Image)" class="javax.swing.JFrame" /> des classes <javaClass class="javax.swing.JFrame" /> et <javaClass class="javax.swing.JDialog" />.
Par défaut, les fenêtres Swing sont cachées lorsque l'utilisateur clic sur la croix. Cette action par defaut peut facilement être remplacée.<javaMethode methde="setDefaultCloseOperation(int)" class="javax.swing.JFrame"/>.
DO_NOTHING_ON_CLOSE - Ne fait aucune action par défault.
HIDE_ON_CLOSE - Cache la fenêtre.
DISPOSE_ON_CLOSE - Détruit la fenêtre.
EXIT_ON_CLOSE - Quitte l'application.
Note : La solution utilisée avec AWT reste valable avec Swing, elle permet d'effectuer des traitements plus complexe en parallèle du traitement par defaut.
Lorsque l'on affiche une fenêtre à l'écran, la machine virtuelle alloue la mémoire et les ressources systèmes nécessaires à la création de l'image de cette fenêtre à l'écran. Les méthodes <javaMethode methode="hide()" class="java.awt.Window"/> et <javaMethode methode="dispose()" class="java.awt.Window"/> font tous les deux disparaître la fenêtre de l'écran ; en revanche, elles diffèrent par leur action sur la mémoire.
Cacher une fenêtre avec hide() :
La méthode <javaMethode methode="hide()" class="java.awt.Window"/> se contente de masquer la fenêtre, les ressources nécessaires à son affichage sont conservées. La fenêtre est donc prête à être réaffichée. C'est une bonne idée de cacher les fenêtres qui sont utilisées régulièrement par l'application, leur réaffichage est plus rapide.
Détruire une fenêtre avec dispose() :
La méthode <javaMethode methode="dispose()" class="java.awt.Window"/> restitue les ressources au système. Les ressources libérées ne concernent que les objets utilisés pour la construction de l'image, les différents composants que vous avez placés dans la fenêtre restent en mémoire comme n'importe quel autre objet. Même après avoir été détruit, on peut toujours utiliser la méthode <javaMethode methode="show()" class="java.awt.Window"/> pour réafficher la fenêtre (de nouvelles ressources seront alors allouées). C'est donc une très bonne idée de détruire les fenêtres lorsque vous n'en avez plus besoin.
Note :
Tant qu'une fenêtre n'est pas détruite, elle ne peut pas être collectée par le rammasse miette.
Ce document issu de http://www.developpez.com est soumis à la licence GNU FDL traduit en français ici.
Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement.