Semaine 9
Activité 2
Revue de la bibliothèque de codes Java Swing
Sommaire
Le langage Java intègre, depuis sa version 1.2, l’API Swing, un ensemble de classes permettant la création de composantes graphiques. Ces classes proposent des fonctionnalités plus sophistiquées que les plus anciennes classes de l’API Abstract Window Toolkit (AWT) de Java. Par exemple, elles intègrent de façon native (bref, dans le code natif du système d’exploitation de la machine virtuelle Java) le Look and Feel de celui-ci. Le Look and Feel est le standard graphique qu’un système d’exploitation donne à ses composantes graphiques : fenêtres, boîtes de dialogue, boutons, etc.
Look and Feel de Windows vs Mac OS X
JFrame
L’objet de base Swing permettant de créer une fenêtre d’application se nomme JFrame. Il s’agit de la composante graphique correspondant à la fenêtre d’application standard avec boutons aux coins supérieurs (selon le Look and Feel) permettant de réduire ou de fermer la fenêtre. À ce JFrame, il est possible d’apposer des menus (JMenu) et les autres composantes graphiques Swing. Voici un exemple de JFrame.
public class ExempleDeJFrame extends javax.swing.JFrame { /** * Constructeur */ public ExempleDeJFrame() { // Appelle une méthode d’initialisation tel que formaté dans l’IDE NetBeans initComponents(); } /** * Initialise les composantes */ private void initComponents() { // Permet de fermer le JFrame lorsque le bouton standard (coin supérieur) est appuyé setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); // Méthode de l’objet JFrame permettant d’ajuster la taille du JFrame selon les tailles des composantes Swing incluses dans le Frame. Exemple, que la taille du Frame soit supérieure ou égale à la taille d’un bouton inclus dans le frame. pack(); } /** *@param args the command line arguments */ public static void main(String args[]) { // Exemple d’utilisation d’un Look And Feel, dans ce cas-ci Nimbus try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } // Créé un Thread (fil d’exécution) intégrant l’instanciation du JFrame java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new ExempleDeJFrame().setVisible(true); } }); } }
JPanel
L’organisation des composantes à l’intérieur d’un JFrame se fait en utilisant les JPanel et la combinaison de différents layouts (mises en page). Un JPanel est une composante Swing, apparentée à un tableau d’affichage, permettant d’afficher d’autres composantes graphiques Swing selon certaines dispositions gérées par un Layout. La stratégie générale de construction d’une interface avec Swing est de créer une structure de plusieurs JPanel imbriqués (un JPanel peut contenir d’autres JPanel) ayant différents layouts afin d’arriver aux résultats souhaités.
Un JPanel peut être formaté pour afficher des bordures (borders), un fond de couleur spécifique, etc. Également, un JFrame comprend par défaut un premier JPanel. Voici un exemple de JFrame intégrant un JPanel avec une bordure de type TitleBorder.
Code associé à ce JPanel :
public class ExempleDeJFrame extends javax.swing.JFrame { public ExempleDeJFrame() { initComponents(); } private void initComponents() { jPanel1 = new javax.swing.JPanel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); // Spécification du type de bordure jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Exemple de JPanel")); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 388, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 276, Short.MAX_VALUE) ); getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); pack(); } /** *@param args the command line arguments */ public static void main(String args[]) { try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new ExempleDeJFrame().setVisible(true); } }); } private javax.swing.JPanel jPanel1; }
Il existe également un ensemble d’autres composantes de type « conteneur » (container) dans l’API Swing, dont :
- le JTabbedPane – composante permettant d’afficher plusieurs JPanel sous forme d’onglet : https://docs.oracle.com/javase/7/docs/api/javax/swing/JTabbedPane.html )
- JSplitPane – composante permettant d’afficher deux JPanel et divisée par un séparateur dynamique pouvant modifier la taille occupée par les deux JPanel : https://docs.oracle.com/javase/tutorial/uiswing/components/splitpane.html
- JScrollPane – composante permettant de gérer automatiquement les défilements vertical et horizontal sur des panneaux ayant une dimension supérieure à l’espace disponible dans un JFrame : https://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html
- JToolBar – composante permettant d’afficher des boutons à la manière d’une barre d’outils. Cette composante gère automatiquement la modification de l’ordre des items sur la barre : https://docs.oracle.com/javase/tutorial/uiswing/components/toolbar.html
- JMenuBar – composante permettant de gérer l’affichage d’une barre de menus. Cette barre de menus est elle-même composée d’un ensemble d’autres composantes telles que des JMenu et des JMenuItem : https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html
Layout (mise en page)
Comme il est indiqué précédemment, les objets « conteneurs » de Swing tels que le JPanel peuvent être formatés pour gérer automatiquement la disposition des composantes graphiques qu’ils présentent. Certains modèles de mise en page tels que le Absolute Layout permettent de placer des composantes graphiques selon des dispositions précises, mais l’avantage premier de l’utilisation de ces modèles est l’automatisation de la disposition des composantes selon un schéma propre aux modèles utilisés. Les layouts permettent également d’automatiser la disposition des composantes selon la manipulation de la taille des JFrame et JPanel. Par exemple, avec le FlowLayout et la réduction par l’utilisateur de la taille du JFrame, les emplacements des boutons sont automatiquement ajustés dans le JFrame selon la taille disponible :
Code associé à cette figure : public class ExempleDeJFrame extends javax.swing.JFrame { /** * Creates new form ExempleDeJFrame */ public ExempleDeJFrame() { initComponents(); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ private void initComponents() { buttonGroup1 = new javax.swing.ButtonGroup(); jButton1 = new javax.swing.JButton(); jButton2 = new javax.swing.JButton(); jButton3 = new javax.swing.JButton(); jButton4 = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); getContentPane().setLayout(new java.awt.FlowLayout()); jButton1.setText("jButton1"); getContentPane().add(jButton1); jButton2.setText("jButton2"); getContentPane().add(jButton2); jButton3.setText("jButton3"); getContentPane().add(jButton3); jButton4.setText("jButton4"); getContentPane().add(jButton4); pack(); } /** *@param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see https://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(ExempleDeJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new ExempleDeJFrame().setVisible(true); } }); } private javax.swing.ButtonGroup buttonGroup1; private javax.swing.JButton jButton1; private javax.swing.JButton jButton2; private javax.swing.JButton jButton3; private javax.swing.JButton jButton4; }
Chaque sous-classe de JLayout a son utilité et gère de façon différente la disposition des composantes graphiques. Voici un résumé des modèles de mise en page les plus utilisés. Vous pouvez également consulter le document officiel (en anglais) sur le site Java/Oracle (https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) :
Type de modèles de mise en page | Description |
AbsoluteLayout | Il s’agit en fait du modèle de mise en page par défaut lorsque celui-ci n’est pas spécifié (p. ex., *.setLayout(null)).
Place les objets selon des références en x et y selon le point de référence (0,0) correspondant au coin supérieur droit du JFrame.
Documentation officielle (en anglais) : https://docs.oracle.com/javase/tutorial/uiswing/layout/none.html |
BorderLayout | Place les objets selon 5 zones prédéfinies : nord, sud, est, ouest et centre. Très pratique pour construire un formulaire dans la zone centrale et des boutons dans la zone sud : Ici, la zone centrale est un JPanel ayant une bordure titrée « Formulaire » et la zone sud est un JPanel avec 2 boutons.
Documentation officielle (en anglais) : https://docs.oracle.com/javase/tutorial/uiswing/layout/border.html
|
FlowLayout | Il s’agit du modèle de mise en page par défaut de tous les JPanel. Il place les objets sur une même ligne (quand l’espace le permet) depuis la gauche vers la droite. Il gère automatiquement l’espace entre les composantes, selon l’espace total disponible. Documentation officielle (en anglais) : https://docs.oracle.com/javase/tutorial/uiswing/layout/flow.html
|
GridLayout | Permet la disposition des composantes de même taille selon une grille comportant des lignes et des colonnes. Documentation officielle (en anglais) : https://docs.oracle.com/javase/tutorial/uiswing/layout/grid.html
|
BoxLayout | Modèle de mise en page qui permet de mettre les composantes sur une seule ligne ou colonne.
Documentation officielle (en anglais) : https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html
|
GridBagLayout | Il s’agit d’un modèle de mise en page permettant de placer des composantes dans un JPanel selon une grille, où les composantes peuvent prendre plus qu’une cellule de la grille. Il est également possible de modifier la hauteur ou largeur de colonnes ou de lignes précises à l’aide du LayoutManager. Documentation officielle (en anglais) : https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
|
Voici une vidéo de type tutoriel présentant l’usage de ces modèle de mise en page et le code produit.
Autres composantes graphiques de Swing
Il existe des composantes Swing équivalentes pour chacun des composantes AWT avec des constructeurs semblables. Voici les principales composantes graphiques de l’API Swing :
Nom de la classe | Description |
JLabel | Il s’agit d’un champ de texte non éditable permettant d’afficher du texte dans une interface graphique. |
JButton | Il s’agit de la composante graphique classique représentant un bouton poussoir. |
JToggleButton | Bouton poussoir ayant un état de type ouvert/fermé. |
JCheckBox | Composante graphique représentant la case à cocher classique. |
JRadioButton | Autre type de case à cocher permettant un choix unique parmi un groupe de JRadioButton. Cette composante est généralement utilisée avec l’objet JButtonGroup (voir ci-dessous). |
ButtonGroup | Objet permettant de contrôler l’utilisation d’un groupe de JRadioButton ou d’autres types de boutons (p. ex., JToggleButton). |
JTextField | Composante graphique permettant à l’utilisateur une entrée textuelle sous la forme d’une seule ligne de texte. |
JTextArea | Composante graphique permettant à l’utilisateur une entrée textuelle sous la forme de plusieurs lignes de texte. |
JList | Composante graphique permettant à l’utilisateur de sélectionner un ensemble d’entrées dans une liste de champs textuels. |
JComboBox | Composante graphique offrant une liste déroulante lorsque l’utilisateur sélectionne la composante. |
JTable | Composante graphique permettant d’afficher un tableau de données qui peuvent être éditables ou ne pas l’être. La gestion du contenu de la table se fait par l’entremise de la création d’une sous-classe de l’objet TableModel.
Un exemple d’utilisation des JTable est présenté dans la vidéo suivante. Voici la documentation officielle d’Oracle : https://docs.oracle.com/javase/tutorial/uiswing/components/table.html |
JTree | Composante graphique permettant d’afficher une arborescence d’éléments (p. ex., un système de fichier). Fonctionne de pair avec une structure de données arborescentes avec l’objet DefaultMutableTreeNode.
Exemple d’utilisation de JTree avec la documentation officielle d’Oracle : https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html |
Voici une vidéo de type tutoriel présentant les principales composantes graphiques de Swing et indiquant la façon de les utiliser dans une interface graphique Java. Voici également le code produit lors de cet exercice (fichier compressé, zip contenant le code source. Il s’agit d’un projet NetBeans que vous pouvez ouvrir dans votre IDE).
Vidéo externe sans voix :
Le code associé est accessible ici: https://koor.fr/Java/SupportSwing/slide1.wp
Il également possible d’ajouter des images de type icône à ces composantes graphiques. Pour ce faire, il suffit d’ajouter l’objet gérant l’affichage de l’icône au constructeur de la composante graphique. Le constructeur d’un objet Icon admet comme seul paramètre le nom ou l’URL d’un fichier graphique.
import javax.swing.*; import java.awt.event.*; public class UneFenetre extends JFrame { public swing3() { super("titre de l'application"); WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e){ System.exit(0); } }; addWindowListener(l); ImageIcon img = new ImageIcon("tips.gif"); JButton bouton = new JButton("Mon bouton",img); JPanel panneau = new JPanel(); panneau.add(bouton); setContentPane(panneau); setSize(200,100); setVisible(true); } public static void main(String [] args){ JFrame frame = new swing3(); } }
Au cours des prochaines semaines, nous apprendrons à mieux connaître ces composantes en les utilisant dans plusieurs exercices. Entre autres, nous y intégrerons de l’événementiel afin que les applications mises au point réagissent aux interactions des utilisateurs avec ces composantes graphiques.







