Transcript Cours SWING

Introduction aux IHM et à la
réflexivité Java
Vos premiers pas en Swing
Modèle & Vue
MODÈLE/VUE AVEC LES JLIST ET LES
JTABLE
• Il est possible de partager le modèle de données d’une JTable
ou d’une JList à d’autres composants considérés comme
d’autres vues de l’objet JTable ou JList
• Par exemple : une liste de noms affichée dans une JList. La JList
est une vue (interactive) de la liste de noms permettant la
sélection d’élément.
• Une représentation tabulaire de la même liste est une autre
vue
• Un texte qui indique le nombre d’éléments de la liste est une
3
autre vue du modèle
ILLUSTRATION
4
Définition du modèle associé
• Si le modèle est décrit par une interface
ListModel / TableModel prédéfinie,
• L’interface permet d’expliciter comment gérer les données du
modèle et d’ajouter des vues (écouteurs de changements sur
le modèle)
Rem : il existe généralement une classe Adapter nommée
Default<X>Model avec <X>=List ou Table
• Si le modèle change, il génère un événement et notifie les
vues (via des méthodes en fire<…>)
5
JLIST
• Possède différents constructeurs :
– Données fixes :
• JList (Vector listData)
• JList (Object[] listData)
– Données modifiables :
• JList (ListModel dm)
6
JLIST
• Exemple
String listData[]= {…, "Carlos" ,…, "Ramier"};
DefaultListModel model = new DefaultListModel();
for (int i=0; i<listData.length; i++)
model.addElement(listData[i]);
JList dataList = new JList(model);
JScrollPane listeScroll = new JScrollPane(dataList);
7
JLIST
• Possède une méthode qui permet de spécifier le mode de
sélection : setSelectionMode (int mode). mode peut valoir :
– SINGLE_SELECTION
– SINGLE_INTERVAL_SELECTION
– MULTIPLE_INTERVAL_SELECTION
• Possède une méthode addListSelectionListener () qui écoute
un ListSelectionEvent e qui est émis à chaque fois qu’une
sélection change
et implémente une méthode : valueChanged
8
JLIST : LE MODÈLE ASSOCIÉ
• Pour le modèle, utiliser la classe DefaultListModel. Ce modèle
stocke les objets sous forme de vecteur et fournit les
méthodes suivantes :
– addElement (Object),
– boolean contains(Object),
– boolean removeElement(Object)
– Object get(index), Object remove(index), int size()
– addListDataListener (ListDataListener l), remove…
– fireContentsChanged,fireIntervalAdded,
fireIntervalRemoved (Object source, int index0, int index1)
9
JLIST : LA VUE
• Une vue d’une JList implémente l’interface ListDataListener. Il
y a trois méthodes :
– void contentsChanged(ListDataEvent e) : contenu de la liste
l
a changé
– void intervalAdded(ListDataEvent e)
– void intervalRemoved(ListDataEvent e)
10
JLIST : PLUSIEURS VUES ?!
• Créer un modèle instance de DefaultListModel et le
mémoriser. Créer ensuite la liste avec ce modèle.
• Pour chaque composant désirant être informé des
changements ( = d’autres vues ou le contrôleur) :
– Mémoriser le modèle ( = le stocker dans un membre)
– Implémenter ListDataListener
– Enregistrer le composant dans le modèle avec
addListDataListener
11
ILLUSTRATION
12
JTABLE
• Un constructeur possible de JTable :
– JTable (Object[][] rowData, Object[] columnNames)
– On peut accéder au modèle sous-jacent avec la méthode
:
• TableModel getModel()
• Un autre constructeur avec directement le modèle :
String nomsCol[]={«Prenom», «Nom»};
String rows[][] = { {«Dinah»,«Cohen»}, … ,
{«Said», «Kharrazen»}};
DefaultTableModel model = new DefaultTableModel(rows, nomsCol);
JTable table = new JTable(model);
13
JTABLE : LE MODÈLE ASSOCIÉ
• Il existe 3 différents éléments pour créer un modèle :
– L’interface TableModel
– La classe AbstractTableModel qui implémente
TableModel
– La classe DefaultTableModel
• DefaultTableModel est le plus simple à utiliser, quelques
constructeurs associés :
– DefaultTableModel(int row, int col)
– DefaultTableModel(Object[][] data, Object[]
columnNames)
– DefaultTableModel(Vector data, Vector columnNames)
–…
14
JTABLE : LA VUE
• Une vue implémente l’interface TableDataListener
• Il y a une méthode :
– void tableChanged(TableModelEvent e)
• L’événement associé TableModelEvent :
– int getType() : INSERT, UPDATE, DELETE
– int getColumn()
– int getFirstRow()
– int getLastRow()
15
JTABLE : PLUSIEURS VUES ?!
• Créer un modèle, par exemple une instance de
DefaultTableModel et le mémoriser
• Pour chaque composant désirant être informé des
changements (les vues et/ou le contrôleur) :
– Mémoriser le modèle
– Implémenter TableModelListener
– Enregistrer le composant dans le modèle avec :
addTableModelListener
16
Vous avez vu comment écrire la
partie Modèle
la partie Vue
Reste comment mettre en place le
contrôle ?
Observer Observable
Rappel
Moyen
Définir une dépendance de “1” à
“n” entre des objets telle que
lorsque l’état d’un objet change,
tous ses dépendants sont
informés et mis à jour
automatiquement
Besoin d’événements
• Le pattern “Observer” décrit
– comment établir les relations entre les objets dépendants.
• Les objets-clés sont
– la source
• Peut avoir n’importe quel nombre d’observateurs dépendants
• Tous les observateurs sont informés lorsque l’état de la source change
– l’observateur.
• Chaque observateur demande à la source son état afin de se synchroniser
Structure
Implémentations Java du pattern
Une classe et une interface : class Observable {... } et
interface Observer
Un objet Observable doit être une instance de la classe qui dérive de la
classe Observable
Un objet observer doit être instance d’une classe qui implémente
l’interface Observer
void update(Observable o, Object arg);
Des listeners : ajouter des listeners, notifier les listeners avec des
évenements, réagir aux événements
Listeners Supported by Swing
Components
• http://java.sun.com/docs/books/tutorial/uisw
ing/events/intro.html
CREATION D’UN PANNEAU
class ButtonPanel extends JPanel
implements ActionListener // interface écouteur d'événements
{ private JButton Boutonjaune;
private JButton BoutonBleu;
private JButton BoutonRouge;
PLACER DES COMPOSANTS DANS LE PANNEAU
public ButtonPanel() // constructeur de la classe ButtonPanel
{ Boutonjaune = new JButton("Jaune");
BoutonBleu = new JButton("Bleu");
BoutonRouge = new JButton("Rouge");
// Insertion des trois boutons dans l'objet ButtonPanel
add(Boutonjaune);
add(BoutonBleu);
add(BoutonRouge);
ASSOCIER DES EVENEMENTS AUX COMPOSANTS
// Les sources d'événements sont déclarées à l'écouteur
Boutonjaune.addActionListener(this);
BoutonBleu.addActionListener(this);
BoutonRouge.addActionListener(this);
}
TRAITEMENT DES EVENEMENTS
{ public void actionPerformed(ActionEvent evt)
// Permet de traiter l'événement en fonction de l'objet source
{ Object source = evt.getSource();
Color color = getBackground();
if (source == Boutonjaune) color = Color.yellow;
else if (source == BoutonBleu) color = Color.blue;
else if (source == BoutonRouge) color = Color.red;
setBackground(color);
repaint();
}
}
CREATION DE LA FENETRE ET PLACEMENT DU PANNEAU
class ButtonFrame extends JFrame
{ public ButtonFrame()
{ setTitle("ButtonTest");
setSize(300, 200);
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0);
}
} );
Container contentPane = getContentPane();
contentPane.add(new ButtonPanel());
}
}
public class ButtonTest
{ public static void main(String[] args)
{ JFrame frame = new ButtonFrame();
frame.show();
}
LE CONTRÔLEUR
Zoom sur les événements et les Listeners
31
LE CONTRÔLEUR
•
•
•
•
•
Des types d’événements
Des écouteurs associés
Méthodes pour implémenter les écouteurs
Evénements Sémantiques
Les Actions
32
HÉRITAGE DES EVÉNEMENTS
33
Exemples d’événements
• Définis dans java.awt.event
– FocusEvent : activation ou désactivation du focus
du clavier
– MouseEvent : mouvement et clics de souris, et
entrer/sortir d’un composant
– KeyEvent : événements clavier
– WindowEvent
:
dés/activation,
ouverture,
fermeture, dés/iconification de fenêtres
– ComponentEvent : changement de taille, position
34
ou visibilité d’un composant
AWTEvent
• dérive de java.util.EventObject
• contient par héritage
– getSource() qui renvoie la source de l’événement
(objet où l’événement s’est produit)
• définit des constantes permettant d’identifier
des classes d’événements :
– MOUSE_EVENT_MASK
– MOUSE_MOTION_EVENT_MASK
– WINDOW_EVENT_MASK
–…
35
Filtrer les événements
• Une méthode ENABLEEVENTS()
– Les ID (types d’événements particuliers)
correspondants dans WindowEvent :
WINDOW_OPENED, WINDOW_CLOSING, …
– Pour les autres classes d’événements, il a d’autres
ID
36
UTILISER ENABLEEVENTS()
• Utilisation :
1. Appeler enableEvent () sur le composant avec des
masques AWTEvent
2. Implémenter les méthodes correspondantes, i.e :
• processEvent ( AWTEvent e)
• processMouseEvent ( MouseEvent e)
• …
37
GESTION GLOBALE AVEC
ENABLEEVENTS()
public class toto extends JFrame {
public toto() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
protected void processWindowEvent(WindowEvent e) {
if (e.getID() == WindowEvent.WINDOW_CLOSING){
dispose(); // libère les ressources
System.exit(0);
}
super.processWindowEvent( e ): // Passe l’ev.
}
}
38
}
LES ECOUTEURS
• Depuis (JAVA 1.1)
– interfaces écouteurs correspondants
masques d’événements principaux.
– extensions de java.util.EventListener.
aux
39
LES ECOUTEURS
– WindowListener : pour les événements de la
fenêtre
– MouseListener : pour les clics et entrées/sorties
fenêtre
– MouseMotionListener : pour les mouvements
de la souris
– KeyListener : pour les touches clavier
– FocusListener : pour le focus clavier
– ComponentListener : pour la configuration du
40
composant
Contrôle des Fenêtres
Concerne tout ce qui est en
rapport avec la fenêtre :
• WINDOWSLISTENER
– Ouvrir, fermer, réduire, agrandir,
windowActivated(WindowEvent e) - clic
windowDeactivated(WindowEvent e)
windowClosed(WindowEvent e)
windowOpened(WindowEvent e) 1ere fois
windowClosing(WindowEvent e) menu fermé
du système
windowDeiconified(WindowEvent e)
41
windowIconified(WindowEvent e)
Contrôle de la souris
• MouseListener : Gestion des états de la souris :
– Clic, Pressé, Relâché
– Et également l’entrée/sortie sur un composant
mouseClicked(MouseEvent e)
mouseEntered(MouseEvent e)
mouseExited(MouseEvent e)
mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)
42
Gestion des mouvements
MouseMotionListener : Mouvements de la
souris sur un composant avec bouton appuyé
ou relâché
mouseDragged(MouseEvent e)
mouseMoved(MouseEvent e)
43
MOUSEINPUTLISTENER
• interface écouteur de javax.swing.event.
– Implémente
• un MouseListener et un MouseMotionListener
• ATTENTION : il n’existe pas de méthode
addMouseInputListener il faut enregistrer
l’écouteur deux fois :
– avec addMouseListener
– et avec addMouseMotionListener
44
Contrôle du clavier
• KEYLISTENER
– concerne tout ce qui est en rapport avec le clavier
: tapé, pressé, relâché….
• keyPressed(KeyEvent e)
• keyReleased(KeyEvent e)
• keyTyped(KeyEvent e)
• FOCUSLISTENER
– gère le focus - savoir si un composant a obtenu le
focus ou s’il la perdu
• focusGained(FocusEvent e)
• focusLost(FocusEvent e)
45
Contrôle des composants
COMPONENTLISTENER permet de gérer:
L’apparition/disparition d’un composant
• componentHidden(ComponentEvent e)
• componentShown(ComponentEvent e)
– Le déplacement d’un composant
• componentMoved(ComponentEvent e)
– Le redimensionnement d’un composant
• componentResized(ComponentEvent e)
46
COMMENT AJOUTER UN
ECOUTEUR ?!
• Pour ajouter un écouteur, on utilise la
méthode addXXXListener (XXXListener l) sur le
composant désiré
• Il suffit alors de remplacer les XXX parce que
l’on souhaite avoir
49
POUR IMPLÉMENTER LES
ÉCOUTEURS
• Il existe plusieurs méthodes
– Etendre une classe Adapter ou implémenter une
interface Listener
– Définir des classes internes
– Définir des classes anonymes
50
ETENDRE UNE CLASSE ABSTRAITE
public class MaClass extends MouseAdapter {
...
unObject.addMouseListener(this);
...
public void mouseClicked(MouseEvent e) {
...
// l’implementation de la méthode
// associée à l’événement vient ici ...
}
}
51
IMPLÉMENTER UNE INTERFACE
public class MaClass implement MouseListener {
...
unObject.addMouseListener(this);
...
void mouseClicked(MouseEvent e) {}
void mouseEntered(MouseEvent e) {}
void mouseExited(MouseEvent e) {}
void mousePressed(MouseEvent e) {}
void mouseReleased(MouseEvent e) {}
}
52
DÉFINIR UNE CLASSE INTERNE
window.addWindowListener(new WindowHandler());
// classe interne WindowHandler
// pour les événements de fermeture
class WindowHandler extends WindowAdapter {
// Méthode pour WINDOW_CLOSING event
public void windowClosing( WindowEvent e ) {
window.dispose();
System.exit(0);
}
}
53
DÉFINIR UNE CLASSE ANONYME
button = new JButton("test");
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked (MouseEvent e) {
// code que l'on souhaite effectuer
}
});
54
EVÉNEMENTS SÉMANTIQUES
Ces trois événements sémantiques sont dans :
java.awt.event
55
EVÉNEMENTS ACTIONEVENT
• une action sur un composant réactif :
– Clic sur un item de menu,
– Clic sur un bouton,
–…
• émis par les objets de type :
– Boutons : JButton, JToggleButton, JCheckBox
– Menus : JMenu, JMenuItem, JCheckBoxMenuItem,
JRadioButtonMenuItem …
56
– Texte : JTextField
EVÉNEMENTS : ITEMEVENT
• composant sélectionné ou désélectionné
• émis par les objets de type :
– Boutons : JButton, JToggleButton, JCheckBox
– Menus : JMenu, JMenuItem, JCheckBoxMenuItem,
JRadioButtonMenuItem
– Mais aussi JComboBox, JList
57
EVÉNEMENTS ADJUSTMENTEVENT
• Se produisent quand un élément ajustable
comme une JScrollBar sont ajustés
• Sont émis par ScrollBar, JScrollBar
58
ECOUTEURS ASSOCIÉS AUX
EVÉNEMENTS SÉMANTIQUES
• Chaque interface contient une unique méthode :
– ActionListener : void actionPerformed(ActionEvent e)
– ItemListener : void itemStateChanged(ItemEvent e)
– AdjustementListener : void adjustementValueChanged
(AdjustementEvent e)
59
EXEMPLE (1/2)
• Cette applet contrôle l’apparition d’une
fenêtre supplémentaire (un JFrame) qui
apparaît lorsque l’on enfonce le bouton ‘‘Start
60
playing…’’
EXEMPLE (2/2)
• Dans le JFrame on trouvera un label et une
checkbox qui permettra de cocher si le label
est rendu visible ou invisible
• On pourra aussi iconifier le JFrame ou non
• Les différent événements captés écriront leur
source et leur type au centre du cadre de
61
l’applet précédent dans la zone de texte
AUTRES EVÉNEMENTS
SÉMANTIQUES
• Il existe d’autres événements sémantiques
comme par exemple :
– Une JList génère des SelectionEvent
– Les modèles associés aux listes et aux tables
génèrent des ListDataEvent et des
TableModelEvent (envoyés aux vues quand
des changements se produisent sur le modèle)
68
AUTRES EVÉNEMENTS
SÉMANTIQUES
• Il existe d’autres événements sémantiques
comme par exemple :
– Les sous-classes de AbstractButton peuvent
générer des événements ChangeEvent quand
on modifie l’état d’un bouton
– Les dérivés de JMenuItem génèrent des
MenuDragMouseEvent et des MenuKeyEvent
69
LES ACTIONS : CONCEPT
• Une action est objet de n’importe quelle classe
qui implémente l’interface Action.
• L’interface déclare des méthodes qui opèrent sur
un objet Action
• L’interface Action étend l’interface ActionListener
donc un objet Action est aussi un écouteur
d’événement d’action de type ActionEvent
70
LES ACTIONS : PRINCIPE
• Les composants Swing suivants possèdent une
méthode add() qui prend en argument un type
Action :
– JMenu ,
– JPopupMenu,
– JToolBar
71
LES ACTIONS : PRINCIPE
• un add() d’un objet Action sur un menu ou une
barre d’outils crée un composant à partir de
l’objet Action qui est du bon type par rapport
au composant auquel on l’ajoute (i.e. item de
menu ou bouton)
– ajout à un JMenu, add() ajoute un JMenuItem au
menu. ajoute à une JToolBar, c’est un JButton qui
lui sera ajouté
• l’objet Action est comme son propre écouteur,
le bouton et l’item de menu supporteront la 72
même procédure d’action.
PROPRIÉTÉS LIÉES À ACTION
.Il y a 7 propriétés standards qui caractérisent un
objet implémentant l’interface Action :
– NAME : String
– SMALL_ICON : Icon (pour la toolbar)
– SHORT_DESCRIPTION : String (pour le tooltip)
– ACCELERATOR_KEY : KeyStroke (accélérateur)
– LONG_DESCRIPTION : String (aide contextuelle)
– MNEMONIC_KEY : int (mnémonique de l’action)
– ACTION_COMMAND_KEY : (keymap associée au comp.)
• La classe Property est dans java.util.
73
• void putValue (String key, Object value) :
associe l’objet value avec la clé key dans le
dictionnaire pour l’objet Action
• Exemple : pour stocker un nom d’action
putValue(NAME, leNom) (On utilise la clé
standard NAME pour stocker l’objet leNom)
• Object getValue (String key) : retourne l’objet
correspondant à la clé key dans le dictionnaire.
• Pour retrouver l’icône de la toolbar dans une
méthode d’une classe d’action : Icon lineIcon =
(Icon) getValue (SMALL_ICON)
74
• boolean isEnabled() : retourne true si l’objet d’action
est actif et accessible
• void setEnabled(boolean state) : permet d’agir à la
fois sur le bouton de la barre d’outils et l’élément de
menu si tous deux ont été créés à partir de la même
action
• void addPropertyChangeListener
(PropertyChangeListener l) : ajoute un listener qui
écoute les changements de propriétés (état
d’activation). Utilisé par les conteneurs
• void removePropertyChangeListener
75
(PropertyChangeListener listener)
ABSTRACTACTION
• Est défini dans le package javax.swing et
implémente l’interface Action
• Fournit des mécanismes pour stocker les
propriétés d’une action
• Possède trois constructeurs :
– AbstractAction ( )
– AbstractAction ( String name )
– AbstractAction ( String name, Icon icon)
76