IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo

FAQ Java GUIConsultez toutes les FAQ

Nombre d'auteurs : 37, nombre de questions : 155, dernière mise à jour : 10 octobre 2015  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.

Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.

SommaireAWT et SwingLes listeners (10)
précédent sommaire suivant
 

Dans le contexte d'une interface graphique (Swing, AWT, etc.), les listeners permettent au programmeur de réagir suite aux actions de l'utilisateur (clic de souris, touche du clavier enfoncée, etc.).

Les « listeners » sont des interfaces. Ces interfaces fournissent une ou plusieurs méthodes qui peuvent donc être implémentées différemment selon les cas et les besoins, pour répondre aux événements.

Les interfaces « listener » sont présentes principalement dans le package java.awt.event, mais également dans le package javax.swing.event.

Chaque listener dispose d'une classe Event associée. Cette classe étend java.awt.event.EventObject et fournit une description de l'événement capturé. Par exemple, la classe ActionEvent décrit les événements capturés par un ActionListener.

Il y a plusieurs manières d'utiliser les listeners, vous trouverez ces méthodes dans les Q/R suivantes.

Mis à jour le 26 mai 2007 Janitrix

Voici la présentation et quelques explications sur la première possibilité concernant l'utilisation des listeners.

1ère possibilité : implémentation de l'interface dans la classe principale.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.awt.event.ActionListener;  
  
// Étape 1 : déclaration de la classe  
public class MaClasse implements ActionListener {  
	// Étape 3 : Création de deux boutons 
	JButton monBouton = new JButton("Mon Bouton");  
	JButton monBouton2 = new JButton("Mon Bouton2");  
  
	public MaClasse() {  
		// Étape 4 : On ajoute « l'écouteur » sur le bouton « monBouton ».  
		monBouton.addActionListener(this);  
		// Puis sur monBouton2 
		monBouton2.addActionListener(this); 
	}  
  
	/* Étape 2 :Cette méthode est déclarée dans l'interface ActionListener. Il nous faut l'implémenter. */  
	public void actionPerformed(ActionEvent e) {  
                // Étape 2bis 
		if(e.getSource() == monBouton) { 
			// Bouton 1 a été cliqué 
		}else { 
			// Bouton 2 a été cliqué 
		} 
	}  
}
Tout d'abord, à l'étape 1, nous déclarons une classe « MaClasse » qui implémente l'interface ActionListener (nous l'étudierons plus en détail dans une autre Q/R). Puisque nous implémentons l'interface, nous devons également implémenter toutes les méthodes définies dans l'interface.

Le cas de l'interface ActionListener est simple puisqu'elle ne contient qu'une méthode.

Méthode que nous implémentons à l'étape 2 justement.

Nous créons un bouton Swing à l'étape 3.

À l'étape 4, nous ajoutons un « listener » sur les boutons précédemment créés. La méthode addActionListener est définie dans la classe AbstractButton, classe parente de JButton. Cette méthode attend un paramètre de type ActionListener.

La classe MaClasse implémente cette interface, elle peut être justement considérée comme du type ActionListener. Nous pouvons donc fournir l'opérateur 'this' en paramètre, qui représente l'instance en cours de la classe MaClasse.

Concrètement, qu'avons nous fait ? Nous avons demandé aux boutons monBouton et monBouton2 qu'ils nous préviennent lorsqu'un utilisateur les actionne (c'est le rôle du « listener » ActionListener en particulier). Et comment ? En utilisant la méthode actionPerformed, définie dans l'interface ActionListener et surchargée dans la classe MaClasse.

Nous avons deux boutons, mais une seule méthode actionPerformed. Nous devons donc différencier (étape 2bis) la source de l'événement, monBouton ou monBouton2.

La boucle est bouclée.

Mis à jour le 15 novembre 2008 Janitrix

2ème méthode : utilisation des classes anonymes.

Une deuxième possibilité est d'utiliser les classes anonymes. Voici quelques explications, toujours avec un code pour l'exemple.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Étape 1 : déclaration de la classe 
public class MaClasse {  
	// Étape 2 : création de deux boutons.  
	JButton monBouton = new JButton("Mon Bouton");  
	JButton monBouton2 = new JButton("Mon Bouton 2");  
  
	/* Étape 3 : création de la  classe anonyme */  
	monBouton.addActionListener(new ActionListener() {  
		public void actionPerformed(ActionEvent e) {  
			// Cette méthode ne sera appelée que pour les événements sur le bouton monBouton.  
		}  
	});  
  
	/* On refait la même chose pour le deuxième bouton */  
	monBouton2.addActionListener(new ActionListener() {  
		public void actionPerformed(ActionEvent e) {  
			// Cette méthode ne sera appelée que pour les événements sur le bouton monBouton2.  
		}  
	});  
}
Dès le début, nous pouvons remarquer quelques différences avec la première méthode d'utilisation traitée précédemment.

Tout d'abord, notre classe MaClasse n'implémente pas l'interface ActionListener. Aucune instance de la classe MaClasse ne pourra donc être utilisée dans la méthode addActionListener.

Nous créons deux boutons à l'étape 2. L'étape 3 est la plus intéressante. Nous définissons une instance de l'interface ActionListener dans une classe anonyme, sans garder de référence vers cette classe anonyme. Dans ce cas, nous devons le faire deux fois, une fois pour chaque bouton (il faut une classe anonyme pour chaque composant déclenchant un événement).

Un avantage de cette méthode est un code plus léger au niveau de l'implémentation des événements. En effet, nous n'avons pas à dissocier les composants « source » (les composants écoutés par le listener), comme nous le faisons dans la première possibilité.

En contrepartie, nous devons créer une classe anonyme à chaque fois. Une autre possibilité qui est une simple variante de celle présentée ici est la suivante :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Étape 1 : déclaration de la classe 
public class MaClasse {  
	// Étape 2 : création de deux boutons.  
	JButton monBouton = new JButton("Mon Bouton...");  
	JButton monBouton2 = new JButton("Mon Bouton 2...");  
  
	/* Étape 3 : création de la  classe anonyme */  
	ActionListener listener = new ActionListener() {  
		public void actionPerformed(ActionEvent e) {  
			if(e.getSource() == monBouton) { 
				// Bouton 1 a été cliqué 
			}else { 
				// Bouton 2 a été cliqué 
			} 
		}  
	}; 
  
	monBouton.addActionListener(listener);  
	monBouton2.addActionListener(listener);  
}
Ce code est fortement similaire au précédent et mérite donc peu d'explications. La seule subtilité est que nous « sauvegardons » l'instance de la classe anonyme dans une variable, et que nous pouvons donc la réutiliser autant de fois que nécessaire. Cependant, cette façon de faire nous oblige à différencier les composants « source » pour implémenter un comportement différent selon la source.

Mis à jour le 15 novembre 2008 Janitrix

3ème méthode : création d'une classe dédiée.

Code java : Sélectionner tout
1
2
3
4
5
// Fichier : MonListener.java 
public class MonListener implements ActionListener {  
	public void actionPerformed(ActionEvent e) {  
	}  
}
Et dans votre classe principale :

Code java : Sélectionner tout
monButton.addActionListener(new MonListener());
Cette possibilité est très simple, il vous suffit d'implémenter le comportement voulu dans la classe qui implémente le listener, puis vous créez une instance de cette classe que vous passez en paramètre de la méthode addXXXListener située dans votre classe où sont déclarés les composants (boutons, listes, etc.).

Mis à jour le 15 novembre 2008 Janitrix

ActionListener est, comme son nom l'indique, un listener utilisé pour réagir aux actions utilisateurs. Celles-ci sont multiples, la principale étant l'activation d'un bouton (par un clic ou par appui de la touche Entrée lorsque le bouton est sélectionné).

Une seule méthode est déclarée dans cette interface : public void actionPerformed(java.awt.event.ActionEvent e).

La classe ActionEvent étend la classe java.util.EventObject et hérite donc de ses méthodes. Parmi elles, getSource() est particulièrement intéressante. Elle renvoie l'objet concerné par l'événement (par exemple le bouton qui a été cliqué).

Cela nous permettra de différencier les composants sources dans l'implémentation de la méthode actionPerformed.

La classe ActionEvent fournit quant à elle quelques méthodes spécifiques aux événements d'action. Les plus utilisées sont getWhen() et getActionCommand().

getWhen() récupère le timestamp Unix marquant le déclenchement de l'événement, tandis que getActionCommand() retourne le nom de la commande associée à l'événement (par exemple, le texte du bouton à l'origine de l'action).

Voici une simple implémentation d'un ActionListener, utilisant la première méthode d'implémentation proposée :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[...] 
import java.awt.event.*; 
  
// Étape 1 : déclaration de la classe  
public class MaClasse implements ActionListener { 
	// Étape 2 : créations des boutons 
	JButton monBouton = new JButton("Un bouton vivant"); 
	JButton monBouton2 = new JButton("Un bouton vivant2"); 
  
	public MaClasse() { 
		// Étape 3 : on ajoute le listener aux boutons 
		monBouton.addActionListener(this); 
		monBouton.addActionListener(this); 
	} 
  
	// Étape 4 : l'implémentation de l'ActionListener 
	public void actionPerformed(ActionEvent e) { 
		System.out.println("Un bouton a été cliqué, timestamp : " + e.getWhen()); 
  
		// Étape 5 : différenciation de la source d'événement 
		if(e.getSource() == monBouton || e.getActionCommand() == monBouton.getText()) { 
			System.out.println("C'est le bouton 1 !"); 
		}else if(e.getSource() == monBouton2 || e.getActionCommand() == monBouton2.getText()) { 
			System.out.println("C'est le bouton 2 !"); 
		} 
  
	} 
}
Rien de nouveau aux étapes 1, 2, 3, et 4. Vous aurez compris que lorsque l'un des deux boutons est appuyé, la méthode actionPerformed est invoquée.

Cependant, nous avons deux boutons, et un clic sur chacun d'eux invoquera la même implémentation de l'ActionListener. Nous devons donc différencier le bouton source de l'action. Cela peut se réaliser de deux façons : soit on compare le libellé du bouton avec celui de l'action capturée, soit on compare le bouton et l'objet source de l'événement.

Les deux méthodes sont présentées à l'étape 5. Notez que mettre ces deux tests (comparaison de libellés et comparaison de sources) dans une même condition est superflu, un seul des deux tests est nécessaire pour savoir quel bouton a été actionné.

Mis à jour le 26 mai 2007 Janitrix

Le KeyListener est utilisé pour réagir aux événements du clavier, et est donc utilisable sur des composants permettant la saisi de texte (JTextField, JTextArea, etc).

Trois méthodes sont déclarées dans l'interface du KeyListener : keyTyped(KeyEvent e), keyPressed(KeyEvent e) et keyReleased(KeyEvent e). Elle permettent respectivement de réagir lorsqu'une touche a été : tapée (pressée puis relâchée), pressée, relâchée.

La classe KeyEvent étend java.util.EventObject et dispose donc des méthodes déclarées dans cette classe (notamment getSource() ), mais fournit également une dizaine d'autres méthodes spécifiques aux événements relatifs au clavier. Parmi elles : getKeyChar() retourne le caractère associé à la touche appuyée, getKeyCode() récupère le code de la touche pressée, isActionKey() retourne true si la touche appuyée est une touche d'action (CAPS LOCK, Verr Num, etc), et getKeyText(int keyCode) retourne le texte associée à la touche (par ex. F1, A, etc).

La dernière méthode, getKeyText, est statique et ne s'utilise donc pas avec l'instance de KeyEvent fournie.

Les codes retournés par la méthode getKeyCode() sont utiles pour déterminer la touche pressée.

Voici une simple implémentation d'un KeyListener, utilisant la première méthode d'implémentation proposée :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.awt.event.*;  
  
// Étape 1 : on crée la classe et on implémente KeyListener.  
public class MaClasse implements KeyListener {  
  
	// Étape 2 : on crée un composant JTextField  
	private JTextField textField = new JTextField();  
  
	public MaClasse() {  
		// Étape 3 :  on ajoute le listener au composant  
		textField.addKeyListener(this);  
	}  
  
	// Étape 4 : on implémente la méthode keyTyped définie dans l'interface KeyListener  
	public void keyTyped(KeyEvent e) {  
		/* Cette méthode est appelée quand l'utilisateur appuie sur une touche Unicode (donc les caractères) et ne prend pas en compte les touches comme F1, Echap, ALT, etc. */  
		System.out.println(e.getKeyChar());  
	}  
  
	// Étape 5: on implémente la méthode keyPressed définie dans l'interface KeyListener  
	public void keyPressed(KeyEvent e) {  
		/* Cette méthode est appelée quand l'utilisateur appuie sur une touche.  
		Il est conseillé de ne pas utiliser getKeyChar() mais getKeyCode(), car les touches spéciales comme F1 ou Echap ne disposent pas d'un équivalent en Unicode, et donc ne peuvent être représentées en char. */  
	        System.out.println(KeyEvent.getKeyText( e.getKeyCode() );  
		if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {  
			System.out.println("L'utilisateur a appuyé sur Echap");  
		}  
	}  
  
	// Étape 6 : on implémente la méthode keyReleased définie dans l'interface KeyListener  
	public void keyReleased(KeyEvent e) {  
		// Le fonctionnement est le même que pour keyPressed, sauf que cette méthode est appelée quand la touche est relâchée.  
	}  
}
Le code est assez explicite, et les commentaires précisent quelques points obscures. Rien de nouveaux dans ce code, si ce n'est la comparaison entre le code de la touche appuyée et le code de la touche Echap.

Enfin, sachez que si vous trouvez trop lourd de devoir implémenter les trois méthodes alors qu'une seule vous suffit, il existe la classe abstraite java.awt.event.KeyAdapter.

Vous pouvez soit créer une classe qui étendra KeyAdapter, soit faire une classe anonyme.

Exemple :

Code java : Sélectionner tout
1
2
3
4
5
monTextField.addKeyListener( 
		new KeyAdapter() { 
			public void keyTyped(KeyEvent e) { 
			} 
		});

Mis à jour le 26 mai 2007 Janitrix

Le MouseListener est utilisé pour les événements relatifs à la souris (clics, déplacements).

Cinq méthodes sont déclarées dans l'interface MouseListener : mouseClicked(MouseEvent e) prévient des clics (la souris a été pressée puis relâchée), mousePressed(MouseEvent e) pour les pressions sur la souris (donc on enfonce le bouton sans le relâcher), mouseReleased(MouseEvent e) prévient du relâchement d'un bouton de la souris, mouseEntered(MouseEvent e) indique que la souris est entrée dans l'espace d'un composant, mouseExited(MouseEvent e) indique que la souris est sortie de l'espace d'un composant.

La classe MouseEvent étend java.util.EventObject et dispose donc des méthodes déclarées dans cette classe (notamment getSource() ), mais fournit également douze autres méthodes spécifiques aux événements relatifs à la souris, notamment getButton() retourne le bouton qui a été cliqué, getClickCount() retourne le nombre de clics (utile pour gérer le double clic), getLocationOnScreen() retourne un objet Point représentant la position de la souris à l'écran, et enfin isPopupTrigger() précise si le bouton cliqué est celui habituellement utilisé pour afficher la liste déroulante (bouton droit sur le bureau Windows par exemple).

Voici un exemple d'implémentation d'un MouseListener :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class MaClasse implements MouseListener { 
  
	public void mousePressed(MouseEvent e) { 
		// Cette méthode est appelée quand l'utilisateur appuie le bouton sur le composant écouté 
	} 
  
	public void mouseReleased(MouseEvent e) { 
		// Cette méthode est appelée quand l'utilisateur relâche le bouton sur le composant écouté 
	} 
  
	public void mouseClicked(MouseEvent e) { 
		// Cette méthode est appelée quand l'utilisateur a cliqué (appuyé puis relâché) sur le composant écouté 
		if(e.getClickCount() == 2) { 
			System.out.println("Il y a eu un double clic"); 
		} 
  
		Point p = e.getLocationOnScreen(); 
  
		System.out.println("La souris est aux coordonnées : x=" + p.getX() + ";y=" + p.getY() + " de l'écran."); 
	} 
  
	public void mouseEntered(MouseEvent e) { 
		// Cette méthode est appelée quand la souris entre dans la zone du composant écouté 
		System.out.println("La souris vient d'entrer..."); 
	} 
  
	public void mouseExited(MouseEvent e) { 
		// Cette méthode est appelée quand la souris sort de la zone du composant écouté 
		System.out.println("La souris vient de sortir... rattrapez là :)"); 
	} 
}
Il est fort probable que seules quelques-unes de ces méthodes vous intéressent, il vous semblera donc lourd d'implémenter chacune des méthodes.

Il existe donc une classe abstraite MouseAdapter qui vous permet d'implémenter seulement les méthodes qui vous intéressent.

Exemple :

Code java : Sélectionner tout
1
2
3
4
monPanel.addMouseListener(new MouseAdapter() { 
	public void mouseClicked(MouseEvent e) { 
	} 
}

Mis à jour le 26 mai 2007 Janitrix

Le WindowListener est utilisé pour les événements relatifs aux fenêtres (activation, fermeture, ouverture, etc.).

Cette interface déclare sept méthodes : windowActivated(WindowEvent e) indique que la fenêtre a été activée, windowDeactivated(WindowEvent e) indique que la fenêtre n'est plus la fenêtre active, windowClosed(WindowEvent e) indique que la fenêtre a été fermeé, windowClosing(WindowEvent e) indique que l'utilisateur a demandé la fermeture de la fenêtre, windowOpened(WindowEvent e) est appelée la première fois que la fenêtre est rendue visible, windowIconified(WindowEvent e) indique que la fenêtre a été réduite dans la barre de tâche, windowDeiconified(WindowEvent e) indique que la fenêtre a été restaurée depuis la barre de tâche.

La classe WindowEvent étend java.util.EventObject et dispose donc des méthodes déclarées dans cette classe (notamment getSource() ), mais fournit également cinq autres méthodes spécifiques aux événements relatifs aux fenêtres, notamment getNewState() et getOldState() qui fournissent respectivement le nouvel état et l'ancien état de la fenêtre, mais aussi getWindow(), qui retourne la fenêtre source de l'événement.

Afin d'ajouter un WindowListener sur une fenêtre, vous disposez de la méthode addWindowListener(WindowListener) de la classe Window (étendue par la classe JFrame notamment).

Voici un exemple d'implémentation d'un WindowListener :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class MaClasse implements WindowListener { 
  
	// [...] 
  
        public MaClass() { 
             maFenetre.addWindowListener(this); 
        } 
  
	public void windowOpened(WindowEvent e) { 
		System.out.println("On vient de m'ouvrir !"); 
	} 
  
	public void windowClosed(WindowEvent e) { 
		System.out.println("On m'a fermé !") 
	} 
	public void windowClosing(WindowEvent e) { 
		System.out.println("On veut me fermer !"); 
	} 
  
	public void windowIconified(WindowEvent e) { 
		System.out.println("Je suis réduite à une icône !"); 
	} 
  
	public void windowDeiconified(WindowEvent e) { 
		System.out.println("Je suis restaurée !"); 
	} 
  
	public void windowActivated(WindowEvent e) { 
		System.out.println("Je suis activée"); 
	} 
  
	public void windowDeactivated(WindowEvent e) { 
		System.out.println("Je suis désactivée"); 
	} 
  
}
Les méthodes sont nombreuses mais bien spécifiques. Il existe encore une fois une classe Adapter qui vous permet de n'implémenter que les méthodes qui vous intéressent : WindowAdapter.

Mis à jour le 12 janvier 2008 Janitrix

Le FocusListener est utilisé pour les événements relatifs au focus clavier.

Cette interface déclare deux méthodes : focusGained(FocusEvent e) indique que le composant a gagné le focus clavier tandis que focusLost(FocusEvent e) indique que le composant a perdu le focus clavier.

La classe FocusEvent étend java.util.EventObject et dispose donc des méthodes déclarées dans cette classe (notamment getSource() ), mais fournit également trois autres méthodes spécifiques aux événements relatifs aux fenêtres, notamment isTemporary() qui indique si le composant n'a le focus que temporairement, et getOppositeComponent() qui retourne l'autre composant impliqué dans le changement de focus.

Afin d'ajouter un FocusListener, vous disposez de la méthode addFocusListener(FocusListener) de la classe Component.

Voici un exemple d'implémentation d'un FocusListener :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
public class MaClasse implements FocusListener { 
     public MaClasse() { 
         monComposant.addFocusListener(this); 
     } 
  
     public void focusGained(FocusEvent e) { 
          System.out.println("On a gagné le focus"); 
     } 
  
     public void focusLost(FocusEvent e) { 
         System.out.println("On a perdu le focus"); 
     } 
}

Mis à jour le 12 janvier 2008 Janitrix

Le ItemListener est utilisé pour les évènements relatifs aux éléments (liste, checkbox, etc.).

Cette interface déclare une seule méthode : itemStateChanged(ItemEvent e) qui indique que l'élément a changé d'état.

La classe ItemEvent étend java.util.EventObject et dispose donc des méthodes déclarées dans cette classe (notamment getSource() ), mais fournit également quatre autres méthodes spécifiques aux événements relatifs aux fenêtres, notamment getItem() qui retourne l'élément affecté par l'événement, getStateChange() retourne le nouvel état de l'élément (sélectionné ou désélectionné), et getItemSelectable() qui retourne le composant originaire de l'événement.

Afin d'ajouter un ItemListener sur les composants qui le permettent (les boutons, JcomboxBox, les listes, etc), vous disposez de la méthode addItemListener(ItemListener).

Voici un exemple d'implémentation d'un ItemListener :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MaFrame extends JFrame implements ItemListener { 
	private JComboBox choix; 
  
	// [...] 
  
        public MaFrame() { 
            choix = new JComboBox(); 
            choix.addItemListener(this); 
        } 
  
	public void itemStateChanged(ItemEvent e) { 
		if(e.getStateChange() == ItemEvent.SELECTED) { 
			System.out.println("Un nouveau choix est sélectionné*: " + e.getItem().toString()); 
		}else if(e.getStateChange() == ItemEvent.DESELECTED) { 
			System.out.println("*Un choix est désélectionné*: " + e.getItem().toString()); 
		} 
	} 
}
Nous effectuons un test afin de savoir l'état de l'élément affecté par l'événement. En effet, deux états sont possibles : ItemEvent.ITEM_SELECTED et ItemEvent.DESELECTED. Il faut bien comprendre que la méthode itemStateChanged est invoquée deux fois : une fois pour l'élément qui vient d'être désélectionné et une fois pour celui qui vient d'être sélectionné (ceci est vrai dans le cas d'une JComboBox par exemple). Il est donc important de faire la différence, sous peine de voir son code exécuté deux fois.

Mis à jour le 12 janvier 2008 Janitrix

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.