Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 1
Les GUIs en Java
Nicolas Nobelis IUT R&T
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 2
Définition
GUI = Graphical User Interface.
Ces interfaces permettent à l'utilisateur de dialoguer de manière conviviale avec le logiciel.
Le développement des GUI s'effectue, mis à part quelques cas précis, APRÈS le développement du logiciel proprement dit.
Les GUIs en Java
Il existe plusieurs toolkits graphiques :
AWT (Abstract Window Toolkit) : le tout premier proposé par Sun (développé en 30 jours). Implémentation via des composants natifs. Peu de composants disponibles.
Swing : librairie pure Java, construite au dessus d'un sous- ensemble d'AWT. De nombreux composants disponibles (arbre, menus, sélecteur). Entièrement portable mais plutôt lent.
SWT (Standard Widget Toolkit) : librairie nouvelle génération soutenue par le projet Eclipse. Implémentation native et nombreux composants. Très rapide. Portabilité limitée.
Swing
AWT et Swing sont étroitement liés :
La majeure partie des classes AWT existe dans Swing (e.g.
Button et JButton).
La programmation Swing nécessite de temps en temps l'usage de classes AWT (en particulier pour les événements et les polices) : privilégier, quand c'est possible, l'utilisation des classes Swing.
les classes s'obtiennent en important les paquetages suivants :
java.awt.*;
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 5
Les différents composants Swing : JFrame
Les JFrame : une fenêtre.
Méthodes intéressantes :
setTitle(String) pour mettre le titre de la fenêtre.
setSize(int longueur, int hauteur).
setLocation(int x, int y) pour déplacer la fenêtre.
dispose() pour fermer la fenêtre.
pack() ajuste chaque composant à sa taille optimale et retaille la fenêtre.
setDefaultCloseOperation(int constante) spécifie l'action à effectuer quand on clique sur la croix en haut à droite.
Par ex. : JFrame.DISPOSE_ON_CLOSE.
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 6
Les différents composants Swing (2) : JLabel
ImageIcon ii = new ImageIcon("icon.png");
JLabel jl = new JLabel("text + icône", ii, JLabel.CENTER);
Méthodes intéressantes :
setEnabled(boolean) pour activer/désactiver une zone de texte.
setHorizontalAlignement(cste) pour contrôler l'alignement de texte. cste = JLabel.LEFT, JLabel.CENTER, etc...
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 7
Les différents composants Swing (3) : JButton
Méthodes intéressantes :
setEnabled(booléen) pour activer ou désactiver un bouton.
setText(String) pour changer le texte du bouton.
setMnemonic(char) pour enregistrer quel caractère est accessible par mnémonique (i.e. quand on presse alt et le mnémonique, le bouton est activé).
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 8
Les différents composants Swing (4) : JOptionPane
JOptionPane.showMessageDialog(null, "Faille du noyau...", "Alerte ", JOptionPane.ERROR_MESSAGE);
int retour = JOptionPane.showConfirmDialog(null, "Voulez vous continuer ?",
"Question",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
System.out.println("Est ce que oui a été choisit ? " + (retour == JOptionPane.YES_OPTION));
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 9
Les différents composants Swing (5)
Voici une liste non exhaustive d'autres composants (consulter la Javadoc pour les utiliser) :
JPanel : un conteneur vide.
JComboBox : liste à plusieurs valeurs souvent utilisé dans les formulaires web.
JTextField : une ligne de texte.
JTextArea : une zone de texte.
JCheckBox : petite boite à cocher.
JRadioButton : un groupe de petits boutons ronds à choix unique.
JList : une liste.
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 10
Les différents composants Swing (6)
JProgressBar : une barre de remplissage.
JMenu et JMenuItem : un menu et ses éléments.
JPopMenu : un menu flottant (souvent utilisé dans les clics droits).
JToolBar : une barre d'outils.
JToolTip : une bulle d'aide.
JTree : une structure arborescente.
JFileChooser : un sélecteur de fichier.
JColorChooser : un sélecteur de couleur.
Architecture
Tous les composants Swing héritent de la super-classe JComponent.
Comme JComponent hérite de java.awt.Container, tous les composants Swing peuvent contenir d'autres composants.
Les composants s'ajoutent par :
Container.add(<JComponent>) placement avec une contrainte par défaut.
Container.add(<JComponent>, <Object>) placement avec une contrainte spécifiée.
Un exemple
Cette fenêtre peut s'obtenir de deux manières : par composition
et par spécialisation.
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 13
Un exemple : composition
import javax.swing.*;
public class GUITest {
public static void main (String[] args) {
JFrame j = new JFrame("Le titre de la fenetre");
JLabel texte = new JLabel("Hello World");
JButton bu = new JButton("Yes, Hello !");
j.add(texte, java.awt.BorderLayout.NORTH);
j.add(bu, java.awt.BorderLayout.SOUTH);
j.setSize(400, 300);
j.setVisible(true);
}
}//END OF CLASS
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 14
Un exemple : spécialisation
import javax.swing.*;
public class GUITest2 extends JFrame {
public GUITest2 (int largeur, int hauteur) { super("Le titre de la fenetre");
JLabel texte = new JLabel("Hello World");
JButton bu = new JButton("Yes, Hello !");
add(texte, java.awt.BorderLayout.NORTH);
add(bu, java.awt.BorderLayout.SOUTH);
setSize(largeur, hauteur);
setVisible(true);
}
public static void main (String[] args) { GUITest2 f = new GUITest2(400, 300);
}
}//END OF CLASS
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 15
Utilisation
Que faut-t-il utiliser ? La spécialisation ou la composition ?
dans une utilisation normale, la composition est plus efficace car elle vous permet de minimiser le nombre de lignes de code à écrire.
dans le cas où vous devez utiliser plusieurs composants ad-hoc, il vaut mieux choisir la spécialisation.
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 16
Mise en page
Comment s'effectue la mise en page des composants dans le conteneur ?
Tous les conteneurs disposent d'une méthode setLayout qui permet de spécifier le gestionnaire de mise en page à utiliser.
Lors de l'ajout d'un nouveau composant dans un autre
(via la méthode add), on peut préciser un paramètre de
contrainte.
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 17
Les différents gestionnaires : BorderLayout (1)
import javax.swing.*;
import java.awt.BorderLayout;
public class GUITest3 {
public static void main (String[] args) { JFrame j = new JFrame();
j.setLayout(new BorderLayout());
j.add(new JButton("Nord"), BorderLayout.NORTH);
j.add(new JButton("Sud"), BorderLayout.SOUTH);
...
Ce layout est celui par défaut dans les JFrame.
La zone est divisée en 5 parties
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 18 import javax.swing.*;
import java.awt.GridLayout;
public class GUITest4 {
public static void main (String[] args) { JFrame j = new JFrame();
j.setLayout(new GridLayout(3, 2));
for (int i = 1; i < 7 ; i++) {
j.add(new JButton("But " + i));
} ...
Ce layout divise la zone sous la forme d'une grille.
Le constructeur prend le nombre de lignes et le nombre de colonnes.
Les différents gestionnaires : GridLayout (2)
import javax.swing.*;
import java.awt.FlowLayout;
public class GUITest5 {
public static void main (String[] args) { JFrame j = new JFrame();
j.setLayout(new FlowLayout(FlowLayout.CENTER));
for (int i = 1; i < 7 ; i++) {
j.add(new JButton("But " + i));
Ce layout est celui par défaut dans les JPanel.
Ce layout remplit la zone au fur et à mesure, en allant à la ligne quand il n'y a plus de place.
Les différents gestionnaires : FlowLayout (3)
Il existe d'autres LayoutManager :
BoxLayout : la zone est divisée en cellules de même hauteur mais de longueurs différentes.
GridBagLayout : la zone est divisée en cellules de taille variable. Il est possible de paramétrer la manière dont l'espace supplémentaire est alloué à chaque cellule. Complexe !
Les différents
gestionnaires (4)
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 21
Les bordures
Les JComponents peuvent se voir attribuer une bordure par la méthode setBorder(Border)
Pour obtenir une bordure, utiliser les méthodes statiques de la classe BorderFactory (createEtchedBorder, ...)
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 22
Les événements
Programmation par événement :
1) Un écouteur s'abonne à une source.
2) La source déclenche l'événement.
3) La source le passe aux abonnés.
4) Les abonnés réagissent.
Les composants sont des sources.
Événements déclenchés par une action utilisateur .
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 23
Les événements (2) : exemple
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 24
Les événements (3) : exemple
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUITest7 extends JFrame {
JLabel lb; // variable globale sinon le listener ne peut y accéder public GUITest7 () {
super("Le titre de la fenetre");
setLayout(new FlowLayout(FlowLayout.CENTER));
JButton hb = new JButton("Push for hello");
lb = new JLabel("Hello Monde");
hb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
lb.setText("OUCH !");
} });
add(hb);
add(lb);
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 25
Les événements (4)
Voici les principales classes d'écouteur :
Les plus utilisées sont :
ActionListener.
ItemListener.
Il existe aussi des listeners spécifiques :
MouseListener, MouseAdapter (pour la souris).
KeyListener, KeyAdapter (pour les événements clavier).
WindowListener, WindowAdapter (pour les fenêtres).
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 26
Les événements (5)
Si vous implémentez un <XXX>Listener, vous vous engagez à écrire le code de toutes ses méthodes.
Dans certains cas (e.g. MouseListener), il y a beaucoup de méthodes à redéfinir. Dans ces cas là, utilisez un
<XXX>Adapter : vous ne redéfinissez que le corps des méthodes qui vous intéresse.
Le dessin
Le dessin dans Swing est fondé sur :
les classes :
public abstract class java.awt.Graphics
public abstract class java.awt.Graphics2
les méthodes de javax.swing.JComponent :
paintComponent(Graphics)
paint(Graphics)
repaint()
Le dessin (2)
Méthodes de Graphics :
drawArc
drawImage
drawLine
drawOval
drawPolygon
drawRect
drawString
getColor
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 29
Le dessin (3) : exemple
Nous allons créer un composant spécifique : un JPanel qui contient un dessin.
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 30
Le dessin (4) : exemple
public class GUITest8 extends JPanel { public GUITest8 () { }
// pour éviter que pack diminue la zone d'affichage en dessous d'une certaine zone public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
// méthode appelée quand le panneau doit être redessiné public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawString("Hello World", 10, 10);
g.setColor(Color.RED);
g.fillOval(100, 50, 30, 70);
g.setColor(Color.BLUE);
g.fill3DRect(300, 80, 50, 40, true) ; }
}
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 31
Le Look And Feel
Par défaut, toutes les fenêtres de Swing ont le même aspect, quelque soit la plate-forme. Il est néanmoins de possible de changer d'aspect.
Ces aspects s'appellent des Look And Feel (LAF).
On peut, sur une plate forme donnée, choisir
le LAF par défaut (CrossPlatformLookAndFeel)
le LAF du système courant (SystemLookAndFeel)
le LAF d'un autre système, si les licences le permettent (e.g. le LAF Windows n'est pas disponible sur Linux).
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 32
Le Look And Feel (2)
LAF par défaut (Métal) LAF Unix (Motif)
LAF Linux (Gtk) LAF Windows
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 33
Le Look And Feel (3)
JFrame f = new JFrame();
// récupère la liste des LAF
UIManager.LookAndFeelInfo[] leslafs = UIManager.getInstalledLookAndFeels();
// affiche cette liste
for (int i = 0; i < leslafs.length ; i++) {
System.out.println(leslafs[i].getClassName());
} try {
// met le troisième LAF
UIManager.setLookAndFeel(leslafs[2].getClassName());
}
catch (ClassNotFoundException x) { x.printStackTrace(); } catch (InstantiationException x1) { x1.printStackTrace(); } catch (IllegalAccessException x2) { x2.printStackTrace(); }
catch (UnsupportedLookAndFeelException x3) { x3.printStackTrace(); } SwingUtilities.updateComponentTreeUI(f);
Les GUI en Java. (C) 2005-2006 Nicolas Nobelis 34
Astuce : comment centrer une fenêtre ?
La méthode statique suivante centre une fenêtre. Il faut l'appeler juste après les pack et setSize et juste avant le setVisible(true) :
public static void centerJFrame(JFrame j) { int h = j.getHeight();
int l = j.getWidth();
java.awt.Dimension d =
java.awt.Toolkit.getDefaultToolkit().getScreenSize();
j.setLocation(d.width/2-l/2, d.height/2-h/2);
}
Références
Cette présentation est fondée sur les travaux suivants :
cours d'interface graphique de Peter Sander : http://www.essi.fr/~sander/courses/prog101/GUI/
cours d'interface graphique de Yannis Bres :
http://www.yannis.bres.name/Teaching/ESSI/2/AWT-Swing/
cours d'interface graphique de Jean Berstel : http://www- igm.univ-mlv.fr/%7Eberstel/Cours/liste.html
Pour aller plus loin sur les interfaces graphiques, je vous recommande l'excellent livre (un peu vieux) :