Swing : les interfaces graphiques

Ce chapitre est une introduction au développement d’application graphique en Java à l’aide de la bibliothèque Swing.

Swing permet de développer des applications graphiques portables en Java. Cela signifie que ces applications fonctionneront de manière identique quels que soient le système d’exploitation et l’environnement graphique utilisé. Swing a été conçu plus spécifiquement pour créer des applications pour ordinateur de bureau (desktopenvironment). Il est composé d’un ensemble de classes qui se trouvent dans le package javax.swing ainsi que dans ses sous-packages.

Note

Depuis Java 8, Swing n’est plus la bibliothèque de référence pour créer des applications graphiques : elle a été remplacée par JavaFX. Néanmoins, Swing reste encore largement connu et donc utilisé par les développeurs.

Swing a lui-même remplacé une bibliothèque Java plus ancienne nommé AWT(Abstract Window Toolkit). Cette dernière offrait un accès en Java à l’API graphique du système alors que Swing offre des composants graphiques totalement implémentés en Java (et donc avec un comportement et un rendu identiques quel que soit le système sous-jacent). AWT est toujours présent dans la bibliothèque standard de Java et ses classes se trouvent dans le package java.awt . Swing utilise une partie des classes fournies par AWT.

Une première application

Dans une interface graphique, le composant graphique fondamental est la fenêtre. Une fenêtre dispose généralement d’une barre de titre, un cadre et éventuellement une barre de menu et une barre d’état. Dans Swing, une fenêtre correspond à La classe JFrame.


import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;

public class HelloWorld {

  public static void main(String[] args) {
    JFrame window = new JFrame("Première appli");
    window.add(new JLabel("Hello world!"));
    window.setSize(300,100);
    window.setLocation(100, 100);
    window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    window.setVisible(true);
  }
}

Le code ci-dessus crée une fenêtre dans laquelle est écrit « Hello world! ».

  • ligne 10 : création d’une instance de JFrame qui représente la fenêtre principale (et unique) pour cette application. Le paramètre de constructeur indique le titre à afficher dans la barre de titre.
  • ligne 11 : on ajoute un composant graphique de type JLabel qui correspond à un libellé.
  • ligne 12 : on indique la dimension en pixels de la fenêtre (largeur puis hauteur)
  • ligne 13 : on indique la position à l’écran de la fenêtre. La position est donnée en pixels depuis le bord supérieur gauche de l’écran.
  • ligne 14 : on spécifie une opération par défaut lorsque la fenêtre est fermée par l’utilisateur (par exemple lorsqu’il clique sur le bouton fermer de la barre de titre). Pour cet exemple, on indique la constante EXIT_ON_CLOSE qui indique que le programme doit s’arrêter lorsque cette fenêtre est fermée.
  • ligne 15 : on rend la fenêtre visible, ce qui déclenche son affichage.

Une chose peut paraître surprenante : après la ligne 15, le programme ci-dessus ne fait plus rien, la méthode main se termine et donc le programme devrait s’arrêter. Mais il n’en est rien. Si vous exécutez ce code, une fenêtre s’affiche et le programme continue de s’exécuter tant que la fenêtre n’est pas fermée. En fait la méthode main se termine effectivement mais comme la fenêtre a été rendue visible à la ligne 15, cela a déclenché la boucle des événements Swing (eventloop). La boucle des événements est une boucle qui s’exécute dans un processus léger (thread). Elle traite continuellement les événements que reçoit l’application graphique. Par exemple, si l’utilisateur appuie sur une touche du clavier ou bouge la souris,la boucle des événements en est alertée et crée des objets pour représenter ces événements. Pour les exemples donnés, il s’agira d’instances de KeyEvent et de MouseEvent. Tant que la boucle des événements s’exécute, l’application ne peut pas s’arrêter (même si toutes les fenêtres de l’application ont été fermées).C’est pour cela qu’à la ligne 14, on précise que si la fenêtre est fermée, alors il faudra déclencher un événement de sortie (EXIT_ON_CLOSE) qui mettra fin à boucle des événements et arrêtera l’application.

Les principaux composants

Les composants graphiques Swing sont conçus comme des conteneurs. D’ailleurs, ils héritent indirectement de la classe AWT Container. Cela signifie qu’une instance de JFrame (une fenêtre) contient des composants graphiques qui eux-mêmes peuvent contenir des composants graphiques, etc, etc. Donc on peut imaginer une interface graphique sous la forme d’un arbre dont la racine est constituée par une instance de JFrame. Pour ajouter un composant graphique dans un autre composant graphique, on peut utiliser une des méthodes add héritées de Container. On peut également supprimer un composant d’un autre avec la méthode Container.remove ou Container.removeAll.

Parmi les composants graphiques les plus couramment utilisés en Swing, on trouve:

JPanel
Ce composant a une représentation graphique vide (à l’exception d’une couleur de fond). Il sert soit à grouper des composants dans une arborescence de composants graphiques soit comme classe parente pour créer un composant graphique plus élaboré.
JLabel
Ce composant représente une zone de texte ou une image à afficher. Généralement, il est utilisépour afficher des textes cours. Une instance de JLabel ne réagit pas aux événements (notamment de type clavier). Il est conçu pour fournir un libellé ou une icône pour un champ de saisi (d’où son nom).
JTextField
Ce composant représente une champ texte éditable par l’utilisateur.
JTextArea
Ce composant représente une zone de texte éditable par l’utilisateur. Le JTextArea est plus adapté que le JTextField lorsqu’on veut représenter du texte sur plusieurs lignes.
JEditorPane
Ce composant correspond à un éditeur de texte riche. Il peut afficher du texte avec des informations de formatage (comme des balises). Par défaut, il supporte le texte brut (text/plain), le HTML (text/html) et le RTF(text/rtf).
JCheckBox
Ce composant correspond à une case à cocher.
JRadioButton
Ce composant représente un bouton radio.
JComboBox
Ce composant fait apparaître une liste de choix que l’utilisateur peut sélectionner. La JComboBox supporte la sélection unique ou la multi sélection.
JProgressBar
Ce composant dessine une barre de progression.
JButton
Ce composant représente un bouton.
JSeparator
Ce composant affiche un trait pour marquer une séparation entre deux composants
JSpinner
Ce composant affiche une boite de saisie avec deux flèches (une vers le haut et une vers le bas). Il s’agit le plus souvent d’afficher un nombre et de donner la possibilité à l’utilisateur d’incrémenter ou de décrémenter ce nombre en cliquant sur les flèches.
JTabbedPane
Ce composant permet d’afficher plusieurs onglets. Chaque onglet contient un composant Swing.

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.WindowConstants;

public class ExempleComposant extends JFrame {

  private JTabbedPane tabbedPane;

  @Override
  protected void frameInit() {
    super.frameInit();
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setName("Exemple composants");
    tabbedPane = new JTabbedPane();
    this.add(tabbedPane);

    addComponent("Label",
                 new JLabel(UIManager.getIcon("FileView.computerIcon")),
                 new JLabel("Libellé avec du texte"));

    addComponent("Text field", new JTextArea("champ de texte"));
    addComponent("Text area", new JTextArea("zone de texte"));
    addComponent("Combo box", new JComboBox(new String[] {"Bleu", "Rouge", "Vert"}));
    addComponent("Check box", new JCheckBox("une boite à cocher"));
    addComponent("Spinner", new JSpinner());
    addComponent("Editor", new JEditorPane("text/html", "

Un éditeur de texte riche

")); JProgressBar progressBar = new JProgressBar(); progressBar.setValue(60); addComponent("Progress bar", progressBar); addComponent("Button", new JButton("Un bouton")); } private void addComponent(String titre, JComponent... components) { JPanel panel = new JPanel(); for (JComponent component : components) { panel.add(component); } tabbedPane.add(titre, panel); } public static void main(String[] args) { JFrame window = new ExempleComposant(); window.setSize(500, 400); window.setLocationRelativeTo(null); window.setVisible(true); } }

Le programme ci-dessus présente un exemple d’affichage des principaux composants graphiques. Il définit la classe ExempleComposant qui hérite de JFrame . Il s’agit d’un méthode assez courante pour créer des applications graphiques avec Swing. On crée un nouveau composant qui hérite de JFrame pour jouer le rôle d’une fenêtre dans notre application. Ce composant redéfinit la méthodeJFrame.frameInit (à partir de la ligne 23) qui lui permet d’effectuer toutes les opérations d’initialisation. Dans notre cas, il s’agit de créer une instance de JTabbedPane, puis de créer un exemple de chaque composant et de l’ajouter dans le tabbedPane grâce à la méthode privée addComponent déclarée à la ligne 46. Notez que les composants ne sont pas directement ajoutés au tabbedPane mais à une instance de JPanel qui est ajoutée au tabbedPane.

Note

À la ligne 57, on appelle la méthode Window.setLocationRelativeTo qui permet de positionner une fenêtre à la même position qu’un autre composant graphique. En passant null comme paramètre, cela positionne la fenêtre au centre de l’écran.

Les layouts

Lorsqu’on ajoute plusieurs composants graphiques dans un conteneur, on souhaite organiser visuellement ces composants d’une certaine manière. Par exemple, pour un formulaire de saisie, on souhaite afficher ligne par ligne un champ libellé avec son champ de texte de saisie. Si le conteneur graphique change de taille (parce que la fenêtre change de dimension ou parce que les autres composants autour du conteneur changent), on souhaite que le contenu conserve une cohérence dans son organisation. Un type d’agencement est appelé un layout et il existe en Swing des objets qui représentent des types de layout particulier.

Chaque composant Swing a une taille préférée (une hauteur et une largeur enpixels) qui est donnée par la méthode Container.getPreferredSize. Par exemple, une instance de JButton va donner une taille qui lui permet d’afficher correctement son libellé ainsi que le dessin qui représente le cadre du bouton lui-même. Un layout doit tenir compte de la taille préférée de tous les composants dont il a la charge. Swing fournit huit layouts différents : BorderLayout ,BoxLayout,CardLayout,FlowLayout,GridBagLayout,GroupLayout,GridLayout,SpringLayout.

Note

Les sections ci-dessous ne couvrent pas tous les layouts.Vous pouvezvous reporter au guide officiel :https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

Le BoxLayout

Le BoxLayoutpermet d’organiser les composants selon l’axe de la page (PAGE_AXIS),c’est-à-dire verticalement ou selon l’axe de la ligne (LINE_AXIS),c’est-à-direhorizontalement.


import java.awt.FlowLayout;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class ExempleBoxLayout extends JFrame {

  @Override
  protected void frameInit() {
    super.frameInit();
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setName("Exemple box layout");
    this.getContentPane().setLayout(new BoxLayout(this.getContentPane(), BoxLayout.PAGE_AXIS));

    addRow("Civilité", new JComboBox(new String[] {"Madame", "Monsieur"}));
    addRow("Nom", new JTextField());
    addRow("Prénom", new JTextField());
    addRow("Addresse", new JTextArea(10, 20));
    addButtons(new JButton("Ok"), new JButton("Annuler"));
    this.pack();
    this.setResizable(false);
  }

  private void addRow(String titre, JComponent... components) {
      JPanel panel = new JPanel();
      panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
      panel.setBorder(BorderFactory.createEmptyBorder(5, 20, 5, 20));

      JLabel label = new JLabel(titre);
      label.setLabelFor(components[0]);
      panel.add(label);

      for (JComponent component : components) {
        panel.add(Box.createHorizontalStrut(10));
        panel.add(component);
      }
      this.add(panel);
  }

  private void addButtons(JButton...buttons) {
    FlowLayout flowLayout = new FlowLayout(FlowLayout.RIGHT);
    JPanel panel = new JPanel(flowLayout);
    for (JButton button : buttons) {
      panel.add(button);
    }
    this.add(panel);
  }

  public static void main(String[] args) {
    JFrame window = new ExempleBoxLayout();
    window.setLocationRelativeTo(null);
    window.setVisible(true);
  }

}

Le programme ci-dessus produit une fenêtre de formulaire :

../_images/exemple_boxlayout.png

À la ligne 25, on ajoute une instance de BoxLayoutcomme layout dans lecontent pane.

Note

Un objet de type JFramepossède une hiérarchie de composants particulière.Comme il représente une fenêtre, il peut posséder une barre de menu, unebarrede statut et une zone de contenu appelée le content pane. Lorsqu’onajouteun composant dans une instance de JFrame,on ajoute en fait le composantà son content pane. Si on veut modifier le type de layoutde la fenêtre, ils’agit en fait du layout de sa zone centrale et donc du contentpane.

La méthode addRow déclarée à la ligne 36 permet d’ajouter les lignes duformulaire. Une ligne correspond à une instance de JPaneldont le layout estgéré par une instance de BoxLayout.À la ligne 46, on crée une Boxgrâce àla méthode static Box.createHorizontalStrut.Cette boite permet de donnerun écart minimal en pixels entre deux composants.

La méthode addButtons déclarée à la ligne 52 permet de créer une lignecontenantles boutons en bas du formulaire. Là encore, la ligne est représentée par unJPanel.Mais son layout est ici géré par une instance de FlowLayout .UnFlowLayoutorganise les composants les uns à la suite des autres en permettantde spécifier un alignement. Pour notre application on demande que les boutonssoient alignés à droite (FlowLayout.Right).

À la ligne 32, on appelle la méthode pack.Comme son nom l’indique, cette méthodecompacte les dimensions du composant graphique afin que sa taille soit minimale.Appliquéeà notre classe qui représente la fenêtre de l’application, cette méthode forceles gestionnaires de layout à organiser visuellement les composantsgraphiquespour qu’ils s’affichent correctement. Puis, à la ligne 33, on spécifie que lafenêtre de l’application ne peut pas être redimensionnée.

Le GridBagLayout

Le GridBagLayoutpermet de gérer le layout comme une grille fictive. Chaque composanta des contraintes de positionnement. Ces contraintes sontreprésentées par les attributs d’une instance de GridBagConstraints:

gridx, gridy
Ces attributs indiquent la position dans la grille (colonne et ligne).
gridwidth, gridheight
Ces attributs indiquent si le composant s’étend sur plusieurscases (horizontalement et verticalement) de la grille.
weightx, weighty
Ces attributs donnent le poids du composant : c’est-à-dire le pourcentage del’espace qu’il occupe par comparaison aux autres à l’horizontal et à laverticale.
fill
Cet attribut indique comment le composant remplit la case dans laquelle ilsetrouve.

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class ExempleGridBagLayout extends JFrame {

  @Override
  protected void frameInit() {
    super.frameInit();
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setTitle("Exemple grid bag layout");
    this.getContentPane().setLayout(new GridBagLayout());

    int rowIndex = 0;
    addRow(rowIndex++, "Civilité", new JComboBox(new String[] {"Madame", "Monsieur"}));
    addRow(rowIndex++, "Nom", new JTextField());
    addRow(rowIndex++, "Prénom", new JTextField());
    addRow(rowIndex++, "Addresse", new JTextArea(10, 20));
    addButtons(rowIndex++, new JButton("Ok"), new JButton("Annuler"));
    this.pack();
    this.setResizable(false);
  }

  private void addRow(int rowIndex, String titre, JComponent component) {
    // création des contraintes de positionnement
    GridBagConstraints cst = new GridBagConstraints();
    // le composant doit occuper tout l'espace horizontal de sa case
    cst.fill = GridBagConstraints.HORIZONTAL;
    // le composant doit être aligné sur le haut de la case
    cst.anchor = GridBagConstraints.NORTH;
    // on définit la marge en pixels pour le haut, la gauche, le bas et la droite
    cst.insets = new Insets(5, 20, 5, 20);
    // on définit la position verticale
    cst.gridy = rowIndex;
    // on définit la position horizontale
    cst.gridx = 0;
    // poids relatif à l'horizontal
    cst.weightx = .3;

    JLabel label = new JLabel(titre);
    label.setLabelFor(component);
    this.add(label, cst);

    // on définit la position horizontale
    cst.gridx = 1;
    // poids relatif à l'horizontal
    cst.weightx = .7;
    this.add(component, cst);
  }

  private void addButtons(int rowIndex, JButton...buttons) {
    JPanel panel = new JPanel();
    for (JButton button : buttons) {
      panel.add(button);
    }
    // création des contraintes de positionnement
    GridBagConstraints cst = new GridBagConstraints();
    // on définit la marge en pixels pour le haut, la gauche, le bas et la droite
    cst.insets = new Insets(5, 10, 0, 0);
    // le composant doit occuper tout l'espace horizontal de sa case
    cst.fill = GridBagConstraints.HORIZONTAL;
    // on définit la position verticale
    cst.gridy = rowIndex;
    // on définit la position horizontale
    cst.gridx = 0;
    // le composant s'étend à l'horizontal sur deux cases de la grille
    cst.gridwidth = 2;
    this.add(panel, cst);
  }

  public static void main(String[] args) {
    JFrame window = new ExempleGridBagLayout();
    window.setLocationRelativeTo(null);
    window.setVisible(true);
  }

}

Le programme ci-dessus produit une fenêtre de formulaire :

../_images/exemple_gridbaglayout.png

À la ligne 24, on spécifie le GridBagLayoutcomme layout pour le content pane.Aux lignes 38 et 69, chaque méthode de création des composants crée une instancede GridBagConstraints de manière à spécifier les contraintes de placement quisont ensuite passées en paramètres au moment de l’ajout des composants auxlignes60 et 80.

Le GridBagLayoutest particulièrement utile pour des fenêtres de type formulairequi sont le plus souvent organisées par rapport à une grille. Il évite d’avoir àcréerdes objets de type JPanelpour grouper les composants entre eux.

Le SpringLayout

Le SpringLayoutoffre la plus grande liberté pour définir un layout. Les composantssont simplement ajoutés au conteneur utilisant ce gestionnaire delayout. Puis,on déclare des contraintes spatiales entre les composants ou entre lescomposantset le conteneur.


import java.awt.Container;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.WindowConstants;

public class ExempleSpringLayout extends JFrame {

  private SpringLayout springLayout;

  @Override
  protected void frameInit() {
    super.frameInit();
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setTitle("Exemple spring layout");
    springLayout = new SpringLayout();
    this.getContentPane().setLayout(springLayout);

    Container container = addRow(null, "Civilité", new JComboBox(new String[] {"Madame", "Monsieur"}));
    container = addRow(container, "Nom", new JTextField());
    container = addRow(container, "Prénom", new JTextField());
    container = addRow(container, "Addresse", new JTextArea(10, 20));
    addButtons(new JButton("Ok"), new JButton("Annuler"));
    this.setSize(300,350);
  }

  private Container addRow(Container topContainer, String titre, JComponent component) {
      JLabel label = new JLabel(titre);
      label.setLabelFor(component);
      this.add(label);
      // Un libellé est à 20px du bord gauche
      springLayout.putConstraint(SpringLayout.WEST, label, 20, SpringLayout.WEST, this.getContentPane());
      if (topContainer == null) {
        // Un libellé est à 20px du bord du haut
        springLayout.putConstraint(SpringLayout.NORTH, label, 20, SpringLayout.NORTH, this.getContentPane());
      } else {
        // Un libellé est à 10px de la ligne du dessus
        springLayout.putConstraint(SpringLayout.NORTH, label, 10, SpringLayout.SOUTH, topContainer);
      }

      // Un composant est à 15px du libellé
      springLayout.putConstraint(SpringLayout.WEST, component, 15, SpringLayout.EAST, label);
      // Un composant est à 20px du bord droit
      springLayout.putConstraint(SpringLayout.EAST, component, -20, SpringLayout.EAST, this.getContentPane());
      if (topContainer == null) {
        // Un composant est à 20px du bord du haut
        springLayout.putConstraint(SpringLayout.NORTH, component, 20, SpringLayout.NORTH, this.getContentPane());
      } else {
        // Un composant est à 10px de la ligne du dessus
        springLayout.putConstraint(SpringLayout.NORTH, component, 10, SpringLayout.SOUTH, topContainer);
      }
      this.add(component);
      return component;
  }

  private void addButtons(JButton...buttons) {
    JPanel panel = new JPanel();
    for (JButton button : buttons) {
      panel.add(button);
    }
    this.add(panel);
    // La barre des boutons est à 20px du bord droit
    springLayout.putConstraint(SpringLayout.SOUTH, panel, -20, SpringLayout.SOUTH, this.getContentPane());
    // La barre des boutons est à 20px du bas
    springLayout.putConstraint(SpringLayout.EAST, panel, -20, SpringLayout.EAST, this.getContentPane());
  }

  public static void main(String[] args) {
    JFrame window = new ExempleSpringLayout();
    window.setLocationRelativeTo(null);
    window.setVisible(true);
  }

}

Le programme ci-dessus produit une fenêtre de formulaire :

../_images/exemple_springlayout.png

Le look & feel

Avec Swing, les composants graphiques manipulés par une application ne sontpas directement responsables de leur représentation à l’écran. Il est possible demodifier l’aspect général (le look and feel) d’une application sans changersignificativement l’implémentation. Par défaut,Swing utilise un look and feel identique sur toutes les plates-formes. Maisil est possible de demander d’utiliser un rendu qui corresponde plus à celuide l’environnement graphique de l’utilisateur ou même de fournir un lookand feel personnalisé.


import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.WindowConstants;

public class ExempleComposant extends JFrame {

  private JTabbedPane tabbedPane;

  @Override
  protected void frameInit() {
    super.frameInit();
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setName("Exemple composants");
    tabbedPane = new JTabbedPane();
    this.add(tabbedPane);

    addComponent("Label",
                 new JLabel(UIManager.getIcon("FileView.computerIcon")),
                 new JLabel("Libellé avec du texte"));

    addComponent("Text field", new JTextArea("champ de texte"));
    addComponent("Text area", new JTextArea("zone de texte"));
    addComponent("Combo box", new JComboBox(new String[] {"Bleu", "Rouge", "Vert"}));
    addComponent("Check box", new JCheckBox("une boite à cocher"));
    addComponent("Spinner", new JSpinner());
    addComponent("Editor", new JEditorPane("text/html", "

Un éditeur de texte riche

")); JProgressBar progressBar = new JProgressBar(); progressBar.setValue(60); addComponent("Progress bar", progressBar); addComponent("Button", new JButton("Un bouton")); } private void addComponent(String titre, JComponent... components) { JPanel panel = new JPanel(); for (JComponent component : components) { panel.add(component); } tabbedPane.add(titre, panel); } public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } JFrame window = new ExempleComposant(); window.setSize(500, 400); window.setLocationRelativeTo(null); window.setVisible(true); } }

L’exemple ci-dessus reprend l’application qui affiche différents composantsgraphiques. La seule différence se situe des lignes 55 à 59. Avant de créerla fenêtre principale, on utilise la classe UIManagerpour sélectionner lelook and feel correspondant au système sur lequel l’application s’exécute.

Exercice

Application pour éditer les donnéespersonnelles

Objectif

Créez une application Swing qui permet de saisir lesinformations personnellesd’un utilisateur. Cette application ne permet pas (encore) de sauvegarder nide chargerdes données. Les champs à saisir sont :

  • Le titre : Monsieur, Madame, Docteur, Professeur ou rien (utilisezune liste déroulante)
  • Le prénom
  • Le nom
  • L’émail
  • Le numéro de téléphone
  • L’adresse : rue, code postal, ville
  • La date de naissance

Pour la saisie de la date de naissance, utilisez le composant graphiqueJDatePickerdisponible avec la dépendance Maven :


<dependency>
	<groupId>io.github.lzh0379</groupId>
	<artifactId>jdatepicker</artifactId>
	<version>2.0.3</version>
</dependency>

On peut ensuite créer un JDatePicker et utiliser la méthode getModel()pour positionner ou récupérer la date :


JDatePicker jDatePicker = new JDatePicker(Calendar.getInstance());
System.out.println(jDatePicker.getModel().getDay());
System.out.println(jDatePicker.getModel().getMonth());
System.out.println(jDatePicker.getModel().getYear());
System.out.println(jDatePicker.getModel().getValue());

Un JDatePicker est un composant Swing qui peutêtre ajouté dans un JFrame,un JPanelou n’importe quel composant graphique Swing.

Modèle Maven du projet à télécharger
swing-template.zip
Mise en place du projet
Éditer le fichier pom.xml du template et modifier la baliseartifactId pour spécifier le nom de votre projet.