Interface graphique¶
Pour commencer¶
Packages¶
java.awt
: première bibliothèque. Fournit des interfaces et des composants limités en code natif.javax.swing
: seconde bibliothèque. Ne remplace pasjava.awt
, mais la complète avec des composants originaux et/ou performants, écrits en Java.On va utiliser
javax.swing
en priorité (composants commençant parJ
), mais aussijava.awt
(layout managers, événements).
Hello World¶
import javax.swing.*;
public class HelloWorldSwing implements Runnable {
@Override
public void run() {
//Create the window
JFrame f = new JFrame("HelloWorldSwing");
//Set the behavior for when the window is closed
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add a label
f.getContentPane().add(new JLabel("Hello world!"));
//Set the window size from its components size
f.pack();
//By default, the window is not visible; make it visible
f.setVisible(true);
}
public static void main(String[] args) {
//Run the application at the correct time in the event queue
SwingUtilities.invokeLater( new HelloWorldSwing() );
}
}
Event-Dispatching Thread¶
Au lancement d’une application graphique, en plus du thread principal, est lancé un second thread appelé Event-Dispatching Thread (EDT).
Une application graphique est réactive aux évenements (clic sur un bouton par exemple). Or les réactions (affichage d’un commentaire par exemple) sont placées dans une file et exécutées les unes après les autres dans l’EDT.
Les composants graphiques sont thread unsafe. C’est une erreur fréquente de les manipuler depuis plusieurs threads. Les autres threads doivent soumettre leur code à exécuter à l’EDT pour éviter les incohérences.
Structure d’une fenêtre¶
Hiérarchie de conteneurs¶
Le nom des conteneurs de javax.swing
commencent par J
.
Chaque application graphique possède au moins un conteneur de haut-niveau:
JFrame
(fenêtre)JDialog
(boîte de dialogue)JApplet
(fenêtre à intégrer dans une page web)
Ces conteneurs possèdent un panneau d’affichage (accessible par getContentPane()
, setContentPane()
)
sur lequel vous pouvez disposer des composants (qui dérivent de JComponent
).
Composants graphiques¶
- Il existe de nombreux composants graphiques:
JPanel
(conteneur générique léger)JLabel
(étiquette de texte)JButton
(bouton)JTextField
(champs texte pouvant être éditable)JMenuBar
(barre des menus)…
Consultez l’API standard
pour la liste des composants disponibles dans javax.swing
.
Personnaliser le panneau d’affichage¶
Habituellement, on crée un nouveau panneau d’affichage de zéro
en utilisant JPanel
, puis on l’ajoute au conteneur de haut
niveau (typiquement de type JFrame
) avec setContentPane()
.
//Create a panel and add components to it.
JPanel contentPane = new JPanel();
contentPane.add(someComponent);
contentPane.add(anotherComponent);
topLevelContainer.setContentPane(contentPane);
Layout Manager¶
Il existe des modèles pour disposer les composants graphiques sur un panneau d’affichage:
java.awt.BorderLayout
(répartition en 5 zones: haut, bas, gauche, droite, centre)java.awt.FlowLayout
(place les composants de gauche à droite, ligne par ligne)java.awt.GridLayout
(répartition en un tableau 2d régulier)javax.swing.BoxLayout
(place les composants les uns au-dessous des autres)…
Consultez la page des layout managers pour avoir un aperçu de ces modèles.
Utiliser un Layout Manager¶
Le modèle par défaut est FlowLayout
. Mais il est très simple d’en utiliser un autre
en le passant en paramètre, soit au constructeur de JPanel
, soit à la méthode
setLayout()
.
JPanel contentPane = new JPanel(new BorderLayout());
//or:
//JPanel contentPane = new JPanel();
//contentPane.setLayout( new BorderLayout() );
contentPane.add(someComponent, BorderLayout.CENTER);
contentPane.add(anotherComponent, BorderLayout.PAGE_END);
topLevelContainer.setContentPane(contentPane);
Ex.1. Détails¶
Le panneau d’affichage principal utilise un
BorderLayout
.En haut (PAGE_START), se trouve un
JTextField
.En bas (PAGE_END), se trouve un
JLabel
.A gauche (LINE_START), se trouve un
JButton
pour remettre la calculatrice à zéro.A droite (LINE_END), se trouve un
JButton
pour afficher le résultat.Au centre (CENTER), se trouve un panneau secondaire utilisant un
GridLayout
contenant desJButton
pour les chiffres et les opérations.Pensez à garder des références vers tous les composants.
Gestion des evénements¶
Fonctionnement général¶
A un composant graphique (
JButton
), on attache un objet capable d’écouter les événements (ActionListener
).Quand l’utilisateur réalise une action sur le composant (clic), un événement est généré (
ActionEvent
).La machine virtuelle reçoit tous les événements, mais seul les événements écoutés déclenchent une réaction (dont le code se trouve dans la méthode
actionPerformed()
de l’interfaceActionListener
).
Exemple de Listener¶
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
/*
* Button listener
*/
public class ButtonBeeper implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//print 'beep' to the standard output
//when an action event is received
System.out.println("beep");
}
}
Exemple d’application¶
import javax.swing.*;
public class BeeperApp implements Runnable {
@Override
public void run() {
//Create the window.
JFrame f = new JFrame("Beeper");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Add a button with an action listener
JButton b = new JButton("Click me");
b.addActionListener( new ButtonBeeper() );
f.getContentPane().add(b);
//Display the window.
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
//Run the application at the correct time in the event queue.
SwingUtilities.invokeLater( new BeeperApp() );
}
}
Quelques types d’évenement¶
ActionEvent
/ActionListener
(déclenchés parJButton
)ItemEvent
/ItemListener
(déclenchés parJCheckBox
)MouseEvent
/MouseListener
(déclenchés par la souris sur un composant)KeyEvent
/KeyListener
(touche clavier)…
Consultez l’API standard
pour la liste des événements disponibles dans java.awt.event
,
le tutoriel Evénements,
ainsi que les How To
consacrés aux composants pour savoir quel type d’événement ils déclenchent.
ActionEvent / ActionListener¶
Le couple ActionEvent
/ ActionListener
est le plus commun.
ActionEvent
est la classe des événements déclenchés par une action bien définie sur un composant. Elle possède notamment la méthodegetSource()
pour obtenir le composant ayant déclenché l’événement.Un objet issu d’une classe qui implémente l’interface
ActionListener
, doté de la méthodeactionPerformed()
, est attaché à un tel composant par la méthodeaddActionListener()
.
Ex.2. Calculatrice/Evenements (30 min)¶
Faites en sorte que votre calculatrice affiche le résultat d’une suite d’additions ou de soustractions données par des actions sur les différents boutons.
Téléchargez la classe
Processeur
qui se charge des calculs.Ecrivez un listener par type de bouton (un pour les chiffres, le plus, le moins, le
=
et leC
); chacun connaissant une instance deProcesseur
(calcul) et une instance deJTextField
(affichage).Astuce: les composants
JButton
etJTextField
possèdent tous les deux les méthodesgetText()
etsetText()
pour respectivement lire et écrire le texte attaché au composant.
Ce qu’il faut retenir¶
Une fenêtre (
JFrame
) est composée d’une hiérarchie de conteneurs (JPanel
), contenant eux-même des composants graphiques élémentaires (JLabel
,JButton
, etc.).Des modèles (layout managers) permettent de disposer les composants sur un panneau d’affichage.
Les composants graphiques peuvent s’abonner à des listeners (
ActionListener
), écoutant des événements particuliers. Lorsqu’un énénement écouté (ActionEvent
) est déclenché, le code associé au listeners est exécutée par le Event-Dispatching Thread.
Ce que vous devez savoir faire¶
Réaliser une application graphique qui réagit aux actions de l’utilisateur.