Vous êtes sur la page 1sur 97

Interfaces

graphiques
Pratique de la programmation oriente-objet
Michel Schinz 20150518
AWT, Swing, Java FX
La bibliothque Java contient trois ensembles de classes
permettant la cration d'interfaces graphiques. Dans l'ordre
chronologique de leur apparition, ce sont :
1. AWT (Abstract Window Toolkit), tomb en dsutude
mais servant de base Swing,
2. Swing, utilis pour la majorit des applications
existantes mais en cours de remplacement par Java FX,
3. Java FX.
Cette leon dcrit Swing, mais la plupart des concepts se
retrouvent dans Java FX et dans d'autres bibliothques
similaires pour d'autres langages.
Swing

Swing est compos d'un trs grand nombre de classes


appartenant toutes (ou presque) au paquetage
javax.swing et ses sous-paquetages.
Etant donn que Swing se base sur AWT, les classes du
paquetage java.awt et ses sous-paquetages sont parfois
ncessaires.
Composants
Composants

Une interface graphique Swing se construit en combinant


un certain nombre de composants (components),imbriqus
les uns dans les autres.
Par exemple, les fentres, les menus, les boutons, les zones
de texte, etc. sont des composants.
Les classes reprsentant ces composants ont toutes un nom
commenant par J, et quelques exceptions prs
hritent de la classe abstraite javax.swing.JComponent.
Types de composants

Il existe deux types de composants Swing :


1. les composants de base, qui ne contiennent pas
d'autres composants (boutons, etc.),
2. les conteneurs, dont le but principal est de contenir et
d'organiser d'autres composants (fentres, etc.).
Les conteneurs sont spars en deux catgories:
1. les conteneurs de niveau intermdiaire, qui peuvent
eux-mme tre contenus par d'autres conteneurs,
2. les conteneurs de niveau suprieur (top-level
containers), qui ne peuvent pas l'tre.
Hirarchie
Les composants d'une application Swing sont organiss en
(au moins) une hirarchie arborescente dont:
la racine est un conteneur de niveau suprieur,
les nuds autres que la racine sont des composants
intermdiaires,
les feuilles sont des composants de base.
Le principal type de conteneur de niveau suprieur est la
fentre, donc chaque fentre affiche l'cran par une
application Swing correspond une hirarchie.
A noter qu'un composant ne peut pas appartenir plus
d'une hirarchie, ou apparatre plus d'une fois dans la
mme hirarchie.
Exemple de hirarchie
conteneur de
conteneur JFrame niveau suprieur
intermdiaire

JPanel JLabel JPanel

JLabel JLabel JPanel JLabel

composant
de base JButton JButton

Note : cette hirarchie a t lgrement simplifie par


rapport la ralit.
Prsentation l'cran
A l'cran, tout composant occupe une zone rectangulaire.
Les fils d'un conteneur se partagent gnralement sa zone
lui, et il n'y a pas de chevauchement entre composants
frres.
La hirarchie de composants est donc aplatie en un
ensemble de zones rectangulaires imbriques.

hirarchie apparence
JFrame

JPanel JPanel
JButton

JButton

JButton

JButton
JComponent

La classe abstraite JComponent sert de classe-mre tous


les composants Swing, sauf ceux de niveau suprieur.
JComponent et ses sous-classes possdent un grand
nombre de proprits (attributs) modifiables. A chacune
d'entre-elles est associe une mthode de lecture nomme
get et une mthode d'criture nomme set.
Par exemple, la proprit font, qui contient la police
utilise pour le texte d'un composant, se lit avec la mthode
getFont et s'crit avec la mthode setFont.
Composants de base
Les composants de base offerts par Swing incluent :
une tiquette, textuelle ou graphique (JLabel),
diffrents boutons : un tat (JButton), deux tats
(JToggleButton), radio (JRadioButton), cocher
(JCheckBox),
un champ textuel (JTextField), galement en version
formatante (JFormattedTextField), ou masque
pour les mots de passe (JPasswordField),
une liste de valeurs dont certaines peuvent tre
slectionnes (JList),
etc.
Conteneurs intermdiaires

Les conteneurs intermdiaires offerts par Swing incluent :


un panneau spar en deux parties redimensionnables,
affichant chacune un composant (JSplitPane),
un panneau onglets (JTabbedPane),
un panneau affichant une partie d'un composant trop
grand pour tre affich en entier (JScrollPane),
un panneau permettant de superposer plusieurs
composants (JLayeredPane),
un panneau sans reprsentation graphique (JPanel),
etc.
Conteneurs de niveau sup.

Les conteneurs de niveau suprieur offerts par Swing sont


au nombre de trois :
la fentre (JFrame),
la bote de dialogue (JDialog),
l' applet (JApplet) destine principalement tre
utilise dans un navigateur Web, rarement utilise de
nos jours.
Exemple
L'interface graphique d'une calculatrice quatre oprations
pourrait tre obtenue au moyen de la hirarchie suivante :

JFrame

JPanel

JFormattedTF

JButton

JButton

Exemple
L'interface graphique d'une calculatrice quatre oprations
pourrait tre obtenue au moyen de la hirarchie suivante :

JFrame

JPanel

JFormattedTF

JButton

JButton

Exemple
L'interface graphique d'une calculatrice quatre oprations
pourrait tre obtenue au moyen de la hirarchie suivante :

JFrame

JPanel

JFormattedTF

JButton

JButton

Exemple
L'interface graphique d'une calculatrice quatre oprations
pourrait tre obtenue au moyen de la hirarchie suivante :

JFrame

JPanel

JFormattedTF

JButton

JButton

Exemple
L'interface graphique d'une calculatrice quatre oprations
pourrait tre obtenue au moyen de la hirarchie suivante :

JFrame

JPanel

JFormattedTF

JButton

JButton

Conteneurs
de niveau suprieur
Composants de niveau sup.

Les composants de niveau suprieur (top-level components)


sont la racine de toute hirarchie visible l'cran.
Contrairement aux autres types de composants, ceux de
niveau suprieur ne peuvent pas tre inclus dans d'autres
composants.
Swing offre trois types de conteneurs de niveau suprieur:
la fentre, la bote de dialogue et l'applet. Seuls les deux
premiers sont examins ici.
JFrame
JFrame reprsente une fentre.
Ses principales proprits sont: son titre (title), sa taille
et sa position l'cran (bounds), sa visibilit (visible,
valant false par dfaut), son comportement en cas de
fermeture (defaultCloseOperation) et son panneau de
contenu (contentPane).

titre

Une fentre

panneau
de contenu
Fermeture des fentres
Par dfaut, lorsque l'utilisateur ferme une fentre, celle-ci est
simplement rendue invisible.
Ce comportement est souvent inadquat pour la fentre
principale d'une application, car il est prfrable que la
fermeture de cette fentre provoque l'arrt complet de
l'application, p.ex. via un appel System.exit.
Pour obtenir ce comportement, on peut changer la
proprit defaultCloseOperation afin de lui donner la
valeur EXIT_ON_CLOSE :
JFrame f = ;
frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
Agencement

Comme cela sera expliqu plus loin, l'agencement des


composants l'cran est gnralement fait
automatiquement dans une application Swing. Cet
agencement se fait rcursivement, en commenant par les
feuilles puis en remontant jusqu' la racine.
Les composants de niveau suprieur offrent une mthode
pack permet d'agencer tous les composants de la
hirarchie dont ils constituent la racine.
JDialog

JDialog reprsente une bote de dialogue, visuellement


similaire une fentre mais se comportant diffremment.
Une bote de dialogue est toujours lie une fentre
existante, dans le sens o lorsque cette dernire est ferme
ou iconifie, il en va de mme de la premire.
Beaucoup de botes de dialogue sont modales, dans le sens
o toute interaction avec le reste de l'application est
impossible tant et aussi longtemps que la bote n'est pas
ferme.
Panneaux racine/contenu
Les conteneurs de niveau suprieur ne contiennent pas
directement un certain nombre de composants fils. Au lieu
de cela, ils possdent un unique panneau racine (root
pane), un type spcial de conteneur intermdiaire.
Ce panneau racine contient, entre autres, un panneau de
contenu (content pane), dans lequel les composants
spcifiques l'application sont ajouts. La plupart des
applications ignorent donc le panneau racine et
interagissent uniquement avec le panneau de contenu.
Le panneau de contenu est une proprit modifiable des
conteneurs de niveau suprieur, nomme contentPane.
Panneaux racine/contenu

prdfini
et fixe JFrame
rootPane

JRootPane

contentPane

JPanel
spcifique
l'application

Conteneurs
intermdiaires
Conteneur intermdiaire

Les conteneurs intermdiaires sont les nuds autres que


la racine de la hirarchie.
Le but principal d'un conteneur intermdiaire est de
grouper et d'organiser un certain nombre d'autres
composants, nomm ses fils. Ds lors, sa reprsentation
graphique propre est souvent minimale, voire inexistante.
JSplitPane
JSplitPane permet de diviser le composant en deux
parties, chacune affichant un composant fils.
La division peut tre verticale ou horizontale, et est
redimensionnable, ventuellement par l'utilisateur.

fils 1 fils 2
JTabbedPane
JTabbedPane est un panneau compos d'un certain
nombre d'onglets affichant chacun un composant fils
diffrent. Un seul onglet est visible un instant donn.

fils (onglet) 1
JScrollPane
JScrollPane donne accs une sous-partie d'un
composant trop grand pour tenir l'cran et permet de
dplacer la zone visualise de diffrentes manires, p.ex. au
moyen de barres de dfilement.

Lorem ipsum dolor sit amet, consectetur


adipiscing elit. Donec a diam lectus. Sed sit
amet ipsum mauris. Maecenas congue ligula
ac quam viverra nec consectetur ante
hendrerit. Donec et mollis dolor. Praesent et
diam eget libero egestas mattis sit amet vitae
augue. Nam tincidunt congue enim, ut porta
lorem lacinia consectetur. Donec ut libero sed
arcu vehicula ultricies a non tortor. Lorem
ipsum dolor sit amet, consectetur adipiscing
elit. Aenean ut gravida lorem. Ut turpis felis,
pulvinar a semper sed, adipiscing id dolor.
Pellentesque auctor nisi id magna consequat
sagittis. Curabitur dapibus enim sit amet elit
pharetra tincidunt feugiat nisl imperdiet. Ut
convallis libero in urna ultrices accumsan.
Donec sed odio eros. Donec viverra mi quis
quam pulvinar at malesuada arcu rhoncus.
Cum sociis natoque penatibus et magnis dis
parturient montes, nascetur ridiculus mus. In
rutrum accumsan ultricies. Mauris vitae nisi at
sem facilisis semper ac in est.
JLayeredPane
JLayeredPane permet de superposer plusieurs
composants, ce qui peut tre utile pour dessiner au-dessus
de composants existants ou pour intercepter les clics de
souris qui leur sont destins.

fils 1

fils 2

fils 3
Conteneur
intermdiaire
JPanel
JPanel

JPanel reprsente un panneau, un conteneur intermdiaire


sans reprsentation graphique propre (exception faite de
son ventuelle bordure, voir plus loin) et pouvant avoir un
nombre quelconque de fils.
Malgr son invisibilit, JPanel joue un rle fondamental
dans l'organisation des interfaces, de par sa capacit
grouper et placer via son gestionnaire d'agencement
d'autres composants.
Gestion des fils
Les mthodes add et remove permettent de grer les fils
d'un conteneur JPanel :
void add(JComponent c, Object l, int i) :
insre le composant c la position i dans les fils (1
signifiant la fin) et lui associe l'information
d'agencement l (voir plus loin),
void add(JComponent c, Object l)
add(c, l, -1)
void add(JComponent c) add(c, null)
void remove(JComponent c) : supprime le
composant c des fils,
void remove(int i) : supprime le fils d'index i.
Bornes des fils
Tout composant fils d'un panneau occupe un rectangle
imbriqu dans celui de son parent. On nomme bornes
(bounds) la position (x, y) et la taille (width, height) de ce
rectangle, exprims dans le repre du panneau.
x

y panneau parent

fils
height

width
Agencement des fils

L'agencement des fils leur positionnement l'intrieur du


rectangle de leur parent peut se faire de deux manires :
1. manuellement , en changeant leurs bornes au
moyen de la mthode setBounds,
2. via un gestionnaire d'agencement (layout manager)
attach au parent et responsable de l'agencement de
ses fils et de son dimensionnement.
Dans la quasi-totalit des cas, la seconde solution est
choisie.
Agencement
Les gestionnaires d'agencement peuvent utiliser plusieurs
caractristiques des composants fils pour les placer :
leur index dans la squence des fils,
leur taille minimale (proprit minimumSize), prfre
(preferredSize) et maximale (maximumSize),
l'ventuelle information d'agencement qui leur a t
associe au moment de leur ajout via la mthode add.
Attention : les gestionnaires ont le droit mais pas
l'obligation d'utiliser ces caractristiques. En particulier,
plusieurs gestionnaires ignorent totalement les informations
de taille.
LayoutManager

L'interface LayoutManager reprsente un gestionnaire


d'agencement.
Un certain nombre de gestionnaires prdfinis
l'implmentant sont fournis avec Swing : FlowLayout,
BorderLayout, GridLayout, GridBagLayout, etc. Ces
gestionnaires agencent chacun les fils en fonction d'une
technique qui leur est propre.
BorderLayout
BorderLayout dcoupe le composant en cinq rgions
nommes, chacune d'entre-elles pouvant contenir au plus
un composant.

PAGE_START

LINE_START CENTER LINE_END

PAGE_END

Toutes les zones sauf la centrale sont dimensionnes en


fonction de leur contenu qui peut tre inexistant. La
totalit de l'espace restant est attribu la zone centrale.
FlowLayout
FlowLayout place les fils de la mme manire que les
mots d'un texte sont arrangs en lignes successives.
Cet agencement peut se faire de gauche droite ou de
droite gauche, et les lignes peuvent tre alignes
gauche, droite, ou centres. Les fils sont spars
horizontalement et verticalement par un espacement
configurable.
Par exemple, il peut agencer ainsi six fils d'un panneau en
les plaant de gauche droite et en centrant chaque ligne :

1 2 3 4

5 6
BoxLayout
BoxLayout place les fils dans l'ordre, soit aligns
horizontalement, soit empils verticalement.
Par exemple, il peut agencer ainsi trois fils d'un panneau en
les empilant verticalement :

3
GridLayout
GridLayout place les fils dans une grille de nm cellules
de taille identique, en partant du coin haut-gauche et en
suivant le sens de lecture.
Par exemple, il peut agencer ainsi neuf fils d'un panneau
dans une grille de 33 cellules :

1 2 3

4 5 6

7 8 9
Autres gestionnaires
Swing offre encore d'autres gestionnaires d'agencement,
plus puissants que ceux prsents jusqu'ici, parmi lesquels :
GridBagLayout, version amliore de GridLayout
permettant de dimensionner les lignes et colonnes
individuellement, et de combiner des cellules,
GroupLayout, associant chaque composant un
groupe horizontal et un groupe vertical et alignant de
manire configurable tous les composants d'un groupe.
Malheureusement, comme tous les gestionnaires
d'agencement offerts par Swing, ils montrent assez vite leurs
limites lors de la construction d'interfaces complexes.
Exemple
L'interface de la calculatrice peut tre mise en page au
moyen de deux gestionnaires :
1. le premier de type BorderLayout, attach au
panneau de contenu, permettant de placer l'affichage
dans la zone PAGE_START et le panneau du clavier
dans la zone CENTER,
2. le second de type GridLayout et de taille 44,
attach au panneau clavier.
Exemple
L'interface de la calculatrice peut tre mise en page au
moyen de deux gestionnaires :
1. le premier de type BorderLayout, attach au
panneau de contenu, permettant de placer l'affichage
dans la zone PAGE_START et le panneau du clavier
dans la zone CENTER,
2. le second de type GridLayout et de taille 44,
attach au panneau clavier.

BorderLayout
Exemple
L'interface de la calculatrice peut tre mise en page au
moyen de deux gestionnaires :
1. le premier de type BorderLayout, attach au
panneau de contenu, permettant de placer l'affichage
dans la zone PAGE_START et le panneau du clavier
dans la zone CENTER,
2. le second de type GridLayout et de taille 44,
attach au panneau clavier.

BorderLayout
GridLayout (44)
Exemple
JPanel p = new JPanel(new BorderLayout());
JFormattedTextField display = ;
// configuration de display
p.add(display, BorderLayout.PAGE_START);

JPanel keyboard =
new JPanel(new GridLayout(4, 4));
// configuration de keyboard (boutons, )
p.add(keyboard, BorderLayout.CENTER);

JFrame frame = new JFrame("RPN Calc");


frame.setContentPane(panel);
Composants
de base
Etiquette
JLabel reprsente l'un des composants les plus simples
qui soit, une tiquette textuelle et/ou graphique. Ses
principales proprits sont le texte (text) et l'image (icon)
qu'elle affiche, pouvant les deux tre vides (null).

tiquette

Nom

Prnom
Age
Bouton un tat
JButton reprsente un bouton un tat, destin tre
cliqu pour effectuer une action.
Sa principale proprit est le texte qu'il affiche (text). Des
auditeurs peuvent lui tre attachs pour grer les clics de
l'utilisateur voir plus loin.

click me!
Case cocher
JCheckBox reprsente une case cocher, qui peut tre
slectionne ou non. Ses principales proprits sont le
texte qu'elle affiche (text) et son tat (selected).

fromage

pain

vin
ail
Bouton radio
JRadioButton reprsente un bouton radio , similaire
une case cocher mais faisant partie d'un groupe (de type
ButtonGroup) dont un seul peut tre slectionn.
Ses principales proprits sont les mmes que celles de
JCheckBox.

fondue

raclette

crote au fromage

Malakoffs
Combo box
JComboBox reprsente une combo box permettant de
choisir une valeur parmi un ensemble prdfini et
ventuellement d'en entrer une autre.

Pays Suisse
Tadjikistan
Turkmnistan
Vatican
Zimbabwe
Composant textuel simple
JTextField et ses sous-classes JFormattedTextField
et JPasswordField reprsentent des champs textuels
une ligne et prsentation uniforme (police unique, etc.).
Leur principale proprit est leur texte (text), une simple
chane de caractres de type String.

Nom Marie JTextField


Mot de passe JPasswordField
Age 27 JFormattedTextField

JFormattedTextField stocke une valeur non textuelle


dans sa proprit value et la transforme en texte (et
inversement) au moyen d'un formateur qui lui est attach.
Composant textuel volu
JTextArea est similaire JTextField mais permet les
lignes multiples, tandis que JTextPane et JEditorPane
permettent l'affichage et ventuellement l'dition de
texte mis en page.
Leur principale proprit est le texte qu'ils contiennent
(text), galement disponible en version mise en page
(document).

Lorem ipsum dolor sit amet, consectetur


adipiscing elit. Quisque tincidunt dolor a
convallis sagittis. Vestibulum dapibus
massa arcu, id cursus est sodales sit
amet. Phasellus mi ex, posuere in nisi a,
varius malesuada urna.
Barre de progression
JProgressBar reprsente une barre de progression,
permettant de visualiser l'tat d'avancement d'une
opration de longue dure.
Sa principale proprit est sa valeur (value), un entier
compris entre 0 et une valeur maximale choisie, indiquant
l'tat d'avancement actuel.

60%
Macro-composants
En plus des composants de base simples dcrits
prcdemment, Swing offre des macro-composants souvent
utiles, construits partir des composants de base :
JColorChooser, qui permet de choisir une couleur de
diffrentes manires (via une palette, en choisissant ses
composantes dans diffrents modles, etc.),
JFileChooser, qui permet de choisir un ou plusieurs
fichiers ou rpertoires, existants ou non, en naviguant
dans le systme de fichiers.
Ces deux macro-composants peuvent s'utiliser comme des
composants normaux ou dans des botes de dialogue.
Composants structurs

Finalement, Swing offre des composants permettant


d'afficher des donnes structures : listes, tableaux,
hirarchie arborescente.
Ces composants sont plus complexes utiliser que les
autres tant donn la nature des donnes qu'ils affichent.
Pour les obtenir, ces composants utilisent un modle qu'on
leur fournit.
Modles
Composants complexes

Plusieurs composants de base permettent d'afficher et de


manipuler des donnes complexes, par exemple :
JList affiche une liste d'lments,
JTree affiche une hirarchie arborescente,
JTable affiche une table bidimensionnelle de cellules,
etc.
O stocker les donnes affiches par ces composants et
quel type leur attribuer ?
Modles

Une solution serait de stocker les donnes directement


dans les composants. Par exemple, le composant JList
pourrait stocker la liste des lments qu'il affiche.
Cette solution est mauvaise car elle va l'encontre de la
sparation conseille par le patron MVC : les donnes
afficher font partie du modle et ne doivent donc pas tre
stocke dans la vue.
Une meilleure solution est de faire en sorte que les
composants puissent directement utiliser les donnes du
modle.
Modles

Swing offre la possibilit d'attacher chacun des


composants complexes prcits un objet appel modle
(model) et reprsentant les donnes sous-jacentes. Ce
modle doit tre observable au sens du patron Observer
pour permettre au composant de se mettre jour
automatiquement.
Le type de ces modles est spcifi par des interfaces
fournies par Swing, et il est donc gnralement ncessaire
d'crire un adaptateur pour adapter les donnes du
programme aux types attendus par Swing.
Exemple : JList
Le composant JList affiche une liste d'lments et permet
leur slection. Il doit donc pouvoir effectuer les oprations
suivantes sur la liste afficher :
obtenir sa taille,
obtenir l'lment d'indice donn,
observer la liste pour tre inform des changements.
Ces oprations sont regroupes dans l'interface
ListModel, reprsentant un modle de liste.

vue + modle
contrleur model

JList ListModel
listeners
ListModel
L'interface ListModel offre d'une part des mthodes
permettant de grer l'ensemble des observateursappels
ici auditeurs (listeners)et d'autre part des mthodes de
consultation de la liste de valeurs.
public interface ListModel<E> {
void addListDataListener(LDL l);
void removeListDataListener(LDL l);

int getSize();
E getElementAt(int i);
}
(Le type ListDataListener a t abrg LDL pour des
questions de prsentation).
AbstractListModel

Pour faciliter l'criture de modles de listes, Swing offre la


classe AbstractListModel qui met en uvre les
mthodes grant les auditeurs, laissant uniquement les
mthodes getSize et getElementAtIndex abstraites.
Cette classe fournit de plus des mthodes dont le nom
commence par fire et permettant d'informer les
auditeurs de changements dans le modle similaires la
mthode notifyObservers des sujets du patron
Observer.
ListDataListener
L'interface ListDataListener reprsente un observateur
de modle de liste, appel ici auditeur.
public interface ListDataListener {
void intervalAdded(ListDataEvent e);
void intervalRemoved(ListDataEvent e);
void contentsChanged(ListDataEvent e);
}
Plutt qu'une unique mthode de mise jour (update), il
en possde trois. La dernire est gnrale, tandis que les
deux premires reprsentent des cas particuliers ajout et
suppression d'lments qui ont t jugs assez frquents
pour valoir la peine d'tre traits sparment.
ListDataEvent

La classe ListDataEvent contient les informations lies au


changement du contenu de la liste observe, savoir :
le type de changement ajout d'un intervalle,
suppression d'un intervalle, changement gnral,
l'index du premier lment affect par le changement,
l'index du dernier lment affect par le changement.
Diagramme de classes
Le diagramme de classes ci-dessous illustre de manire
lgrement simplifie les classes qui seraient utilises par
une application incluant un composant JList.
model
1
*
ListDataListener ListModel

listeners
1 JList 1 AbstractListModel

ListDataEvent MyListModelAdapter
Composants
personnaliss
Composants personnaliss

Mme si les composants prdfinis couvrent un grand


nombre de besoins, ils ne sauraient les couvrir tous.
Lorsqu'une application ncessite un composant ne figurant
pas parmi les prdfinis, il est possible de le dfinir sous la
forme d'une nouvelle sous-classe de JComponent.
Les principales mthodes redfinir dans ce cas sont :
getPreferredSize, getMinimumSize et
getMaximumSize, qui permettent aux gestionnaires
d'agencement de le dimensionner correctement,
paintComponent, qui dessine le composant.
getSize

Les mthodes getPreferredSize, getMinimumSize et


getMaximumSize sont utilises par certains gestionnaires
de mise en page mais pas tous pour dterminer la taille
du composant.
Il peut donc tre utile de les redfinir lorsque la taille du
composant ne peut pas tre arbitraire.
paintComponent

La mthode paintComponent est automatiquement


appele par Swing chaque fois que le composant doit tre
(re)dessin, par exemple lorsqu'il apparat pour la premire
fois l'cran.
Cette mthode reoit en argument le contexte graphique
utiliser pour effectuer le dessin. Le repre qui lui est associ
est celui du composant.
Exemple
Le composant ci-dessous affiche un rectangle rouge centr
sur fond noir :
public final class RonB extends JComponent {
@Override
protected void paintComponent(Graphics g) {
int w = (int)getBounds().getWidth();
int h = (int)getBounds().getHeight();
g.setColor(Color.BLACK);
g.fillRect(0, 0, w, h);
g.setColor(Color.RED);
g.fillRect(w/4, h/4, w/2, h/2);
}
}
repaint
Il peut arriver qu'un composant doive tre redessin, p.ex.
suite un changement des donnes du modle qu'il
reprsente.
Cela ne doit en aucun cas tre fait en appelant directement
paintComponent, cette mthode tant uniquement
destine tre appele par Swing.
Au lieu de cela, il convient d'appeler la mthode repaint
du composant, afin de demander Swing de le redessiner
(via sa mthode paintComponent) aussi vite que possible.
A noter que Swing redessine automatiquement les
composants dont la taille a chang, sans qu'un appel
repaint ne soit ncessaire.
Bordures
Bordures
Il est possible d'ajouter une bordure (border) n'importe
quel composant au moyen de la mthode setBorder de
JComponent.
Il est assez frquent d'ajouter une bordure un panneau
(JPanel) afin de grouper visuellement un certain nombre
de composants lis logiquement. Par exemple :

bordure Donnes personnelles


avec titre Nom

Prnom
Age
BorderFactory
Contrairement d'autres objets Swing, les bordures ne
doivent pas tre cres directement au moyen de l'nonc
new. Au lieu de cela, il convient d'appeler l'une des
mthodes fabriques de la classe BorderFactory, par
exemple :
createLineBorder prend une couleur et une
paisseur de trait et retourne une bordure compose
d'une simple ligne,
createTitledBorder prend une bordure existante et
une chane, qu'elle lui ajoute en titre,
etc.
Gestion des
Dire que l'interface est bloque tant que
le gestionnaire ne retourne pas

vnements
Prog. vnementielle
Un programme dot d'une interface graphique ne fait
gnralement qu'attendre que l'utilisateur interagisse avec
celle-ci, ragit en consquence, puis se remet attendre.
Chaque fois que le programme est forc de ragir, on dit
qu'un vnement (event) s'est produit.
Cette caractristique des programmes graphiques induit un
style de programmation particulier nomm programmation
vnementielle (event-driven programming).
Ce style se retrouve dans toutes les applications dont le but
principal est de ragir des vnements externes, p.ex. les
serveurs (Web et autres).
Boucle vnementielle
Au cur de tout programme vnementiel se trouve une
boucle traitant successivement les vnements dans leur
ordre d'arrive. Cette boucle, nomme boucle
vnementielle (event loop), pourrait s'exprimer ainsi en
pseudo-code :
tant que le programme n'est pas termin
attendre le prochain vnement
traiter cet vnement
Cette boucle est souvent fournie par une bibliothque et ne
doit dans ce cas pas tre crite explicitement. Il en va ainsi
de la plupart des bibliothques de gestion d'interfaces
graphiques, dont Swing.
Gestion des vnements

Si la boucle vnementielle peut tre identique pour tous


les programmes, la manire dont les diffrents vnements
sont grs est bien entendu spcifique chaque
programme.
Ds lors, il doit tre possible de dfinir la manire de traiter
chaque vnement. Cela se fait gnralement en crivant,
pour chaque vnement important, un morceau de code le
grant, appel le gestionnaire d'vnement (event handler).
Ce gestionnaire est associ, d'une manire ou d'une autre,
l'vnement.
Gestion des vnements
La boucle vnementielle est squentielle, dans le sens o
un vnement ne peut tre trait que lorsque le traitement
de l'vnement prcdent est termin.
Dans le cas d'une interface graphique, cela signifie que
celle-ci est totalement bloque tant et aussi longtemps
qu'un vnement est en cours de traitement.
Pour cette raison, les gestionnaires d'vnements doivent
autant que possible s'excuter rapidement. Si cela n'est pas
possible, il faut utiliser la concurrence pour effectuer les
longs traitements en tche de fond ce qui sort du cadre
de ce cours.
Boucle vnementielle Swing
Dans une application graphique Swing, la boucle
vnementielle s'excute dans un fil d'excution (thread)
spar, nomm le fil de gestion des vnements (event
dispatching thread ou EDT).
Ce fil d'excution est dmarr automatiquement lors de
l'utilisation de Swing, rendant la boucle vnementielle
particulirement invisible au programmeur. Elle n'en existe
pas moins !
De manire gnrale, tous les appels des mthodes de
Swing doit se faire depuis le fil de gestion des vnements.
En particulier, toute la cration de l'interface doit s'y faire.
Auditeurs

Dans Swing, les gestionnaires d'vnements sont des


objets, appels auditeurs (listeners),implmentant une
interface qui dfinit une ou plusieurs mthodes de gestion
d'vnement.
Les auditeurs sont attachs une source d'vnements
gnralement un composant et leurs mthodes sont
appeles chaque fois qu'un vnement se produit.
(Les auditeurs sont assez similaires aux observateurs du
patron Observer, la mthode update de ces derniers
grant l'vnement l'tat du sujet a chang ).
Exemple
La classe ci-dessous illustre la structure typique d'un
programme Swing. L'interface graphique est cre par la
mthode createUI, appele indirectement via
invokeLater afin de garantir qu'elle s'excute sur le fil de
gestion des vnements.
public final class Main {
private static void createUI()
{ /* voir page suivante */ }
public static void main(String[] args) {
SwingUtilities.invokeLater(
() -> createUI());
}
}
Exemple
La mthode createUI cre une fentre et y ajoute un
bouton dont l'auditeur affiche un message l'cran
lorsqu'on lui clique dessus.
private static void createUI() {
JFrame w = new JFrame();
w.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
JButton b = new JButton("click me!");
b.addActionListener(
e -> System.out.println("click!"));
w.getContentPane().add(b);
w.pack();
w.setVisible(true);
}
Exemple
La figure ci-dessous illustre l'excution des diffrentes
parties du programme sur les deux fils existants.

fil principal fil de gestion des vts.


(main thread) (EDT)

main
invokeLater boucle vnementielle :
createUI

println("click!")

Objets vnements

Lorsqu'un vnement se produit, Swing collecte les


informations son sujet dans un objet pass l'auditeur. Par
un lger abus de langage, cet objet lui-mme est nomm
vnement (event).
Gnralement, chaque type d'vnement correspond un
type d'auditeur et un type d'objet-vnement.
Types d'auditeurs

Swing dfinit un grand nombre de types d'auditeurs, en


fonction du type d'vnement qu'ils coutent. Les
principaux types d'auditeurs sont :
les auditeurs d'action (action listeners),
les auditeurs de souris (mouse listeners),
les auditeurs de menu (menu listeners),
les auditeurs de clavier (key listeners),
les auditeurs de cible de saisie (focus listeners).
Seuls les deux premiers sont examins ici, les autres ayant
un fonctionnement similaire.
ActionListener
L'interface (fonctionnelle) ActionListener reprsente un
auditeur l'coute des vnements de type action. Ces
vnements se produisent p.ex. lorsque l'utilisateur clique
sur un bouton, slectionne un menu ou presse Entre dans
un champ textuel.
public interface ActionListener {
void actionPerformed(ActionEvent e);
}
La classe ActionEvent contient diffrentes informations au
sujet de l'vnement, p.ex. les touches de modifications
(Control, Shift, ) presses au moment du dclenchement
de l'action.
ActionListener

Un auditeur de type ActionListener peut tre attach


plusieurs types de composants, principalement les boutons,
les champs textuels et les entres de menus.
Chacun de ces types de composants offre les mthodes
addActionListener et removeActionListener pour
ajouter/supprimer un auditeur d'action.
MouseListener
L'interface MouseListener reprsente un auditeur
l'coute de certains vnements lis la souris: entre et
sortie des bornes du composant, pression et relchement
des boutons:
public interface MouseListener {
void mouseEntered(MouseEvent e);
void mouseExited(MouseEvent e);
void mouseClicked(MouseEvent e);
void mousePressed(MouseEvent e);
void mouseReleased(MouseEvent e);
}
La classe MouseEvent contient diffrentes informations
concernant l'vnement, p.ex. la position de la souris.
MouseMotionListener
L'interface MouseMotionListener reprsente un auditeur
l'coute des vnements lis au dplacement de la souris,
avec un bouton press (mouseDragged) ou non
(mouseMoved):
public interface MouseMotionListener {
void mouseDragged(MouseEvent e);
void mouseMoved(MouseEvent e);
}
Chaque mouvement de la souris constituant un nouvel
vnement, ceux-ci peuvent tre trs nombreux. Les
auditeurs de type MouseMotionListener se doivent donc
de traiter rapidement les vnements.
MouseWheelListener

L'interface (fonctionnelle) MouseWheelListener


reprsente un auditeur l'coute des vnements lis la
molette de la souris:
public interface MouseWheelListener {
void mouseWheelMoved(MouseWheelEvent e);
}
La classe MouseWheelEvent tend MouseEvent en lui
ajoutant des informations lies la molette: distance et
sens de rotation, etc.
MouseListener

Les trois types d'auditeurs lis la souris peuvent tre


attachs (et dtachs de) n'importe quel composant au
moyen des mthodes addMouseListener et
removeMouseListener.
MouseAdapter

La classe hritable MouseAdapter fournit une mise en


uvre par dfaut des interfaces MouseListener,
MouseMotionListener et MouseWheelListener. Elle
implmente la totalit des mthodes de ces interfaces, en
ne faisant rien dans tous les cas.
Attention : malgr son nom, cette classe n'est pas un
adaptateur au sens du patron Adapter. Un nom plus
conforme aux conventions gnralement utilises dans la
bibliothque Java serait AbstractMouseListener.

Vous aimerez peut-être aussi