Les Interfaces Graphiques 27 Février 2009 Patrick Reuter Maître de conférences LaBRI/INRIA, Université Bordeaux 2 http://www.labri.fr/perso/preuter/ig/ 1/3/2007 1
Interface Utilisateur Les interfaces graphiques et les périphériques matériels permettent l'interactivité entre un programme (composé d'un ensemble de fonctions), et un utilisateur.
Avant…
Avant …
Maintenant …
GUI : Interface Graphique Utilisateur GUI : Graphical user Interface (WIMP : Window Icon Menu Pointer) p.ex. Gnome, kde, linux, Macos X, Win* Photo : gimp
GUI : Interface Graphique Utilisateur But : Permettre une interactivité avec un programme de manière « plus simple » et plus intuitive. Elle repose sur trois parties : les entrées, les sorties, le lien
GUI : Interface Graphique Utilisateur Les entrées : récupération des informations auprès de l'utilisateur frappe au clavier, déplacement de la souris, widget, etc. Les sorties : l'affichage des données et de l'état du système. Fenetre, bouton, menu, widget Le lien: entre les actions de l'utilisateur et les actions effectives sur le coeur du programme. Ouvrir un fichier, met le fichier en mémoire
Programmation évènementielle La programmation événementielle est un concept différent de la programmation fonctionnelle ou impérative Il s’agit de permettre une interaction non-linéaire, plusieurs événements peuvent être produits avec un ordre différent. exécution choix Programmation fonctionnelle Programmation évènementielle
Programmation évènementielle Les composants d’une applications événementielle interagissent entre eux et avec l’environnement. Il communiquent en réponse à des événements. Les événements sont captés par le système et sont transmis aux « écouteurs » (listener). C’est vous qui mettez en place les « écouteurs ».(implements)
Programmation évènementielle Pour réaliser des interfaces, il est impératif de programmer de manière evénementielle et donc de prévoir les évènements. Dans ce but, vous devez connaître les capacités de votre interface et les événements qu’elle peut générer.
Comment Concevoir un programme ? Séparez les classes de la gestion du modèle et celle de l’interface graphique Java (Swing) View Événement (souris, clavier, etc.) Control Routines de communication Model Java P.ex. base de données,
Modèle-Vue-Contrôleur (MVC) Motif de conception pour le développement d'applications logicielles qui sépare le modèle de données, l'interface utilisateur et la logique de contrôle. Ce motif a été mis au point en 1979 par Trygye Reenskang, qui travaillait alors sur Smalltalk dans les laboratoires de recherche Xerox PARC.
Modèle-Vue-Contrôleur (MVC) la Vue : correspond à l'interface avec laquelle l'utilisateur interagit. Les résultats renvoyés par le modèle sont dénués de toute présentation mais sont présentés par les vues. Plusieurs vues peuvent afficher les informations d'un même modèle. La vue n'effectue aucun traitement, elle se contente d'afficher les résultats des traitements effectués par le modèle, et de permettre à l'utilisateur d'interagir avec elles.
Modèle-Vue-Contrôleur (MVC) Le Modèle : représente le comportement de l'application : traitements des données, interactions avec la base de données, etc. Il décrit les données manipulées par l'application et définit les méthodes d'accès.
Modèle-Vue-Contrôleur (MVC) le Contrôleur : prend en charge la gestion des événements de synchronisation pour mettre à jour la vue ou le modèle Il n'effectue aucun traitement, ne modifie aucune donnée, il analyse la requête du client et se contente d'appeler le modèle adéquat et de renvoyer la vue correspondant à la demande Routines de communication
Modèle-Vue-Contrôleur (MVC) Résumé : lorsqu'un client envoie une requête à l'application: celle-ci est analysée par le contrôleur ce contrôleur demande au modèle approprié d'effectuer les traitements, puis renvoie la vue adaptée
Concevoir une interface Control Routines de communication Vue Modèle Il faut connaître le modèle et son fonctionnement Définir le contrôle que l’on veut faire (ouvrir, fermer, afficher, etc.) sur le modèle Faire un croquis de l’interface pour définir les widgets (menu, bouton, label, etc.) à utiliser et leurs caractéristiques (nom, position, etc.)
Interface Graphique avec Java JAVA, langage de programmation de SUN utilise deux bibliothèques pour vous aider à développer des interfaces graphiques : AWT (ne s'utilise plus) SWING Buttons Spinner Menu
SWING The Jfc Swing Tutorial: A Guide to Constructing Guis (31 mars 2004) de Kathy Walrath, et al prix : EUR 59,19 Documentation en ligne : http://java.sun.com/docs/books/tutorial/uiswing/mini/index.html Frame
import java.awt.event.*; SWING SWING est en sus de AWT, mais en réutilise quelques parties. Il est inclu dans le SDK (software Development Kit) de JAVA depuis la version 1.2. SWING est contenu dans le package : javax.swing. import javax.swing. import java.awt.*; import java.awt.event.*; SWING est indépendant du système d'exploitation (Mac, Windows, Linux, …) on garde donc une portabilité des programmes.
Interface Graphique avec Java Les applications SWING se développent de la même manière que toutes les applications JAVA en utilisant les classes de la bibliothèque SWING: objets, classes, héritages Programmer une interface n'est pas donc pas différent que programmer un ensemble de classe comme la classe « Cercle », p.ex.
Concevoir l’interface: 1ère partie (Vue)
Concevoir l’interface: 1ère partie (Vue) Java (Swing) Vue Événement (souris, clavier, etc.) Routines de communication Control Modèle Java
Interface Graphique avec Java import java.awt.*; import javax.swing.*; public class FenetreView extends JFrame { public FenetreView(String nom) { super(nom); Container pan = this.getContentPane(); pan.setLayout(new GridBagLayout()); JLabel label; label = new JLabel("Hello ESTIA"); pan.add(label); this.pack(); this.setVisible(true); } public static void main(String s[]) FenetreView f = new FenetreView("simple"); FenetreView.java 1) Écrire le code java 2) compilation 3) Exécution
Interface Graphique avec Java import java.awt.*; import javax.swing.*; public class FenetreView extends JFrame { public FenetreView(String nom) { super(nom); Container pan = this.getContentPane(); pan.setLayout(new GridBagLayout()); JLabel label; label = new JLabel("Hello ESTIA"); pan.add(label); this.pack(); this.setVisible(true); } public static void main(String s[]) FenetreView f = new FenetreView("simple"); FenetreView.java 1) Écrire le code java Importation Constructeur Instanciation de l’objet
SWING : création Elle se fait principalement en 5 étapes : JFrame 1. Création d’une fenêtre (par héritage) 2. Récupération du container 3. Modification du Layout 4. Insertion des widgets dans le conteneur 5. Arranger les composantes Container Layout Widget
SWING: étape 1 Création de la fenêtre par l’héritage de JFrame import java.awt.*; import javax.swing.*; public class FenetreView extends JFrame { public FenetreView(String nom) { super(nom); Container pan = this.getContentPane(); pan.setLayout(new GridBagLayout()); JLabel label; label = new JLabel("Hello ESTIA"); pan.add(label); this.pack(); this.setVisible(true); } public static void main(String s[]) FenetreView f = new FenetreView("simple"); Création de la fenêtre par l’héritage de JFrame JFrame Layout Container Container Widget
SWING : JFrame JFrame est un composant de haut niveau, il contiendra toute l’application, c’est la première brique de l’interface. Pour l’utiliser et simplifier le code, on implémente une nouvelle classe qui hérite de JFrame. Une JFrame possède un conteneur par défaut. Pour hériter de JFrame : - on crée une nouvelle classe (ici Fenetre) qui hérite (extends) de JFrame. - Toujours créer un constructeur pour pouvoir insérer les éléments dans cette fenêtre.
Composants SWING (1/4) Frame Applet Dialog JFrame Container Container Layout Frame Applet Dialog Widget
SWING: étape 1 Appel du constucteur de la classe mère import java.awt.*; import javax.swing.*; public class FenetreView extends JFrame { public FenetreView(String nom) { super(nom); Container pan = this.getContentPane(); pan.setLayout(new GridBagLayout()); JLabel label; label = new JLabel("Hello ESTIA"); pan.add(label); this.pack(); this.setVisible(true); } public static void main(String s[]) FenetreView f = new FenetreView("simple"); Appel du constucteur de la classe mère JFrame Layout Container Container Widget
SWING : création Elle se fait principalement en 5 étapes : JFrame 1. Création d’une fenêtre (par héritage) 2. Récupération du container 3. Modification du Layout 4. Insertion des widgets dans le conteneur 5. Arranger les composantes Container Layout Widget
SWING: étape 2 Extraction du “container” de la fenetre (JFrame) import java.awt.*; import javax.swing.*; public class FenetreView extends JFrame { public FenetreView(String nom) { super(nom); Container pan = this.getContentPane(); pan.setLayout(new GridBagLayout()); JLabel label; label = new JLabel("Hello ESTIA"); pan.add(label); this.pack(); this.setVisible(true); } public static void main(String s[]) FenetreView f = new FenetreView("simple"); Extraction du “container” de la fenetre (JFrame) JFrame Layout Container Container Widget
SWING : Conteneur Layout Container Container Le conteneur est l’objet en Java qui permet d’afficher plusieurs objets graphiques. On peut insérer un ou plusieurs objets dans un même conteneur. Les objets sont placés dans le conteneur suivant les règles imposées par le layout (voir suite). Par la suite, pour réaliser des interfaces plus complexes, on insère des conteneurs dans d’autres conteneurs pour spécifier plusieurs politiques de placement. Les conteneurs les plus souvent utilisés sont les JPanels.
SWING : JPanel Le panneau est un conteneur intermédiaire invisible. Il a pour finalité de positionner d’après son “layout” les composants, boutons et les labels (JScrollPane, JTabbedPane). Son layout par défaut est un FlowLayout. Classe JPanel : déclaration et instanciation : JPanel panel = new JPanel();
Composants SWING (2/4) Panel Tabbed pane Split pane Scroll pane JFrame Container Container Panel Tabbed pane Layout Widget Split pane Scroll pane Tool bar
SWING : création Elle se fait principalement en 5 étapes : JFrame 1. Création d’une fenêtre (par héritage) 2. Récupération du container 3. Modification du Layout 4. Insertion des widgets dans le conteneur 5. Arranger les composantes Container Layout Widget
SWING: étape 3 Mise en place d’un gestionnaire de placement : import java.awt.*; import javax.swing.*; public class FenetreView extends JFrame { public FenetreView(String nom) { super(nom); Container pan = this.getContentPane(); pan.setLayout(new GridBagLayout()); JLabel label; label = new JLabel("Hello ESTIA"); pan.add(label); this.pack(); this.setVisible(true); } public static void main(String s[]) FenetreView f = new FenetreView("simple"); Mise en place d’un gestionnaire de placement : JFrame Layout Container Container Widget
SWING : Layout Les « layout » permettent de positionner les élèments avec une politique de placement des objets. Les layouts sont toujours liès aux conteneurs (JPanels, Tabbed pane).
Composants SWING (3/4) JFrame Container Container Layout Widget
SWING : Layout Il sont par défaut dans tous les composants (JFrame, JPanel). Il existe 7 types : FlowLayout, BorderLayout, GridLayout, BoxLayout, GridBagLayout, SpringLayout et le CardLayout. Chaque layout est une classe Java : Pour créer un layout : déclaration puis instanciation FlowLayout flo = new FlowLayout(); Les composants utilisent souvent par défaut un BorderLayout (JFrame, JDialog, JApplet). Les Layouts sont utilisés surtout avec les panneaux (JPanel) et les fenêtres : On peut affecter un layout dans un panneau au moment de l’instanciation : JPanel panel = new JPanel(new BorderLayout()); Affectation d'un layout dans le conteneur d’une fenêtre "frame": Container pan = frame.getContentPane(); pan.setLayout(new FlowLayout());
SWING : Layout Le même code donnera des résultats différents suivant le Layout utilisé. import java.awt.*; import javax.swing.*; public class JPanel5Boutons extends JPanel { private static String [] layout={"BoxLayout","GridLayout","GridBagLayout", "FlowLayout","BorderLayout","SpringLayout","CardLayout"}; public JPanel5Boutons(String type) { super(); int i=0; int nbLayout = 7; String [] text={"Button 1","Button 2","Button 3","Long-Named Button 4","Button 5"}; for(i=0; i < 7; i++) if(type.equals(layout[i])) nbLayout = i+1; switch(nbLayout) case 1: System.out.println("création avec BoxLayout"); setLayout(new BoxLayout(this,BoxLayout.Y_AXIS)); break; case 2: System.out.println("création avec GridLayout"); setLayout(new GridLayout(2,3)); case 3: System.out.println("création avec GridBagLayout"); GridBagLayout g = new GridBagLayout(); setLayout(g); case 4: System.out.println("création avec FlowLayout"); setLayout(new FlowLayout()); case 5: System.out.println("création avec BorderLayout"); setLayout(new BorderLayout()); case 6: System.out.println("création avec SpringLayout"); setLayout(new SpringLayout()); break; case 7: System.out.println("création avec CardLayout"); setLayout( new CardLayout(5,3)); for(i=0; i < 5; i++) { JButton button = new JButton(text[i]); add(button,text[i]); } default: System.out.println("Type non reconnu : " + type); if(nbLayout!=7) add(button); public static void main(String[] args) { JFrame.setDefaultLookAndFeelDecorated(true); //Create seven windows. for(int i=0; i < 7; i++) JFrame frame = new JFrame(layout[i]); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Set up the content pane. frame.setContentPane(new JPanel5Boutons(layout[i])); //Display the window. frame.pack(); frame.setVisible(true);
SWING : BorderLayout Le BorderLayout possède 5 zones déterminées par les points cardinaux (north, south, east, west) et le centre (center).
SWING : BoxLayout Il positionne tous les composants sur une colonne ou une ligne. Il aligne les composants et respecte la taille maximun.
SWING : FlowLayout C'est le « layout » par défaut des « JPanel ». Les composants sont insérerés de gauche à droite. Si la largeur est trop petite, il passe à la ligne suivante.
SWING : GridLayout Il positionne les composants dans une grille (ligne, colonne) et adapte la taille des boutons au plus grand composant.
SWING : création Elle se fait principalement en 5 étapes : JFrame 1. Création d’une fenêtre (par héritage) 2. Récupération du container 3. Modification du Layout 4. Insertion des widgets dans le conteneur 5. Arranger les composantes Container Layout Widget
SWING: étape 4 import java.awt.*; import javax.swing.*; public class FenetreView extends JFrame { public FenetreView(String nom) { super(nom); Container pan = this.getContentPane(); pan.setLayout(new GridBagLayout()); JLabel label; label = new JLabel("Hello ESTIA"); pan.add(label); this.pack(); this.setVisible(true); } public static void main(String s[]) FenetreView f = new FenetreView("simple"); Insertion d’un widget dans le panneau avec la politique définie par le layout: JFrame Layout Container Container Widget
Composants SWING (4/4) List Buttons Combo box Spinner Text field JFrame Buttons Combo box Container Container List Layout Widget Menu Slider Spinner Text field
SWING : création Elle se fait principalement en 5 étapes : JFrame 1. Création d’une fenêtre (par héritage) 2. Récupération du container 3. Modification du Layout 4. Insertion des widgets dans le conteneur 5. Arranger les composantes Container Layout Widget
SWING: étape 5 import java.awt.*; import javax.swing.*; public class FenetreView extends JFrame { public FenetreView(String nom) { super(nom); Container pan = this.getContentPane(); pan.setLayout(new GridBagLayout()); JLabel label; label = new JLabel("Hello ESTIA"); pan.add(label); this.pack(); this.setVisible(true); } public static void main(String s[]) FenetreView f = new FenetreView("simple"); Insertion d’un widget dans le panneau avec la politique définit par le layout: JFrame Layout Container Container Widget Arranger les composantes
Arranger les composantes Pourquoi cette étape ? Seulement quand SWING connaît toutes les composantes de la mise en page, les positions peuvent être attribué Compatibilité avec les différentes résolution d’écran PC PC portable PDA Téléphone portable ..
Arranger les composantes Egalement possible : JLabel titreLabel = new JLabel("Space Invaders"); titreLabel.setLocation(10,10); pan.add(titreLabel);
Swing Swing est un boîte d’outils de IG pour Java. Est partie des Java Foundation Classes (JFC). Swing inclues une IG (Graphical User Interface (GUI)) et des Widgets comme boutons, menu, … « Swing supports pluggable look and feel – not by using the native platform's facilities, but by roughly emulating them. This means you can get any supported look and feel on any platform. The disadvantage of lightweight components is slower execution. The advantage is uniform behavior on all platforms. »
SWING: mise en page plus complexe import java.awt.*; import javax.swing.*; public class FenetreView extends JFrame { public FenetreView(String nom) { super(nom); Container pan = this.getContentPane(); pan.setLayout(new GridBagLayout()); JPanel pan1 = new JPanel(); pan1.setLayout(new BoxLayout(pan1,BoxLayout.Y_AXIS)); JPanel pan2 = new JPanel(); pan2.setLayout(new BoxLayout(pan2,BoxLayout.X_AXIS)); JButton button1 = new JButton("bouton 1"); JButton button2 = new JButton("bouton 2"); JButton button3 = new JButton("bouton 3"); JButton button4 = new JButton("bouton 4"); pan1.add(button1); pan1.add(button2); button2.setText("nouveau nom"); pan2.add(button3); pan2.add(button4); pan.add(pan1); pan.add(pan2); this.pack(); this.setVisible(true); } pan pan1 pan2
Concevoir l’interface: 2ème partie (Event)
Concevoir un programme : 2 partie Vue Événement (souris, clavier, etc.) Routines de communication Control Model
L’événement et l’action Les évènements sont les interventions de l’utilisateurs sur l’interface graphique à l’aide des périphériques (par exemple : clavier, souris) Frappe au clavier Clic de souris Mouvement de la souris L’action est la traduction par un composant (widget, bouton) de l’évènement. Elle peut être traitée ou pas par le programme. Swing propose des interfaces (au sens Génie logiciel) à implémenter pour traiter les évènements en fonction des composants. C’est vous qui choisissez les événements à traiter…
L’évènement et l’action Exemple pour un Bouton : Evènement : appuyer sur le bouton (géré par Swing) Evènement : appuyer sur le bouton (géré par Swing) Action : actionPerformed Action : aucune Après action sur le bouton Après action sur le bouton Traitement : Changement de nom (géré par le programmeur) Chaque bouton a « son » action !!
Gestion des événements Après avoir créé la partie visible de l’interface (Vue), il faut lier les actions réalisées avec le modèle. Il faut gérer les évènements (souris, clavier, etc.) : - les « intercepter » : lier une action à un composant (bouton, list, tableau, etc.) - les « interpréter » : implémenter l’interface correspondant Avec Swing, vous devez implémenter une interface pour chaque signal. Par exemple pour actionner un bouton : l'interface est ActionListener dont la seule méthode est actionPerformed. Rappel : Utilisation du mot clef « implements », et vous devez implémenter toutes les méthodes de l'interface.
Evénement et leurs “écouteurs” (listener) associés Liste des interfaces Evénement et leurs “écouteurs” (listener) associés Interface écouteur Evénement méthode MouseListener L’utilisateur a relaché le bouton de la souris mouseReleased Le pointeur de la souris est entré dans le composant mouseEntered Le pointeur de la souris est sorti du composant mouseExited Clic complet de la souris (pression et relachement sans mouvement entre les deux) mouseClicked L’utilisateur a appuyer sur un bouton de la souris mousePressed ActionListener Utilisateur clique sur un bouton, presse “enter” dans un champ texte ou sélectionne un champ dans un menu actionPerfomed KeyListener Utilisateur clique sur une touche Utilisateur relâche une touche keyPressed keyReleased Autres interfaces écouteurs : ItemListener, TextListener, MouseMotionListener, WindowListener
Concevoir une interface : 2 partie Nous voulons réaliser une fenêtre avec un bouton, qui affiche « bonjour » sur la sortie standard. Evènement : bouton enfoncé Action : afficher le message à l’écran Modèle : aucun
Gestion des événements Gestion de l’action sur un bouton : 1) Création du bouton : JButton button; button = new JButton("Click Me"); 2) On attache la gestion de l’événement (Listener Type) à ce bouton (cf Tableau précédent) : button.addActionListener(new FenetreEvent()); bouton.addActionListener(…..); // syntaxe addXXX(); où XXX est l’interface écouteur 3) Implémentation de l'interface : public class MyClass implements ActionListener Une classe portant le nom de l'évènement implémente la classe liée (Implements ActionListener) (plus propre et « Génie logiciel »)
Gestion des événements : 2e méthode Le traitement de l’action est gérée par une classe qui hérite de l’interface. !! La difficulté de cette technique réside dans le passage d’argument.
Gestion des événements : 2e méthode Création de la classe FenetreEvent qui implémente l'interface ActionListener On implémente l'interface ActionListener import java.awt.*; import java.awt.event.*; import javax.swing.*; class FenetreEvent implements ActionListener { public FenetreEvent () { System.out.println("My action Event : appel constructeur"); } public void actionPerformed(ActionEvent e) System.out.println("ActionCommand ::: " + e.getActionCommand() + ":::: reçu"); On code l'action de la Méthode actionPerformed
Gestion des événements : 2e méthode Création de la classe FrameBase, fenêtre principale contenant tous les objets, l'appel à l'affichage et la fonction “main” import java.awt.*; import javax.swing.*; public class FenetreView extends JFrame { public FenetreView(String nom) { super(nom); Container pan = this.getContentPane(); pan.setLayout(new GridBagLayout()); JLabel label; label = new JLabel("Hello ESTIA"); pan.add(label); JButton button; button = new JButton("Click Me"); button.addActionListener(new FenetreEvent()); pan.add(button); this.pack(); this.setVisible(true); } public static void main(String s[]) FenetreView f = new Fenetre("simple"); On attache l'écouteur au bouton
Concevoir l’interface: 3ème partie (Control)
Concevoir l’interface: 3ème partie (Control) Vue Événement (souris, clavier, etc.) Routines de communication Control Model
Concevoir l’interface: 3ème partie (Control) traitement évènement Vue Control Affiche bonjour à l’écran Modèle
Utillisation d’un Controleur Le modèle MVC permet d’avoir une séparation plus importante entre le modèle et l’interface et facilite la gestion des événements. Le controleur permet de gérer des programmes plus complexes de manière plus simple. Il connaît l’état de tous les éléments de l’application à tous moments, il peut être assimilé à un « superviseur ».
Exemple en UML : Fenêtre de login ActionListener LoginEvent LoginController LoginController _loginController; LoginModel _loginModel; LoginView_loginView; + LoginEvent(LoginController lc); + actionPerformed(ActionEvent e); + LoginController(); + void start(); + void boutonValider(); LoginModel String _nomFichier; JFrame + LoginModel(String nomFichier); + boolean estValide(String login, String mdp); LoginView JTextField _login; JPasswordField _ + LoginView(LoginController lc); + getLogin(); + getPassword(); + void afficherMessage(String msg); + void afficher(); LoginRun + void main(String[] args);
Concevoir l’interface: 4ème partie (Model)
Concevoir l’interface: 4ème partie (Model) Modèle Le modèle est un programme classique en java qui ne doit contenir aucun appel à la bibliothèque de swing. Il doit pouvoir être utilisable sans interface graphique. Par exemple, la gestion d’un stock, on crée toutes les méthode permettant de gérer le stock (ajouter, enlever, compter, etc.) : - On peut l’utiliser dans une fonction main classique - Ou l’utiliser via une interface
Concevoir une interface traitement évènement Modèle Vue Control -Vous devez respecter la séparation de chaque partie (surtout ne pas mettre de code de la biliothèque Java-Swing dans le modèle) -Vous devez garder une cohérence dans l’interface graphique (c-à-d bon positionnement des widgets, ne pas faire un bouton « ouvrir » qui ferme l’application ;-) )
Conventions Pour la lisibilité, utilisez toujours l'indentation. Pour chaque exercice, créer un nouveau répertoire avec le nom exerciceX.Y qui contiendra les fichiers .java nécessaires. Chaque fichier qui utilise la bibliothèque SWING doit faire les importations suivantes import javax.swing.*; import java.awt.*; import java.awt.event.*; Choisissez des noms des classes avec des lettres en majuscule, des noms de variables avec des lettres en miniscules. Dans un fichier, vous allez définir une seule classe. Le nom de ce fichier sera le nom de la classe suivi de l'extension.java N'utilisez jamais des caractères spéciaux ni des accents dans vos noms de fichiers/classes/variables.
Conventions En utilisant le concept MVC, rajouter au nom de la classe le mot {View} s'il s'agit d'une classe qui s'occupe de la vue, le mot Model s'il s'agit d'une classe Modèle, le mot Control s'il s'agit d'une classe Control (= Action), et le mot Event s'il s'agit d'une classe qui implémente un écouteur, ainsi que le mot Run s'il s'agit d'une classe contenant la méthode main. Pour chaque nouvelle classe de Java SWING que vous utilisez (comme par exemple JFrame, JButton, ...), consultez systématiquement son manuel afin de découvrir ses possibilités http:://java.sun.com/j2se/1.5.0/docs/api/index.html
Pièges à éviter Attention nom du fichier = nom de la classe Une classe --- Un fichier Attention à la casse