Interface graphique
La quasi-totalité des programmes informatiquesnécessitent l’interaction avec l’utilisateur (entrer de
données, affichage de résultats, …etc ).Elle peut s’effectuer avecune interface utilisateur en
modetexte (ou console) (ligne de commande) ou en mode graphique.
Une interface graphique ou GUI (Graphical User Interface) est formée d’une ouplusieurs fenêtres qui
contiennent diverscomposants graphiques (widgets) tels que : boutons, case à cocher, listes
déroulantes, menus, champ texte etc.
L’utilisateur peut interagir à tout moment avecplusieurs objets graphiques : cliquer sur unbouton,
faire un choix dans une liste déroulanteou dans un menu, remplir un champ texte, etc…
Ces actions peuvent modifier totalement lecheminement du programme, sans que l’ordred’exécution
des instructions ne puisse être prévuà l’écriture du code.
1- Les API (bibliothèques) de base d’une interface graphique
On java on peut gérer les interfaces graphiques à travers deux types de bibliothèques de base:
- awt (Abstract WindowToolkit, JDK 1.1) : c’est la première API proposer pour développer des
interfaces graphiques. Elle fait appel aux composants graphiques du système d’exploitation.
- swing : proposée de puis le JDK 1.2. Swing est construit au-dessus de AWT :
- même gestion des événements
- les classes de Swing héritent des classes de AWT
Mais :
- Ses composants écrit complètement avec java et sont indépendant de l’OS (système
d’exploitation).
- Tous les composants de AWT ont leuréquivalent dans Swing mais qui sont plus joli avec plus
de fonctionnalités.
- Swing offre de nombreux composants quin’existent pas dans AWT.
-
- Actuellement, SWING est souvent choisi car il est fourni en standard dans le SDK
●Il est préférable de n'en u liser qu'un seul à la fois, tant les risques d'erreurs peuvent survenir
entre les deux API graphiques (leurs syntaxes sont très proches).
Outre ces deux API d’autre API sont fournis tel que :
- SWT du projet Eclipse.
- et plus récemment JFace, GWT.
2- Les composants de base d’une GUI à base de Swing
On peut distinguer :
1- Des composants qui sont destinés spécifiquement à recevoir d’autres éléments graphiques
qui sont :
– les containers « top-level»dit aussi lourds : JFrame, JApplet, JDialog, JWindow
– les containers « intermédiaires » légers JPanel, JScrollPane, JSplitPane, JTabbedPane, Box
2- Des composants légers (widgets) : qui sont des composants simples dont un conteneur peut
les contenir tel que : des boutons (JButton), des zone de texte (JTextField)…etc
La plupart des widgets de Swing sont des instances de sous-classes de la classe JComponent.
3- Ajouter des composants dans une fenêtre
Avant le JDK 5, les containers « top-level » (topLevel est un container lourd ; JFrame par exemple) ne
pouvaient contenir directement d’autres composants. Ils sont associés à un autre container, le «
content pane » dans lequel on ajoutait les composants
• On obtient ce content pane par :
- Container contentPane = topLevel.getContentPane();
- Ex : ContainercontentPaneJFrame.getContentPane();
- On peut désormais ajouter directement les composants dans un composant « top-level ».
- On peut instancier directement un conteneur (dans un programme) mais Le plus souvent est
de définir une classe qui hérite de ce dernier en déclarent ses composant (JButtons, JLabel… )
comme attributs et en les ajoutant (les instancier et les ajouter ) dans son constructeur.
Ensuite on peut instancier cette nouvelle classe dans un programme.
Exemple :
importjava.awt.*;
importjavax.swing.*;
publicclassMaFenetreextendsJFrame {
privateJLabelll;
privateJButton b1;
publicMaFenetre(){
ll = newJLabel("Bonjour");
b1 = newJButton("Cliquez moi !");
setTitle("fenetre principale");// pour changer le titre
add(l1, BorderLayout.NORTH); // l’ajout du label l1 à la fenêtre
add(b1, BorderLayout.SOUTH); // l’ajout du bouton b1 à la fenêtre
pack(); // calculer la taille de la fenêtre automatiquement
//ou bien utiliser setSize() ou setBound()
setVisible(true);// pour afficher la fenêtre
}}
publicclassProg {
publicstaticvoid main(String[] args) {
// TODO Auto-generated method stub
MaFenetref = newMaFenetre();
}
}
Voici quelles que méthodes qui permettent de manipuler une fenêtre
- setTitle(String title) : Cette méthode modifie le titre de la fenêtre. Ce titre va apparaître dans
la barre de titreet également dans la barre des tâches.
- add() : cette méthode permet d’ajouter (positionner) les composants crées à un conteneur.
elle peut avoir éventuellement des paramètres afin de spécifier leur positionnement.
- setSize(intwidth, intheight) : Cette méthode permet de modifier la taille de la fenêtre.
- setLocationRelativeTo(Component c) : Cette méthode permet de positionner la fenêtre par
rapport à uncomposant. En indiquant un composant null, elle va se placer automatiquement
au milieu de l'écran.
- setResizable(booleanresizable) : Cette méthode permet ou non le redimensionnement de la
fenêtre.
- setDefaultCloseOperation(intoperation) : Cette méthode permet de configurer l'action qui va
être exécutée lors de la fermeture de la fenêtre. On peut choisir de faire quitter le
programme, de fermer la fenêtre ou de la rendre invisible.
- Pack() pour calculer et donner la taille préférée de la fenêtre avant qu’elle soit affichée.
4- Gestionnaires de mise en place
L’utilisateur peut changer la taille d’une fenêtre ; les composants de la fenêtre doivent alors être
repositionnés. Les fenêtres (plus généralement les containers) utilisent des gestionnaires de mise en
place (layout manager) pour repositionner leurs composants. Il existe plusieurs types de layout
managers avec des algorithmes de placement différents.
- Quand on ajoute un composant dans un container on ne donne pas la position exacte du
composant On donne plutôt des indications de positionnement au gestionnaire de mise en
place soit d’une façon explicites (BorderLayout.NORTH) ou implicites (ordre d’ajout dans le
container).
- Un layoutmanagerplace les composants suivant :
o l’algorithme de placement qui lui est propre
o les indications de positionnement des composants
o la taille du container
o les tailles préférées des composants
- Les principaux gestionnaires de présentation de AWT :
o BorderLayout
o BoxLayout
o CardLayout
o FlowLayout
o GridBagLayout
o GridLayout
- Tous les containers ont un gestionnaire de placement par défaut On peut changer ce
gestionnaire de placement d’un Container par la méthode setLayout(LayoutManager) de la
classe Containeren passent comme paramètre un objet d’une des classe qui implémente
l’interface LayoutManager par exemple un nouvel objet de la classe GridLayout.
ex :setLayout(new GridLayout) ;
- Le gestionnaire de mise en place par défaut des fenêtres JFrameest du type BorderLayout
- Le gestionnaire de mise en place par défaut des panneaux (Jpanel…) est du type FlowLayout
BorderLayout :
Affiche au maximum 5 composants (aux 4 points cardinaux East, Ouest, Nord, sud et au centre)
il faut indiquer à la méthode add() outre que le composant à ajouter l’emplacement d’ajout en
indiquant un des constants de la classe BorderLayout qui exprime l’emplacement de
positionnement qui sont : NORTH, SOUTH, WEST, EAST, CENTER).
Remarque :
* rappelant que :
- Par convention le nom d’un constant(un attribut déclarer avec les modificateur static et final)
(un variable de classe ayant une valeur constante) est écrit en majuscule.
- pour accéder à un constanton utilise le nom de la classe suivi par le nom du constant par
exemple BorderLayout.NORTH.
-
Exemple :
package gestionnaire;
import java.awt.BorderLayout;
importjavax.swing.*;
public class Fenêtre extends JFrame {
privateJButtonnord = new JButton("Nord");
privateJButtonouest = new JButton("Ouest");
privateJButtonsud = new JButton("Sud");
privateJButtoncentre = new JButton("Centre");
privateJButton est = new JButton("Est");
publicFenêtre() {
setTitle("Unefenêtre");
setSize(300, 250);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(nord, BorderLayout.NORTH);
add(ouest, BorderLayout.WEST);
add(sud, BorderLayout.SOUTH);
add(centre, BorderLayout.CENTER);
add(est, BorderLayout.EAST);
setVisible(true);
}
}
publicclassProg {
public static void main(String[] args) {
new Fenêtre();
}
}
FlowLayout
Ce gestionnaire dispose les composants les uns à la suite des autres, sur une même ligne. Lorsqu'une
ligne ne possède plus suffisamment de place, l'affichage se poursuit sur la ligne suivante. Chaque
composant conserve sa taille préférée. Par exemple, il essaie de placer les objets sous leur taille
préférée de gauche à droite et de haut en bas.
Exemple :
importjavax.swing.*;
publicclassFenêtreextendsJFrame {
privateJButton nord = newJButton("Nord");
privateJButton ouest = newJButton("Ouest");
privateJButton sud = newJButton("Sud");
privateJButton centre = newJButton("Centre");
privateJButton est = newJButton("Est");
privateJPanelpanneau = newJPanel();
publicFenêtre() {
setTitle("Unefenêtre");
setSize(300, 250);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panneau.add(nord);
panneau.add(ouest);
panneau.add(sud);
panneau.add(centre);
panneau.add(est);
add(panneau);
setVisible(true);
}
}
publicclassProg {
publicstaticvoidmain(String[] args) {
newFenêtre();
}}
GridLayout
Ce gestionnaire permet de disposer les composants suivant une grille régulière, chaque composant
ayant alors la même taille. Il est tout à fait possible de changer de gestionnaire de placement par
défaut et d'imposer celui qui vous convient. Par exemple, nous pouvons choisir le gestionnaire
GridLayout en lieu et place du gestionnaire BorderLayout prévu par défaut pour un cadre de fenêtre :
Exemple :
package gestionnaire;
import java.awt.*;
importjavax.swing.*;
public class Fenêtre extends JFrame {
privateJButtonnord = new
JButton("Nord");
privateJButtonouest = new
JButton("Ouest");
privateJButtonsud = new
JButton("Sud");
privateJButtoncentre = new
JButton("Centre");
privateJButton est = new
JButton("Est");
publicFenêtre() {
setTitle("Unefenêtre");
setSize(300, 250);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new GridLayout(3, 2));
add(nord);
add(ouest);
add(sud);
add(centre);
add(est);
setVisible(true);
}
public static void main(String[] args) {
new Fenêtre();
}}
5- Gestionnaires des événements
Événements
L’utilisateur d’un programme interagit avec les composants Swing à l’écran grâce aux périphériques,
comme la souris ou le clavier. Ces interactions sont regroupées par le système sous forme
d’événements (events en anglais) de deux catégories :
• Les événements primaires, provoqués par un périphérique de l’ordinateur : événements souris
(enfoncement /relâchement d’un bouton de la souris, déplacement du pointeur de la souris) et
événements clavier (enfoncement /relâchement d’une touche du clavier).
• Les événements composites, qui sont créés par le système de gestion événementiel suite à un
enchaînement d’événements primaires sur un composant (double-clic, choix d’un menu...) ou sur un
conteneur (redimensionnement, fermeture d’une fenêtre...).
Ecouteurs (listener )des événements
A partir de la version 1.1 du jdk les événements sont gérés par AWT selon le principe suivant :
Des objets sources d'événements (bouton, barre de défilement, ...) transmettent les événements à
des objets écouteurs d'événements.
Un objet écouteur d'événements est une instance d'une classe qui implémente une interface spéciale
appelée interface écouteur.
Si un composant graphique peut engendrer des événements de type xxxEvent, l’interface écouteur
s'appellera xxxListener. Par exemple :
- l’interface ActionListener qui gère les événements de type « action »(clik ou appuyer sur
entrer). Doté par une seul méthode : actionPerformed()
- L’interface MouseListener qui gère les événements de la sourie (contient 5 méthodes).
En général, l'écouteur d'événement d'un composant d'interface, est souvent le conteneur de ce
composant.
Un composant source des événements peut être lié aux plusieurs objets écouteur d’événement
(chaque objet désigne une catégorie des événements).
Pour lier un composant source d’événement (bouton, case à cocher…) avec son objet écouteur
d’événement de type xxx on utilise la méthode addxxxListener () qui nécessite comme paramètre un
objet écouteur d’événement.
- Si le conteneur (une fenêtre, un panel…) est lui même qui implémente l’interface du listener ;
on passe this comme paramètre à la méthode addxxxListener () puisqu’elle désigne l’objet
(l’instance) courant (il réfère ce conteneur).
Le même objet écouteur peut être associé aux plusieurs composant source d’un événement.
La méthode getSource() (héritée de EventObject superclasse des classes événements) permet de
déterminer quel est l'objet source de l'événement, ou la méthode getActionCommand() renvoie la
chaine de commande associée à l'action.
Les interfaces écouteurs d'événements :
Une classe qui désire recevoir des événements doit implémenter une interface écouteur. Elle se
recense auprès de la source d'événement, puis elle reçoit les événements souhaités et les traite grâce
aux méthodes de l'interface écouteur.
Il y a onze interfaces écouteurs dans le package java.awt.event :
ActionListener // clic, touche entrée, sélection d'un élément
Méthode : actionPerformed(actionEvent e)
Evénements générés par : AbstractButton, Button, JComboBox, JFileChooser, JTextField, List,
MenuItem, TextField avec la méthode addActionListener
AdjustementListener // déplacement du curseur d'une barre de défilement
Méthode : adjustmentValueChanged(AdjustmentEvent e)
Evénements générés par : Scrollbar, JScrollbaravec la méthode addAdjustementListener
TextListener // modification du texte d'un composant texte
Méthodes : textValueChanged(TextEvent e)
Evénements générés par : TextComponentavec la méthode addTextListener
ComponentListener // déplacement, affichage, masquage ou modification de taille de
composants
Méthodes : componentHidden(ComponentEvent e)
componentMoved(ComponentEvent e)
componentResized(ComponentEvent e)
componentShown(ComponentEvent e)
Evénements générés par : Component avec la méthode addComponentListener
ContainerListener // ajout ou suppression d'un composant dans un conteneur
Méthodes : componentAdded(ContainerEvent e)
componentRemoved(ContainerEvent e)
Evénements générés par : Container avec la méthode addContainerListener
FocusListener // obtention ou perte du focus par un composant
Méthodes : focusGained(FocusEvent e)
focusLost(FocusEvent e)
Evénements générés par : Component avec la méthode addFocusListener
ItemListener // sélection dans une liste ou dans un groupe de cases à cocher
Méthodes : itemStateChanged(ItemEvent e)
Evénements générés par : AbstractButton, Checkbox, CheckboxMenuItem, Choice,
JComboBox, List
KeyListener // action sur une touche du clavier (pressée ou relachée)
Méthodes : keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
keyTyped(KeyEvent e)
Evénements générés par : Component avec la méthode addKeyListener
MouseListener // clic sur bouton, déplacement du pointeur
Méthodes : mouseClicked(MouseEvent e)
mouseEntered(MouseEvent e)
mouseExited(MouseEvent e)
mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)
Evénements générés par : Component avec la méthode addMouseListener
MouseMotionListener // événements de glisser-déplacé
Méthodes : mouseDragged(MouseEvent e)
mouseMoved(MouseEvent e)
Evénements générés par : Component avec la méthode addMouseMotionListener
WindowListener // fenêtre activée, désactivée, réduite, fermée, ...
Méthodes : windowActivated(WindowEvent e)
windowClosed(WindowEvent e)
windowClosing(WindowEvent e)
windowDeactivated(WindowEvent e)
windowDeiconified(WindowEvent e)
windowIconified(WindowEvent e)
windowOpened(WindowEvent e)
Evénementsgénérés par : Window avec la méthodeaddWindowListener
Les interfaces écouteurs du package java.swing.event :
AncestorListener
CaretListener
Méthode : caretUpdate(CaretEvent e)
Evénements générés par : JTextComponent avec la méthode addCaretListener
CellEditorListener
ChangeListener
Méthode : stateChanged(ChangeEvent e)
Evénements générés par : AbstractButton, JProgressBar, JViewport
avec la méthode addChangeListener
DocumentListener
HyperlinkListener
InternalFrameListener
ListDataListener
ListSelectionListener
Méthode : valueChanged(ListSelectionEvent e)
Evénements générés par : JListavec la méthode addListSelectionListener
MenuDragMouseListener
Méthodes: menuDragMouseDragged(MenuDragMouseEvent e)
menuDragMouseEntered(MenuDragMouseEvent e)
menuDragMouseExited(MenuDragMouseEvent e)
menuDragMouseReleased(MenuDragMouseEvent e)
Evénements générés par : JMenuItemavec la méthode addMenuDragMouseListener
MenuKeyListener
Méthodes : menuKeyPressed(MenuKeyEvent e)
menuKeyReleased(MenuKeyEvent e)
menuKeyTyped(MenuKeyEvent e)
Evénements générés par : JMenuItem avec la méthode addMenuKeyListener
MenuListener
Méthodes : menuCanceled(MenuEvent e)
menuDeselected(MenuEvent e)
menuSelected(MenuEvent e)
Evénements générés par : JMenuavec la méthode addMenuListener
MouseInputListener
PopupMenuListener
Méthodes : popupMenuCanceled(PopupMenuEvent e)
popupMenuWillBecomeInvisible(PopupMenuEvent e)
popupMenuWillBecomeVisible(PopupMenuEvent e)
Evénements générés par : JPopupMenuavec la méthode addPopupMenuListener
TableColumnModelListener
TableModelListener
TreeExpansionListener
TreeModelListener
TreeSelectionListener
TreeWillExpandListener
UndoableEditListener
Remarque :Certaines interfaces écouteurs sont accompagnées d'adaptateurs qui implémentent
toutes les méthodes de l'interface afin qu'elles n'accomplissent aucune action. En effet, toutes les
méthodes d'une interface ne sont pas forcément utilisées, l'adaptateur évite d'avoir à les citer dans le
programme. Ces adaptateurs sont les suivants : ComponentAdapter, ContainerAdapter,
FocusAdapter, KeyAdapter, MouseAdapter, MouseMotionAdapter ,WindowAdapter
Exemple :
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
importjavax.swing.*;
publicclassFenetreButtonextendsJFrameimplementsActionListener{
JTextFieldt1 = newJTextField(20);
JButtonb1 = newJButton("bonjour");
JButtonb2 = newJButton("bonsoir");
JButtonb3 = newJButton("effacer");
publicFenetreButton() {
setLayout(newFlowLayout());
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
add(t1);
add(b1);
add(b2);
add(b3);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true); }
@Override
publicvoidactionPerformed(ActionEvente) {
if(e.getSource()== b1)
t1.setText("bonjour");
if(e.getSource()== b2)
t1.setText("bonsoir");
if(e.getSource()== b3)
t1.setText("");
}}
publicclasstestEvent {
publicstaticvoid main(String[] args) {
FenetreButtonf = newFenetreButton();
}
}
Utilisation d’une classe interne anonyme
Une autre manière de gestion des événements est d’utiliser les classes internes anonymes sans
implémenter explicitement l’interface d’un écouteur.
- Les méthodes d’une classe anonyme peuvent utiliser les attributs et les méthodes d’instance
de la classe englobant la classe anonyme.
- Les méthodes d’une classe anonyme peuvent utiliser les variables locales etles paramètres de
la méthode dans laquelle la classe anonyme est définies’ils sont déclarés final.
• L’instruction de création d’une classe anonyme de type listener permetd’associer à un composant
Swing son listener juste après l’instanciation ducomposant, regroupant ainsi la création et le
comportement du composant.
• La classe étant anonyme, vous n’avez pas à lui trouver d’identificateur.
•les IDE capables de créer de façon interactive une IHM Swing (plugin d’interface graphique)se base
essentiellement sur cette technique il nous reste à implémenter le traitement de l’événement.
Exemple
importjava.awt.FlowLayout;
importjava.awt.event.*;
importjavax.swing.*;
publicclassFenetreAnonymeextendsJFrame {
JTextFieldt1 = newJTextField(20);
JButtonb1 = newJButton("bonjour");
JButtonb2 = newJButton("bonsoir");
JButtonb3 = newJButton("effacer");
publicFenetreAnonyme() {
setLayout(newFlowLayout());
b1.addActionListener(newActionListener() {
publicvoidactionPerformed(ActionEvente) {
t1.setText("bonjour");
}
});
b2.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente) {
t1.setText("bonsoir");
}
}
);
b3.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente) {
t1.setText("");
}
}
);
t1.addMouseListener(newMouseListener() {
@Override
publicvoidmouseReleased(MouseEvente) {
}
@Override
publicvoidmousePressed(MouseEvente) {
@Override
publicvoidmouseExited(MouseEvente) {
t1.setText("");
}
@Override
publicvoidmouseEntered(MouseEvente) {
t1.setText("la sourisest sur la zone de text");
}
@Override
publicvoidmouseClicked(MouseEvente) {
}
});
add(t1);
add(b1);
add(b2);
add(b3);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}}