Ah ! Ça faisait longtemps… Un petit TP ! Dans celui-ci, nous allons - enfin, vous allez - pouvoir réviser tout ce qui a été vu au cours de cette partie :
- les fenêtres ;
- les conteneurs ;
- les boutons ;
- les interactions ;
- les classes internes ;
L'objectif est ici de réaliser une petite calculatrice basique.
Élaboration
Nous allons tout de suite voir ce dont notre calculatrice devra être capable :
- Effectuer un calcul simple : 12 + 3 par exemple.
- Faire des calculs à la chaîne, par exemple : 1 + 2 + … ; lorsqu'on clique à nouveau sur un opérateur, il faut afficher le résultat du calcul précédent.
- Donner la possibilité de tout recommencer à zéro.
- Gérer l'exception d'une division par 0 !
Conception
Vous devriez obtenir à peu de choses près la figure suivante.
Voyons maintenant ce dont nous avons besoin pour parvenir à nos fins :
- autant de boutons qu'il en faut ;
- autant de conteneurs que nécessaire ;
- un
JLabel
pour l'affichage ; - un booléen pour savoir si un opérateur a été sélectionné ;
- un booléen pour savoir si nous devons effacer ce qui figure à l'écran et écrire un nouveau nombre ;
- nous allons utiliser une variable de type
double
pour nos calculs ; - il va nous falloir des classes internes qui implémenteront l'interface
ActionListener
; - et c'est à peu près tout.
Pour alléger le nombre de classes internes, vous pouvez en créer une qui se chargera d'écrire ce qui doit être affiché à l'écran. Utilisez la méthode getSource()
pour savoir sur quel bouton on a cliqué.
Je ne vais pas tout vous dire, il faut que vous cherchiez par vous-mêmes : la réflexion est très importante ! En revanche, vous devez savoir que la correction que je vous fournis n'est pas la correction. Il y a plusieurs solutions possibles. Je vous propose seulement l'une d'elles.
Allez, au boulot !
Correction
Vous avez bien réfléchi ? Vous vous êtes brûlé quelques neurones ? Vous avez mérité votre correction ! Regardez bien comment tout interagit, et vous comprendrez comment fonctionne ce code.
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Calculatrice extends JFrame { private JPanel container = new JPanel(); //Tableau stockant les éléments à afficher dans la calculatrice String[] tab_string = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", "=", "C", "+", "-", "*", "/"}; //Un bouton par élément à afficher JButton[] tab_button = new JButton[tab_string.length]; private JLabel ecran = new JLabel(); private Dimension dim = new Dimension(50, 40); private Dimension dim2 = new Dimension(50, 31); private double chiffre1; private boolean clicOperateur = false, update = false; private String operateur = ""; public Calculatrice(){ this.setSize(240, 260); this.setTitle("Calculette"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLocationRelativeTo(null); this.setResizable(false); //On initialise le conteneur avec tous les composants initComposant(); //On ajoute le conteneur this.setContentPane(container); this.setVisible(true); } private void initComposant(){ //On définit la police d'écriture à utiliser Font police = new Font("Arial", Font.BOLD, 20); ecran = new JLabel("0"); ecran.setFont(police); //On aligne les informations à droite dans le JLabel ecran.setHorizontalAlignment(JLabel.RIGHT); ecran.setPreferredSize(new Dimension(220, 20)); JPanel operateur = new JPanel(); operateur.setPreferredSize(new Dimension(55, 225)); JPanel chiffre = new JPanel(); chiffre.setPreferredSize(new Dimension(165, 225)); JPanel panEcran = new JPanel(); panEcran.setPreferredSize(new Dimension(220, 30)); //On parcourt le tableau initialisé //afin de créer nos boutons for(int i = 0; i < tab_string.length; i++){ tab_button[i] = new JButton(tab_string[i]); tab_button[i].setPreferredSize(dim); switch(i){ //Pour chaque élément situé à la fin du tableau //et qui n'est pas un chiffre //on définit le comportement à avoir grâce à un listener case 11 : tab_button[i].addActionListener(new EgalListener()); chiffre.add(tab_button[i]); break; case 12 : tab_button[i].setForeground(Color.red); tab_button[i].addActionListener(new ResetListener()); operateur.add(tab_button[i]); break; case 13 : tab_button[i].addActionListener(new PlusListener()); tab_button[i].setPreferredSize(dim2); operateur.add(tab_button[i]); break; case 14 : tab_button[i].addActionListener(new MoinsListener()); tab_button[i].setPreferredSize(dim2); operateur.add(tab_button[i]); break; case 15 : tab_button[i].addActionListener(new MultiListener()); tab_button[i].setPreferredSize(dim2); operateur.add(tab_button[i]); break; case 16 : tab_button[i].addActionListener(new DivListener()); tab_button[i].setPreferredSize(dim2); operateur.add(tab_button[i]); break; default : //Par défaut, ce sont les premiers éléments du tableau //donc des chiffres, on affecte alors le bon listener chiffre.add(tab_button[i]); tab_button[i].addActionListener(new ChiffreListener()); break; } } panEcran.add(ecran); panEcran.setBorder(BorderFactory.createLineBorder(Color.black)); container.add(panEcran, BorderLayout.NORTH); container.add(chiffre, BorderLayout.CENTER); container.add(operateur, BorderLayout.EAST); } //Méthode permettant d'effectuer un calcul selon l'opérateur sélectionné private void calcul(){ if(operateur.equals("+")){ chiffre1 = chiffre1 + Double.valueOf(ecran.getText()).doubleValue(); ecran.setText(String.valueOf(chiffre1)); } if(operateur.equals("-")){ chiffre1 = chiffre1 - Double.valueOf(ecran.getText()).doubleValue(); ecran.setText(String.valueOf(chiffre1)); } if(operateur.equals("*")){ chiffre1 = chiffre1 * Double.valueOf(ecran.getText()).doubleValue(); ecran.setText(String.valueOf(chiffre1)); } if(operateur.equals("/")){ try{ chiffre1 = chiffre1 / Double.valueOf(ecran.getText()).doubleValue(); ecran.setText(String.valueOf(chiffre1)); } catch(ArithmeticException e) { ecran.setText("0"); } } } //Listener utilisé pour les chiffres //Permet de stocker les chiffres et de les afficher class ChiffreListener implements ActionListener { public void actionPerformed(ActionEvent e){ //On affiche le chiffre additionnel dans le label String str = ((JButton)e.getSource()).getText(); if(update){ update = false; } else{ if(!ecran.getText().equals("0")) str = ecran.getText() + str; } ecran.setText(str); } } //Listener affecté au bouton = class EgalListener implements ActionListener { public void actionPerformed(ActionEvent arg0){ calcul(); update = true; clicOperateur = false; } } //Listener affecté au bouton + class PlusListener implements ActionListener { public void actionPerformed(ActionEvent arg0){ if(clicOperateur){ calcul(); ecran.setText(String.valueOf(chiffre1)); } else{ chiffre1 = Double.valueOf(ecran.getText()).doubleValue(); clicOperateur = true; } operateur = "+"; update = true; } } //Listener affecté au bouton - class MoinsListener implements ActionListener { public void actionPerformed(ActionEvent arg0){ if(clicOperateur){ calcul(); ecran.setText(String.valueOf(chiffre1)); } else{ chiffre1 = Double.valueOf(ecran.getText()).doubleValue(); clicOperateur = true; } operateur = "-"; update = true; } } //Listener affecté au bouton * class MultiListener implements ActionListener { public void actionPerformed(ActionEvent arg0){ if(clicOperateur){ calcul(); ecran.setText(String.valueOf(chiffre1)); } else{ chiffre1 = Double.valueOf(ecran.getText()).doubleValue(); clicOperateur = true; } operateur = "*"; update = true; } } //Listener affecté au bouton / class DivListener implements ActionListener { public void actionPerformed(ActionEvent arg0){ if(clicOperateur){ calcul(); ecran.setText(String.valueOf(chiffre1)); } else{ chiffre1 = Double.valueOf(ecran.getText()).doubleValue(); clicOperateur = true; } operateur = "/"; update = true; } } //Listener affecté au bouton de remise à zéro class ResetListener implements ActionListener { public void actionPerformed(ActionEvent arg0){ clicOperateur = false; update = true; chiffre1 = 0; operateur = ""; ecran.setText(""); } } } |
1 2 3 4 5 | public class Main { public static void main(String[] args) { Calculatrice calculette = new Calculatrice(); } } |
Je vais vous donner une petite astuce afin de créer un .jar
exécutable en Java.
Générer un .jar exécutable
Tout d'abord, qu'est-ce qu'un .jar
? C'est une extension propre aux archives Java (J
ava AR
chive). Ce type de fichier contient tout ce dont a besoin la JVM pour lancer un programme. Une fois votre archive créée, il vous suffit de double-cliquer sur celle-ci pour lancer l'application. C'est le meilleur moyen de distribuer votre programme.
C'est exact pour peu que vous ayez ajouté les exécutables de votre JRE (présents dans le répertoire bin
) dans votre variable d'environnement PATH
! Si ce n'est pas le cas, refaites un tour dans le premier chapitre du livre, section « Compilation en ligne de commande », et remplacez le répertoire du JDK par celui du JRE (si vous n'avez pas téléchargé le JDK ; sinon, allez récupérer ce dernier).
La création d'un .jar
est un jeu d'enfant. Commencez par effectuer un clic droit sur votre projet et choisissez l'option Export
, comme le montre la figure suivante.
Vous voici dans la gestion des exports. Eclipse vous demande quel type d'export vous souhaitez réaliser, comme à la figure suivante.
Comme l'illustre la figure précédent, sélectionnez JAR File
puis cliquez sur Next
. Vous voici maintenant dans la section qui vous demande les fichiers que vous souhaitez inclure dans votre archive, comme à la figure suivante.
- Dans le premier cadre, sélectionnez tous les fichiers qui composeront votre exécutable
.jar
. - Dans le second cadre, indiquez à Eclipse l'endroit où créer l'archive et le nom vous souhaitez lui donner.
- Ensuite, cliquez sur
Next
.
La page suivante n'est pas très pertinente ; je la mets cependant en figure suivante afin de ne perdre personne.
Cliquez sur Next
: vous arrivez sur la page qui vous demande de spécifier l'emplacement de la méthode main
dans votre programme (figure suivante).
Cliquez sur Browse…
pour afficher un pop-up listant les fichiers des programmes contenant une méthode main
. Ici, nous n'en avons qu'une (voir figure suivante). Souvenez-vous qu'il est possible que plusieurs méthodes main
soient déclarées, mais une seule sera exécutée !
Sélectionnez le point de départ de votre application et validez. La figure suivante correspond à ce que vous devriez obtenir.
Vous pouvez maintenant cliquer sur Finish
et voir s'afficher un message ressemblant à celui de la figure suivante.
Ce type de message n'est pas alarmant : il vous signale qu'il existe des éléments qu'Eclipse ne juge pas très clairs. Ils n'empêcheront toutefois pas votre application de fonctionner, contrairement à un message d'erreur que vous repérerez facilement : il est en rouge.
Une fois cette étape validée, vous pouvez voir avec satisfaction qu'un fichier .jar
a bien été généré dans le dossier spécifié, comme à la figure suivante.
Double-cliquez sur ce fichier : votre calculatrice se lance !