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

Corrections des exercices du livre "Java pour les enfants, les parents et les grand-parents"


précédentsommairesuivant

V. Chapitre 6

V-A. On adapte la calculatrice de la correction pour petits malins du chapitre 5

V-A-1. Récupération des anciens codes

La calculatrice que nous avons définie à l'aide de la correction (pour petits malins) du chapitre 5, comporte certains avantages. Notamment, au niveau de la répétition du code pour les différents boutons chiffres.

Je suis donc reparti de cette calculatrice-là (à peu de choses près : le nom de la classe MoteurCalcul est à remplacer par MoteurCalcul_avantCorrection et la classe utilisée n'est plus simplement Calculatrice mais Calculatrice_avantCorrection) : mais sachez qu'il n'est pas difficile d'adapter ce que j'ai utilisé par la suite au code original du chapitre 6.

En revanche, le moteur de calcul reste le même, à quelques noms de variables près. Ce sont les noms des boutons opérateurs de la variable parent qui sont à adapter.

Pour rappel, le code calculatrice que nous avons codé à la correction pour petits malins du chapitre 5 :

Ancien code calculatrice
TéléchargerCacher/Afficher le codeSélectionnez

Et voici la classe MoteurCalcul adaptée à nos besoins (pour l'instant remplacez tous les appels à Calculatrice_avantCorrection par Calculatrice_2. Utilisez pour cela le menu Edit->Find/Replace d'Eclipse) :

MoteurCalcul avant la correction
TéléchargerCacher/Afficher le codeSélectionnez

On ajoute donc une instance de MoteurCalcul à l'ensemble des boutons :

  • du panneau panneauChiffres ;
  • du panneau panneauOperations.

Pour ce faire :

  • je me contente de déclarer une instance de MoteurCalcul une fois pour toutes ;
  • pour chaque panneau, je parcours l'ensemble de ses composants. Et pour chaque composant de type JButton, j'ajoute le MoteurCalcul en tant qu'écouteur d'action (ActionListener).

V-A-2. Boucle For each

Avant de vous proposer la nouvelle version de Calculatrice, qui nous permettra de résoudre les exercices du chapitre, je voulais vous parler d'un autre type de boucle for. Elle est plus adaptée au cas présent.

Voici sa syntaxe :

Syntaxe for each
Sélectionnez
for (TypeObjet nomObjet : TableauDuTypeObjets){
    // Faire quelque chose avec nomObjet
}

Avantages :

  • la syntaxe est plus simple ;
  • on n'a pas besoin de créer une variable de type entier pour parcourir le tableau d'objets.

Inconvénient :

  • on ne connaîtra pas la position de l'objet courant. Pour cela, il faudra en revenir à l'utilisation d'une boucle for classique.

Soyez tout de même conscient que cette fonctionnalité n'existe pas avant Java 5. Tout JDK antérieur vous renverra une erreur en employant cette syntaxe.

On appelle cette boucle, une boucle de type for each. Car elle définit une action pour toutes les valeurs du tableau.

V-A-3. La méthode getComponents() de java.awt.Container

Pour connaître la liste des composants d'un panneau, j'utilise la méthode getComponents() de la classe java.awt.Container. Si vous parcourez la javadoc officielle, vous constaterez que la classe javax.swing.JPanel hérite notamment de la classe java.awt.Container.

En revanche, cette méthode renvoie un tableau de java.awt.Component et non de javax.swing.JButton. La classe javax.swing.JButton héritant de java.awt.Component, il suffira de :

  • tester si le composant courant est de type JButton ;
  • si cela est concluant, de faire un casting du composant récupéré dans le type JButton.

Enfin, pour que cela fonctionne, il faut effectuer ce traitement une fois les boutons ajoutés au panneau concerné, pas avant (logique).

V-A-4. Le code final de Calculatrice avant les corrections

Voici donc la classe Calculatrice que nous allons utiliser (pour l'utiliser, il faut modifier la classe MoteurCalcul_avantCorrection pour se baser sur la classe Calculatrice_avantCorrection et non Calculatrice_2) :

Classe Calculatrice avant la correction
TéléchargerCacher/Afficher le codeSélectionnez

En testant le code, vous pouvez vous apercevoir que le fonctionnement est bien celui qui était attendu.

V-B. Division par 0

On nous demande d'afficher un message d'erreur si l'utilisateur tente d'effectuer une division par zéro. On sait d'ores et déjà que la partie graphique est gérée dans la classe Calculatrice et la partie traitements dans la classe MoteurCalcul. C'est donc la classe MoteurCalcul que nous allons ici modifier.

Il nous faut afficher le message d'erreur juste au moment où l'utilisateur appuie sur le bouton égale.

C'est donc cette section de code qui nous intéresse :

Section de code à modifier
Sélectionnez
        else if (sourceEvenement == parent.boutonEgale) {
            // Effectue les calculs en fonction de actionSelectionnee
            // Modifie la valeur de la variable resultatCourant
            // et affiche le resultat
            if (actionSelectionnee == '+') {
                resultatCourant += valeurAffichee;
                // Convertit le resultat en le transformant en String
                // a l'aide de formatNombres
                parent.champAffichage.setText(
                        formatNombres.format(resultatCourant));
            }
            else if (actionSelectionnee == '-') {
                resultatCourant -= valeurAffichee;
                parent.champAffichage.setText(
                        formatNombres.format(resultatCourant));
            }
            else if (actionSelectionnee == '/') {
                resultatCourant /= valeurAffichee;
                parent.champAffichage.setText(
                        formatNombres.format(resultatCourant));
            }
            else if (actionSelectionnee == '*') {
                resultatCourant *= valeurAffichee;
                parent.champAffichage.setText(
                        formatNombres.format(resultatCourant));
            }
        }

Bien sûr, on s'occupera de la section traitant de la division :

Section traitant de la division
Sélectionnez
            else if (actionSelectionnee == '/') {
                resultatCourant /= valeurAffichee;
                parent.champAffichage.setText(
                        formatNombres.format(resultatCourant));
            }

Le deuxième opérande de la division, celui qui ne doit pas valoir 0, est forcément la valeur couramment affichée. On peut donc écrire :

Première modification du code
Sélectionnez
            else if (actionSelectionnee == '/') {
                if (valeurAffichee != 0) {
                    resultatCourant /= valeurAffichee;
                    parent.champAffichage.setText(formatNombres
                            .format(resultatCourant));
                }
                else {
                    // Afficher message d'erreur
                }
            }

Vous savez également qu'une manière facile d'afficher un message d'erreur, consiste à utiliser la classe JOptionPane. Dans le cours vous avez utilisé la méthode statique showConfirmDialog().

Cette fois-ci j'ai utilisé la méthode showMessageDialog(), qui est plus flexible. On peut non seulement changer le message et le titre, mais aussi l'icône à afficher à côté du message. De cette manière, nous afficherons une icône signalant une erreur (encore une fois, n'hésitez pas à aller consulter la javadoc correspondant à votre JDK).

Signatures de showMessageDialog()
Sélectionnez
JOptionPane.showMessageDialog(controleParent, message) ;
JOptionPane.showMessage(controleParent, message, titre, icône) ;

Nous utiliserons la deuxième version :

Le code utilisé pour notifier l'utilisateur de l'erreur
Sélectionnez
JOptionPane.showMessage(null, " Division par 0 impossible ", " Erreur de saisie ", JOptionPane.ERROR_MESSAGE) ;

Voici donc le code du MoteurCalcul mis à jour (le code de la calculatrice reste presque le même, si ce n'est qu'il faut appeler MoteurCalcul_exerciceSimple_corrige cette fois-ci) :

Moteur calcul corrigé (exercice simple)
TéléchargerCacher/Afficher le codeSélectionnez

V-C. Exercice pour les petits malins

On nous demande de n'autoriser qu'une seule virgule à la fois dans le champ d'affichage. Par conséquent, c'est dans la classe MoteurCalcul que nous allons opérer.

Dans le code, une section se charge d'ajouter, à la zone d'affichage, le contenu du bouton cliqué. Bien sûr si celui-ci n'est pas un bouton opérateur :

La section de code qui nous intéresse
Sélectionnez
        else {
            // Pour tous les boutons numeriques, ajoute le libelle
            // du bouton au champ texte
            String libelleBoutonClique = boutonClique.getText();
            parent.champAffichage.setText(texteChampAffichage +
                    libelleBoutonClique);
        }

Il suffit donc de regarder si le bouton cliqué est le bouton virgule et d'adapter le traitement en conséquence :

Modification possible
Sélectionnez
        else {
            // Si le bouton n'est pas le bouton virgule
            // On peut se contenter d'ajouter son texte
            // sur l'ecran
            if (boutonClique != parent.boutonVirgule) {
                // Pour tous les boutons numeriques, ajoute le libelle
                // du bouton au champ texte
                String libelleBoutonClique = boutonClique.getText();
                ajouterCeTexteAuChampAffichage(libelleBoutonClique);
            }
            else {
                // traitement pour bouton virgule
            }
        }

L'exercice nous suggère d'utiliser la méthode indexOf() de la classe String. La javadoc nous apprend que cette fonction retourne :

  • l'index de la première occurrence du caractère passé (c'est-à-dire l'index du premier caractère identique qu'elle trouve à partir du début de la chaîne) si celui-ci y figure ;
  • -1 si celui-ci n'y figure pas du tout.

Il suffit donc de tester que la valeur de :

 
Sélectionnez
texteChampAffichage.indexOf(',')

vaut -1.

Attention tout de même à passer un caractère et non une chaine : on utilise donc de simples apostrophes.

Voici donc ce que cela peut donner :

 
Sélectionnez
        else {
            // Si le bouton n'est pas le bouton virgule
            // On peut se contenter d'ajouter son texte
            // sur l'ecran
            if (boutonClique != parent.boutonVirgule) {
                // Pour tous les boutons numeriques, ajoute le libelle
                // du bouton au champ texte
                String libelleBoutonClique = boutonClique.getText();
                parent.champAffichage.setText(texteChampAffichage
                        + libelleBoutonClique);
            }
            else {
                boolean virguleNonPresente = texteChampAffichage.indexOf(',') == -1;
                if (virguleNonPresente){
                    parent.champAffichage.setText(texteChampAffichage + ',');
                }
            }
        }

V-C-1. Code complet

MoteurCalcul exercice avancé corrigé
TéléchargerCacher/Afficher le codeSélectionnez

V-D. Synthèse

Ainsi, vous avez pu :

  • utiliser une boucle for each pour parcourir l'ensemble des composants d'un panneau ;
  • modifier la classe MoteurCalcul afin d'afficher un message d'erreur si l'utilisateur tente une division par 0 ;
  • empêcher l'utilisateur d'entrer deux virgules (ou plus) pour le même nombre.

précédentsommairesuivant

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 © 2012 Laurent Bernabé. Aucune reproduction, même partielle, ne peut être faite de ce site ni 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.