Création interface graphique avec Swing : les bases


précédentsommairesuivant

5. Ajouter des boutons dans la fenêtre

La principale fonctionnalité d'une application graphique est la programmation événementielle, c'est-à-dire le fait que l'utilisateur puisse déclencher des événements et réagir à ce qui se passe dans la fenêtre. Au contraire d'un programme en mode console, dans lequel le programme régit les actions de l'utilisateur à sa guise.

Pour que l'utilisateur puisse interagir avec le programme, on dispose par exemple, des boutons. Vous allez donc apprendre dans ce chapitre, à vous en servir.

Mais qu'est-ce qu'un bouton ? C'est tout simplement un élément graphique sur lequel l'utilisateur peut cliquer pour déclencher une action. Le bouton ne fait rien tant que l'utilisateur n'a pas cliqué dessus.

Le composant pour créer un bouton est le JButton. On va créer une fenêtre qui comprendra deux boutons.

On va reprendre le code de la classe FenetreTexte (renommé en FenetreBoutons) et l'on va juste s'occuper de la méthode buildContentPane() pour ajouter 2 boutons à la fenêtre :

 
Sélectionnez
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
 
public class FenetreAvecBouton extends JFrame{
	private JPanel buildContentPane(){
		JPanel panel = new JPanel();
		panel.setLayout(new FlowLayout());
 
		JButton bouton = new JButton("Cliquez ici !");
		panel.add(bouton);
 
		JButton bouton2 = new JButton("Ou  !");
		panel.add(bouton2);
 
		return panel;
	}
}

Vous devriez donc avoir un affichage comme celui-ci :

Utilisation de boutons
Utilisation de boutons

C'est bien beau, vous me direz, mais le bouton ne fait rien... C'est normal, on va devoir lui attribuer une action. Nous verrons cela au chapitre qui suit.

5.1. Attribuer une action à un bouton

On va maintenant apprendre à attribuer une action à un bouton. C'est-à-dire indiquer ce qui va devoir se passer en cas de clic.

Le fonctionnement des actions en Swing suit toujours le même principe, celui des évênements et des écouteurs. Donc lors du clic sur un bouton, on aura donc un événement (ActionEvent dans ce cas) qui sera envoyé à tous les écouteurs du bouton. Donc si on veut savoir quand se passe l'action d'un bouton, il faut mettre un écouteur sur ce bouton et réagir en cas d'événement.

Il y a 2 façons de faire avec un bouton :

  • Utiliser une classe qui implémente ActionListener et écouter le bouton : Cette méthode est toute simple. Il faut avoir une classe implémentant ActionListener et l'ajouter comme écouteur aux boutons. Ensuite, à chaque clic, la méthode actionPerformed va être appelée et il faudra tester le bouton qui a envoyé l'événement, ce qui n'est pas très pratique avec un grand nombre de boutons.
  • Utiliser une AbstractAction : Cette classe représente une action de Swing. On peut lui donner un texte et une icône et on peut évidemment lui dire que faire en cas de clic dans la méthode actionPerformed. Personnellement, je préfère cette méthode qui permet de bien séparer l'action du composant graphique, mais c'est un choix personnel.

On va maintenant essayer les 2 techniques.

Code complet : FenetreBoutons

5.1.1. ActionListener

On va reprendre la classe FenetreBoutons et la renommer FenetreBoutonsListener.

On va commencer par la méthode à base d'ActionListener. La première chose à faire est de dire que la FenetreBoutonsListener est un listener d'actions. Comment faire ça ? Tout simplement en implémentant l'interface ActionListener et en redéfinissant la méthode actionPerformed :

 
Sélectionnez
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
 
public class FenetreBoutonsListener extends JFrame implements ActionListener{
	//...
 
	private JPanel buildContentPane(){
		JPanel panel = new JPane();
		panel.setLayout(new FlowLayout());
 
		JButton bouton = new JButton("Cliquez ici !");
		panel.add(bouton);
 
		JButton bouton2 = new JButton("Ou  !");
		panel.add(bouton2);
 
		return panel;
	}
 
	public void actionPerformed(ActionEvent e) {
 
	}
}

Ensuite, on va dire aux boutons que la fenêtre va écouter leurs actions :

 
Sélectionnez
JButton bouton = new JButton("Cliquez ici !");
bouton.addActionListener(this);
panel.add(bouton);
 
JButton bouton2 = new JButton("Ou  !");
bouton2.addActionListener(this);
panel.add(bouton2);

On a donc ajouté un écouteur au bouton avec la méthode addActionListener. Maintenant à chaque fois qu'on va cliquer sur un bouton, là méthode actionPerformed va être appelée. Vous pouvez vérifier en ajoutant cela dans la méthode actionPerformed :

 
Sélectionnez
System.out.println("Clic");

Vous verrez donc apparaître "Clic" dans la console à chaque clic.

Mais, comme fait-on pour différencier les deux boutons ? En fait, ce n'est pas très compliqué, mais ça va nécessiter quelques changements. On va en effet devoir comparer la référence de la source de l'événement avec nos boutons pour savoir qui a lancé l'événement :

 
Sélectionnez
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
 
public class FenetreAvecBouton extends JFrame implements ActionListener{
	private JButton bouton;
	private JButton bouton2;
 
	//...
 
	private JPanel buildContentPane(){
		JPanel panel = new JPane();
		panel.setLayout(new FlowLayout());
 
		bouton = new JButton("Cliquez ici !");
		panel.add(bouton);
 
		bouton2 = new JButton("Ou  !");
		panel.add(bouton2);
 
		return panel;
	}
 
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();
 
		if(source == bouton){
			System.out.println("Vous avez cliqué ici.");
		} else if(source == bouton2){
			System.out.println("Vous avez cliqué là.");	
		}
	}
}

Vous aurez cette fois un message différent en fonction du bouton. Vous pouvez tester avec plus de boutons, ça va marcher aussi. Mais le code de la méthode actionPerformed deviendra vite lourd s'il y a trop de boutons différents. On va maintenant passer à la deuxième technique. Elle nécessite un peu plus de code, mais je la considère plus propre et plus claire.

Code complet : FenetreBoutonsListener

5.1.2. AbstractAction

On va reprendre la classe FenetreBoutons et la renommer FenetreBoutonsActions.

Nous allons maintenant passer à la deuxième méthode : l'utilisation d'AbstractAction. Une AbstraAction est un ActionListener qui nous permet de gérer non seulement l'action générée par le composant mais aussi le texte, l'icône et l'état du composant. Par l'état, je veux dire activé/désactivé. En plus, on peut utiliser une action pour les éléments du menu comme pour les boutons ou alors les JToolbar. Donc si on a un bouton et un élément de menu qui font la même chose, il suffit d'utiliser la même action.

La classe AbstractAction est une implémentation abstraite d'Action qui nous évite de devoir implémenter toutes les méthodes d'Action. On va donc utiliser cette classe.

Maintenant, pour ajouter une Action à un programme, on peut soit créer une nouvelle classe dans un nouveau fichier soit créer une classe interne soit utiliser une classe anonyme. On va utiliser la première solution qui à mon avis, la plus appropriée.

Créons donc une classe IciAction pour notre bouton 1 :

 
Sélectionnez
public class IciAction extends AbstractAction {
	public IciAction(String texte){
		super(texte);
	}
 
	public void actionPerformed(ActionEvent e) { 
		System.out.println("Vous avez cliqué ici");
	} 
}

Tout ce qu'on a eu à faire, c'est redéfinir la méthode actionPerformed et créer un constructeur qui prend un texte en paramètre pour pouvoir lui passer le texte du bouton. Faisons de même pour le deuxième bouton :

 
Sélectionnez
public class LaAction extends AbstractAction {
	public LaAction(String texte){
		super(texte);
	}
 
	public void actionPerformed(ActionEvent e) { 
		System.out.println("Vous avez cliqué ");
	} 
}

On pourrait aussi directement indiquer le texte de l'action dans le constructeur de l'action sans le demander en paramètre, mais cela limiterait un peu la classe, le texte pouvant être différent en fonction d'ou on met l'action.

Et maintenant, on va attribuer ces actions à nos boutons. Pour cela rien de plus, il suffit de passer l'action au constructeur du JButton :

 
Sélectionnez
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
 
public class FenetreBoutonsActions extends JFrame implements ActionListener{
	private JPanel buildContentPane(){
		JPanel panel = new JPane();
		panel.setLayout(new FlowLayout());
 
		JButton bouton = new JButton(new IciAction("Cliquez ici !"));
		panel.add(bouton);
 
		JButton bouton2 = new JButton(new LaAction("Ou "));
		panel.add(bouton2);
 
		return panel;
	}
}

Comme vous le voyez c'est très simple et personnellement, je trouve cela bien plus claire que la méthode avec l'ActionListener unique, mais c'est à vous de juger. Le désavantage étant qu'il faut créer autant de classe que de boutons, mais le nombre de classe n'étant pas limitées, est-ce bien important ?

Dans un tel cas, on aurait pu créer une seule action qui prend en paramètre ce qu'il faut afficher dans la console pour éviter d'être trop redondant au niveau du code.

Code complet :

5.2. Application au projet

Maintenant que nous avons appris à utiliser des boutons et à leur attribuer une action, nous allons appliquer cela à notre application en y ajoutant un bouton "Calculer".

On va donc créer une classe "CalculAction" qui sera vide pour le moment :

 
Sélectionnez
public class CalculAction extends AbstractAction {
	private CalculatriceFenetre fenetre;
 
	public CalculAction(CalculatriceFenetre fenetre, String texte){
		super(texte);
 
		this.fenetre = fenetre;
	}
 
	public void actionPerformed(ActionEvent e) { 
		//Action lors du clic sur le bouton calculer
	} 
}

On a juste mis en paramètre de l'action la référence vers la fenêtre pour que l'action puisse aller chercher des infos dans la fenêtre.

Et on va maintenant ajouter un bouton avec cette action dans notre fenêtre :

 
Sélectionnez
//...
import javax.swing.JButton;
 
public class CalculatriceFenetre extends JFrame {
 
	//...
 
	private JPanel buildContentPane(){
		JPanel panel = new JPane();
		panel.setLayout(new FlowLayout());
		panel.setBackground(Color.White);
 
		JButton bouton = new JButton(new CalculAction(this, "Calculer"));
 
		panel.add(bouton);
 
		JLabel label = new JLabel("Résultat : Pas encore calculé");
 
		panel.add(label);
 
		return panel;
	}
}

Ce qui devrait nous donner pour le moment une calculatrice de ce genre qui ne fait encore rien :

Notre calculatrice
Notre calculatrice

Code complet :


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

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 © 2009 Baptiste Wicht. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.