FANTAR_TP7

publicité
FANTAR SAMI
SRC1 B1
TP n°7 : Composants SWING et gestion d’évenements
Exercice 1. Fenêtre principale de l’application
1.
Le nom du package à importer pour pouvoir utiliser des composants Swing est le package
"javax.swing.*;" l'astérisque permet de dire qu'on prend toutes les méthodes du package
On l'importe au début du programme ainsi que deux autres composants nécessaires "java.awt" et
"java.awt.event".

"java.swing" contient l'ensemble des composants "allégés" qui ont le maximum de
probabilités de fonctionner de la même façon sur toutes les plateformes.

"java.awt" contient toutes les classes nécessaires pour créer des interfaces utilisateurs et
pour l'utilisation d'images. Elle permet aussi de dessiner.

"java.awt.event" contient les interfaces et les classes nécessaires pour communiquer avec
les composants d' awt.
Composants Swing de la classe :










"JFrame" permet de créer une nouvelle fenêtre.
"ActionListener" permet d'invoquer la méthode adéquate lors d'une action.
"JLabel" est une zone de texte ou une image ou les deux.
"JTextField" est un composant allégé permettant d'éditer une ligne de texte.
"JButton" est un bouton permettant de réaliser des actions lors de la pression sur ce
dernier.
"JTextArea" est une zone de texte de plusieurs lignes.
"Dimension" est une classe encapsulée permettant de spécifier la hauteur et la largeur d'un
composant dans un seul objet.
"Color" permet de spécifier la couleur selon un code RGB.
"Font" permet de spécifier la couleur de fond permettant de rendre un texte visible.
"FlowLayout" permet d'arranger le positionnement des composants de gauche à droite,
comme les lignes d'un texte dans un paragraphe.
2.
La méthode "random" de la classe "Math" permet de donner un nombre de manière aléatoire. Elle
retourne une valeur de type double avec un signe positif plus grand ou egal à 0.0 et inférieur à 1.0
3.
Avant l’ajout de la méthode « pack », nous obtenions ceci :
Nous rajoutons dans le code du constructeur un appel à la méthode "pack". La classe PrixLot hérite
de la classe JFrame et la classe JFrame hérite de la classe Window donc de toutes les méthodes de
cette dernière. Nous recompilons et executons :
La méthode pack appartient à la classe Window et permet de redimensionner la fenêtre par
rapport au nombre d'éléments contenus dans la fenêtre.
Exercice 2. Gestion de l’interaction sur la fenêtre du jeu
1.Bouton et fermeture de la fenêtre
Lorsqu'on essaie de fermer la fenêtre en cliquant sur le bouton de fermeture de la fenêtre il ne ce
passe rien. On rajoute donc la ligne "setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE)".
Maintenant le bouton de fermeture de la fenêtre fonctionne.
2. Test des valeurs entrées par le joueur
(a)
Pour gérer l'événement sur le bouton Go! il faut implémenter l'interface ActionListener. Mais
ActionListener oblige de déclarer ensuite dans la classe PrixLot, la méthode actionPerformed().
PrixLot peut maintenant écouter des événements. Pour pouvoir écouter les événements du bouton
go!, il faut ajouter un écouteur à la classe. On ajoute donc : bouton.addActionListener(this).
« This » permet de dire que l'écouteur est la classe courante donc PrixLot devient l'écouteur.
Dorénavant, l'écouteur permet d'appeler la méthode actionPerformed() dès qu' un événement
apparaît et lui passe cet événement en argument.
Puis on vérifie la source de l'événement passé en argument
On vérifie ensuite la source de l'événement passé en argument pour exécuter des instruction
diverses en fonction. Cela permet donc à la classe d'écouter plusieurs boutons en même temps et
de leur attribuer des actions.
(b)
public void actionPerformed(ActionEvent unEvnt)
{
if (unEvnt.getSource() == goButton)
// Le joueur clic sur Go !
{
// On récupere la valeur saisie par le joueur pour la comparer
String valeur_joueur = tfSaisie.getText();
try
{
// On converti la chaîne valeur_joueur en int
int nbTape =Integer.parseInt(valeur_joueur);
if (nbTape==nbCache) //Cas où le joueur trouve d’un coup
{
taResultat.setForeground(Color.BLUE);
taResultat.setFont(new Font("Serif",Font.BOLD,14));
taResultat.setText("Bravo! Tu as trouvé du 1er coup!");
}
else
{
if (nbTape<nbCache)//Cas où nombre taper < nombre caché
{
taResultat.setForeground(Color.GREEN);
taResultat.setFont(new Font("Serif",Font.BOLD,12));
taResultat.setText("trop petit");
}
else //Cas où nombre taper > nombre caché
{
taResultat.setForeground(Color.YELLOW);
taResultat.setFont(new Font("Serif",Font.BOLD,18));
taResultat.setText("trop grand");
}
}
}
catch (NumberFormatException exc)
{
//Verification de la saisie du joueur
System.out.println("Vous n’avez pas saisie un entier") ;
}
}
}
3. Gestion du nombre d'essais
public void actionPerformed(ActionEvent unEvnt)
{
if (unEvnt.getSource() == goButton// Le joueur clic sur Go !
{
int k = nbEssaisAutorises - nbEssais;
if (nbEssais == nbEssaisAutorises)
//cas où nombre d’essais effectués =nombre d’essais autorisé
{
taResultat.setForeground(Color.RED);
taResultat.setFont(new Font("Serif",Font.BOLD,14));
taResultat.setText("Vous n'avez plus la possibilité de rejouer!
Vous avez perdu...");//msg d’erreur signalant que le jeu est
fini
tfSaisie.setEditable(false);//blocage de la saisie de tfsaisie
}
else
// cas où nombre d'essais effectués < nombre d'essais autorisé
{
String valeur = tfSaisie.getText();// Récupération de la valeur
tapée par le joueur
try
{
// On converti la chaîne valeur_joueur en int
int nbTape =Integer.parseInt(valeur);
if (nbTape==nbCache) //Cas où le joueur trouve d’un coup
{
tfSaisie.setEditable(false);
taResultat.setForeground(Color.GREEN);
taResultat.setFont(new Font("Serif",Font.BOLD,14));
taResultat.setText("Bravo! Vous avez deviné en
"+nbEssais+" essais.");
}
else
{
if (nbTape<nbCache)//Cas où nombre taper < nombre caché
{
taResultat.setForeground(Color.BLUE);
taResultat.setFont(new Font("Serif",Font.BOLD,12));
taResultat.setText("trop petit... Attention il ne vous
reste plus que "+k+"essais...");
}
else //Cas où nombre taper > nombre caché
{
taResultat.setForeground(Color.ORANGE);
taResultat.setFont(new Font("Serif",Font.BOLD,18));
taResultat.setText("trop grand… Attention, il ne vous
reste plus que "+k+" essais...");
}
}
}
catch (NumberFormatException exc)
{
//Verification de la saisie du joueur
System.out.println("Vous n’avez pas saisie un entier");
}
nbEssais = nbEssais+1;
}
}
}
4. Gestion des erreurs de saisie
(a)
Lorsque le jouer ne saisie pas une valeur entière dans le JtextArea tfSaisie, le terminal affiche un
message d’erreur « Vous n’avez pas saisie un entier».
Le bloc try{…} catch(NumberFormatException exc){…} dans la méthode actionPerformed permet de
vérifier que le type de données saisie correspond au bon format. Dans notre cas, le format attendu est
un integer (NumberFormat) le mot clé TRY permet de préciser un morceau du code sur lequel on
s'attend à qu'une erreur (exception) se présente.
Le mot clé CATCH sert à spécifier le code à exécuter pour une exception (ou une catégorie)donnée. Il
suffit alors de faire suivre le mot catch d'une parenthèse ouvrante, d'un type exception (une classe)
du nom qu'on lui donne (tout comme un paramètre de fonction), d'une parenthèse fermante, et du
code associé placé entre accolade.
Si un événement indésirable survient dans le bloc try, la partie éventuellement non exécutée de ce bloc
est abandonnée et le premier bloc catch est traité. Si catch est défini pour capturer l'exception issue
du bloc try alors elle est traitée en exécutant le code associé au bloc. Si le bloc catch est vide (aucune
instruction entre les accolades) alors l'exception capturée est ignorée.
(b)
catch (NumberFormatException exc)
{
//Verification de la saisie du joueur
JOptionPane.showMessageDialog (this ," Entrez un nombre
entier !!!", "Attention !", JOptionPane.WARNING_MESSAGE );
}
public static void showMessageDialog(Component parentComponent,
Object message,String title,int messageType)throws HeadlessException
On obtient un message d’erreur qui montre un message en utilisant une icône de défaut déterminée par le
paramètre de messageType lorsque l’utilisateur saisie autre chose qu’un nombre entier.
Les différents paramètres du panneau :
 parentComponent - détermine la vue dans laquelle le dialogue est montré ; si nulle, ou si
parentComponent n'a aucune vue, une vue de défaut est employé
 message – texte à afficher (ici, Entrez un nombre entier !!!)
 title - titre de la boite de message (ici, on l’appel Attention !)
 messageType - type de messsage que le montre : ERROR_MESSAGE, INFORMATION_MESSAGE,
WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE, selon le type de message,
l’icône d’alerte change.
Exercice 3. Ajout d’un menu à la fenêtre principale
1.
La classe MenuPrixLot.java crée un menu pour la fenêtre princiale .La méthode actionPerformed permet
d'exécuter des actions lorsque l'on clique sur l'une des rubriques du menu.
Explication des différents composants et méthodes utilisées :
 JFrame() : Crée une fenêtre invisible sans titre.
 JMenu () : Créer un menu pouvant être inséré dans une barre de menu.
 JMenuItem () :Les éléments du menu sont représenté par des objets MenuItem.
 add () : ceci permet d’ajouter des éléments au menu.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MenuPrixLot extends JMenuBar implements ActionListener
{
JMenuItem item1, item2, item3;
PrixLot fenAppli;
public MenuPrixLot(PrixLot frame)
{
//On associe le menu à l’application principale
fenAppli = frame ;
JMenu menu1, menu2;
menu1 = new JMenu("Fichier");
item1= new JMenuItem("réinitialiser");
item2= new JMenuItem("quitter");
menu1.add(item1);
menu1.add(item2);
add(menu1);
menu2 = new JMenu("Aide");
item3= new JMenuItem("à propos");
menu2.add(item3);
add(menu2);
//MenuPrixLot joue le role d’écouteur sur les différents items du menu.
}
public void actionPerformed(ActionEvent unEvnt)
{
//ici, on gère les évenements liés au Item
}
}
(2)
On rajoute à la fin de la méthode PrixLot, le code suivant permettant d’intégrer l’objet MenuPrixLot dans la
classe PrixLot.
JMenuBar in_barre= new MenuPrixLot(this);
setJMenuBar(in_barre);


Classe JMenuBar: elle représente une barre de menu ou un groupe de menu. JMenuBar.
setJMenuBar : permet d’inserer la barre de menu dans le programme courant.
Exercice 4. Gestion de l’intéraction liée au menu
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MenuPrixLot extends JMenuBar implements ActionListener
{
JMenuItem item1, item2, item3;
PrixLot fenAppli;
public MenuPrixLot(PrixLot frame)
{
//on associe le menu à l’application principale
fenAppli = frame ;
//On crée les différents menu fichier et aide
JMenu menu1, menu2;
menu1 = new JMenu("Fichier");
menu2 = new JMenu("Aide");
//On crée les différents items du menu1
item1= new JMenuItem("réinitialiser");
item2= new JMenuItem("quitter");
//On ajoute les items crée au menu1
menu1.add(item1);
menu1.add(item2);
//On ajoute le menu1 crée à la barre de menu de l’application
add(menu1);
//On crée les différents items du menu2
item3= new JMenuItem("à propos");
//On ajoute les items crée au menu2
menu2.add(item3);
//On ajoute le menu2 crée à la barre de menu de l’application
add(menu2);
//MenuPrixLot joue le rôle d’écouteur sur les items du menu
item1.addActionListener(this);
item2.addActionListener(this);
item3.addActionListener(this);
}
public void actionPerformed(ActionEvent unEvnt)
{
//On gère les événements de l’item2 du menu
if (unEvnt.getSource() == item2)
java.lang.System.exit(0);
//On gère les événements de l’item3 du menu
if (unEvnt.getSource() == item3)
JOptionPane.showMessageDialog(this, "-=[$@m$0ft CORP]=-", "à
propos", JOptionPane.INFORMATION_MESSAGE );
//On gère les événements de l’item1 du menu
if (unEvnt.getSource() == item1)
{
fenAppli.nbEssais = 1;
// on affiche un message dans JTextAera taResultat
fenAppli.taResultat.setText(" Attention, vous n'avez que
"+fenAppli.nbEssaisAutorises+" essais... Soyez stratégiques !");
// on attribut les paramètres demandés d'affichage du texte
fenAppli.taResultat.setForeground(Color.RED);
fenAppli.taResultat.setFont(new Font("Serif",Font.BOLD,14));
fenAppli.taResultat.setEditable(false);
// Recherche aléatoire d’un nombre entre 1 et 100
fenAppli.nbCache = (int)(Math.random()*100)+1;
// Le nombre aléatoire sorti, apparaît dans le terminal
System.out.println("Le nombre à deviner est
"+fenAppli.nbCache+".");
// on attribut les paramètres demandés d'affichage du texte
fenAppli.tfNbCache.setEditable(false);
fenAppli.tfNbCache.setBackground(Color.YELLOW);
fenAppli.tfNbCache.setForeground(Color.DARK_GRAY);
//On efface le contenu de JTextField tfSaisie
fenAppli.tfSaisie.setText("");
//On peut réécrire dans JTextField tfSaisie car on met
setEditable à true
fenAppli.tfSaisie.setEditable(true);
}
}
}
Exercice 5. Un peu de maths…
D’après des connaissances personnelles vu l’année dernière en DUT INFO à Paris5, la recherche dichotomique
me semble la plus adapté comme stratégie pour trouver la valeur recherché en 6 coups.
Principe : on tape l’élément au milieu de la liste. Dans notre cas, la liste va jusqu’à 100. On tape donc 50.
- si sa clé est égale à la valeur cherchée, c'est gagné
- si sa clé est inférieure à la clé cherchée, il ne reste à traiter que la moitié droite de la liste. Donc on tape la
moitié de 50 qui est 25.
- si sa clé est supérieure à la clé cherchée, il ne reste à traiter que la moitié gauche de la liste Donc on tape la
moitié au dessus de 50 qui est 75.
On continue ainsi la recherche en diminuant à chaque fois de moitié le nombre d'éléments de la liste restant à
traiter.
Remarque : cette méthode n'est pas du tout adaptée à une implémentation chaînée puisqu'il n'y a pas d'accès
direct au k-ème élément.
Exemple : le chiffre recherché est 10
- 1er essais : 50 -> c’est trop grand donc on réduit le champ de recherche entre 1 et 50.
- 2ème essais : On prend la moitié de 50 soit 25 -> c’est trop grand donc on réduit le champ de recherche
entre 1 et 25.
- 3ème essais : On prend la moitié de 25 soit 13 -> c’est trop grand donc on réduit le champ de recherche
entre 1 et 13.
- 4ème essais : On prend la moitié de 13 soit 7 -> c’est trop petit donc on réduit le champ de recherche
entre 7 et 12.
- 5ème essais : 12-7=5 donc on ajoute la moitié de 5 à 7 se qui donne 10 -> c’est gagné.
L’algorithme correspondant à la recherche dichotomique est le suivant :
Procedure recherche_dichotomique(par val ent elt, par val ent N, par val
ent T[])
Debut
var inf, sup, m;
inf <- 1;
sup <- N;
m <- (inf+sup) div 2;
/* en C++ m = (int)((inf+sup)/2) */
/* Ici l'astuce : la borne supérieure ou inférieure est modifiée,
le tableau n'est plus parcouru dans son ensemble */
Tant que (T[m] != elt et inf < sup) faire
Si (elt < T[m]) alors
sup <- m - 1;
Sinon inf <- m + 1;
Fin Si
m <- (inf + sup) div 2;
Fin Tque
Si (T[m] = elt)
Afficher("L'element se trouve à l'indice m")
Sinon Afficher ("L' élément n'existe pas ")
Fin Si
Fin
Exercice 6. Finalisation de l’application
Le code suivant se trouvant dans le constructeur de la classe PrixLot soit la méthode PrixLot :
//On ajoute dans le conteneur principal, les composants
Container Conteneur = getContentPane();
Conteneur.setLayout(new FlowLayout());
Conteneur.add(lDevine);
Conteneur.add(tfNbCache);
Conteneur.add(lSaisie);
Conteneur.add(tfSaisie);
Conteneur.add(goButton);
Conteneur.add(taResultat);
Conteneur.setBackground(Color.WHITE);
est remplacé par le code ci-dessous pour pouvoir gérer l'apparence graphique avec des BoxLayout :
//On crée le conteneur de la fenetre de l’application
Container conteneur = getContentPane();
//on crée les objets BoxLayout
JPanel BoxV = new JPanel();
BoxV.setLayout(new BoxLayout(BoxV, BoxLayout.Y_AXIS));
JPanel Box1 = new JPanel();
BoxH1.setLayout(new BoxLayout(Box1, BoxLayout.X_AXIS));
JPanel Box2 = new JPanel();
BoxH2.setLayout(new BoxLayout(Box2, BoxLayout.X_AXIS));
JPanel Box3 = new JPanel();
BoxH3.setLayout(new BoxLayout(Box3, BoxLayout.X_AXIS));
JPanel Box4 = new JPanel();
BoxH4.setLayout(new BoxLayout(Box4, BoxLayout.X_AXIS));
//On ajoute aux BoxLayout JLabel, JTextField, JButton
Box1.add(lDevine);
Box1.add(tfNbCache);
Box2.add(lSaisie);
Box2.add(tfSaisie);
Box3.add(goButton);
Box4.add(taResultat);
//On met la couleur de background en blanc
Box1.setBackground(Color.WHITE);
Box2.setBackground(Color.WHITE);
Box3.setBackground(Color.WHITE);
Box4.setBackground(Color.WHITE);
//On ajoute les 4 BoxLayout horizontales à la BoxLayout verticale (BoxV)
BoxV.add(Box1);
BoxV.add(Box2);
BoxV.add(Box3);
BoxV.add(Box4);
// On ajoute BoxV au conteneur de l’application
conteneur.add(BoxV);
conteneur.setBackground(Color.WHITE);
Téléchargement