Aller au menu - Aller au contenu

Icône TP : une calculatrice

Mise à jour : 12/02/2010
Difficulté : Intermédiaire Intermédiaire Creative Commons BY-NC-SA
96 702 visites depuis 7 jours, dont 1 334 sur ce chapitre classé 4/786
Ah ! Ça faisait longtemps... un petit TP... :p

Dans celui-ci, nous allons - enfin vous allez - pouvoir réviser tout ce que vous avez appris dans cette partie !
  • Fenetre
  • Conteneur
  • Bouton
  • ActionPerformed
  • Classe interne
  • Exception. Bon, ça, c'était dans celle d'avant. ^^


Allez mes ZérOs, en avant !
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Élaboration

Bon, nous allons voir ce que doit faire notre calculatrice.
  • Un calcul simple : 12 + 3 =
  • Des calculs à la chaîne... Exemple : 1 + 2 +, lorsque vous cliquez à nouveau sur un opérateur, vous affichez le résultat du calcul précédent !
  • Donner la possibilté de faire un reset, donc de tout faire recommencer à zéro.
  • Gérer l'exception pour une division par 0 !

Conception

Voilà ce que vous devriez avoir :

Image utilisateur


Maintenant, voyons ce dont nous avons besoin pour réussir ça.
  • 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é choisi.
  • Un booléen pour savoir si nous devons effacer ce qu'il y a à l'écran et écrire un nouveau nombre.
  • Nous allons utiliser une variable de type double pour nos calculs.
  • Il va 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 faire une qui va se charger d'écrire ce qui doit être affiché à l'écran.
Utiliser la méthode getSource() pour savoir de quel bouton il s'agit...


Je ne vais pas tout vous dire... Il faut que vous cherchiez par vous-mêmes... La réflexion est très bonne !
Par contre, je vous le dis tout de suite :
la correction que je vous fournis n'est pas LA correction.
Il n'y a pas de bonne solution : si, en fait, considérez un programme qui fonctionne comme une solution.
Je vous propose seulement une solution POSSIBLE.


Allez, en avant mes ZérOs !

Correction

Vous avez bien réfléchi ?
Vous vous êtes brûlé quelques neurones... Vous avez mérité votre correction...

Secret (cliquez pour afficher)


Classe Main.java



Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class Main {
 
        /**
         * @param args
         */
        public static void main(String[] args) {
                Calculatrice calculette = new Calculatrice();
 
        }
 
}


Classe Calculatrice.java



Code : Java
  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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
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();
        
        String[] tab_string = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", "=", "C", "+", "-", "*", "/"};
        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);
                initComposant();
                
                this.setContentPane(container);
                this.setVisible(true);
        }
        
        private void initComposant(){

                Font police = new Font("Arial", Font.BOLD, 20);
                ecran = new JLabel("0");
                ecran.setFont(police);
                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));

                
                for(int i = 0; i < tab_string.length; i++)
                {
                    
                    tab_button[i] = new JButton(tab_string[i]);
                    tab_button[i].setPreferredSize(dim);
                    
                    switch(i){
	                
                    	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());
	                        tab_button[i].setPreferredSize(dim2);
	                        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 :
                    		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);
                
        }
        
        
        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");
                        }
                }
        }
        
        class ChiffreListener implements ActionListener{
 
                @Override
                public void actionPerformed(ActionEvent e) {
                        //On affiche le chiffre en plus 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);
                }
                
        }
 
        
        class EgalListener implements ActionListener{
 
                @Override
                public void actionPerformed(ActionEvent arg0) {
                        calcul();
                        update = true;
                        clicOperateur = false;
                }
                
        }
        
        
        class PlusListener implements ActionListener{
 
                @Override
                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;
                }
                
        }
        
        class MoinsListener implements ActionListener{
 
                @Override
                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;
                }
                
        }
        
        
        class MultiListener implements ActionListener{
 
                @Override
                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;
                }
                
        }
        
        
        class DivListener implements ActionListener{
 
                @Override
                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;
                }
                
        }
        
        
        class ResetListener implements ActionListener{
 
                @Override
                public void actionPerformed(ActionEvent arg0) {
                        clicOperateur = false;
                        update = true;
                        chiffre1 = 0;
                        operateur = "";
                        ecran.setText("");
                }
                
        }
        
}




Je ne m'attarderai pas trop là-dessus, ce code est très simple et je suis sûr que vous trouverez des améliorations :) .
Regardez bien comment tout interagit, et vous comprendrez comment il fonctionne !

Je vais vous donner une petite astuce pour faire un .jar exécutable en java...

Astuce Eclipse : faire un jar exécutable

Tout d'abord, qu'est-ce qu'un .jar ?
Un tel fichier est une archive Java (Java ARchive). Ce type de fichier contient tout ce dont a besoin la JVM pour lancer votre programme ! Une fois votre archive créée, il vous suffira juste de double cliquer sur celle-ci pour lancer l'application ! :magicien:

Ceci sous réserve que vous ayez ajouté les exécutables de votre JRE (présent dans le répertoire /bin) dans votre variable d'environnement PATH !
Si ceci n'est pas fait, allez faire un tour ici en remplaçant le répertoire du JDK par celui du JRE (si vous n'avez pas téléchargé le JDK, sinon, prenez ce dernier...).


Vous allez voir que créer un .jar est très simple !
Commencez par faire un clic droit sur votre projet et choisissez l'option Export, comme ceci :

Image utilisateur


Vous voici dans la gestion des exports. Eclipse vous demande quel type d'export vous souhaitez faire :

Image utilisateur


Comme sur l'image ci-dessus, ssélectionnez JAR File et cliquez sur Next. Vous voici maintenant dans le section qui vous demande quels fichiers vous voulez mettre dans votre archive.

Image utilisateur


  • Dans le cadre vert, nous choisissons tous les fichiers qui composeront notre exécutable .jar.
  • Dans le cadre bleu, nous spécifions à eclipse où créer l'archive et quel nom elle doit avoir.
  • Ensuite... On clique sur Next. :p


La page suivante n'est pas pertinente ici. Allez hop ! Circulez, y a rien à voir... (Il manque une émoticône gendarme sur le SDZ...)

La voici tout de même :

Image utilisateur


Cliquez sur Next et nous arrivons sur la page qui va nous demander où se trouve la méthode main dans notre programme :

Image utilisateur


Cliquez sur Browse... ; vous êtes maintenant sur une petite popup qui liste les fichiers de programmes contenant une méthode main. Ici, nous n'en avons qu'un... Mais il est possible d'avoir plusieurs méthodes main déclarées MAIS SEULEMENT UNE SEULE SERA EXÉCUTÉE !

Image utilisateur


Sélectionnez le point de départ de votre application et validez !
Voici ce que nous avons :

Image utilisateur


Vous pouvez maintenant cliquez sur Finish et vous devriez avoir un message du genre...

Image utilisateur


Ce type de message n'est pas alarmant ! Celui-ci vous dit qu'il existe des choses qu'Eclipse ne juge pas très claires... Mais celles-ci n'empêcheront pas votre application de fonctionner... Contrairement à un message d'erreur... Mais là, vous allez le repérer... Il est rouge.

Une fois cette étape validée, vous pouvez voir avec joie, qu'un fichier .jar a bien été généré dans le dossier spécifié !

Image utilisateur


Double cliquez sur lui et votre calculatrice se lance ! :magicien:

Si vous voulez en savoir plus sur les fichiers .jar, je vous recommande le tuto de bartimeus.
J'espère que ce TP vous a plu !
Je vous le répète encore une fois, mais mon code est loin d'être parfait et vous pouvez vous y attarder pour l'améliorer ! :p
Par exemple, vous pourriez créer un objet dont la fonction est de faire les calculs...
Vous pourriez aussi faire une calculette avec plus de fonctionnalités ! Enfin, vous voyez quoi...

Bon, continuons notre tuto. Nous en étions restés au problème de thread évoqué lorsque nous avions essayé de relancer notre animation.
Je pense que vous avez deviné la suite, en avant pour : les threads.
Chapitre précédent Sommaire Chapitre suivant

Partager

39 commentaires pour "TP : une calculatrice"
Note moyenne : 3.57 / 4 (1025 votes)
Pseudo Commentaire
Hors ligne ThomLaurent # Posté le 05/09/2011 à 19:10:40
Avatar

re-bonjour, à la fin de ce tuto, cysboy explique comment exporter son code source en .jar. Cependant j'ai remarqué que dès qu'un projet contenait une image, l'exportation n'en prend pas compte, même si l'on coche cette image dans la première page d'exportation, le fichier .jar résultant ne l'intègre pas (sans pour autant générer un beug)
J'aimerai bien (si quelqu'un sait) savoir comment faire en sorte que l'exportation prenne compte des image (essayez par exemple avec le chapitre 5 où le code source crée des boutons dynamiques)
Hors ligne neuronefumant # Posté le 10/01/2012 à 10:24:12

Hello, et bravo Cysboy pour ce tuto, excellent ! :D

Je voudrais juste faire une petite remarque sur le code de la calculette, une erreur toute bête et facile à corriger à l'aide d'un boolean et peut être d'une seconde variable chiffre.

Le code ne respecte pas la priorité des opérateurs
faites 2+2*3 sur la calculette et vous obtiendrez... 12 au lieu de 8 o_O

Mais sinon, super tuto !!! Merci beaucoup :)
Hors ligne Anaroyondo # Posté le 29/01/2012 à 20:22:08

Super tuto, jusqu'à ce TP :s
Aucun rapport avec les précédents chapitres et totalement incompréhensible pour un vrai zéro : un paquet de nouvelles méthodes non expliquées, aucun commentaire, une architecture sans lien avec ce qui est enseigné...
Je suis assez déçu par rapport au reste du tuto qui est excellent, Cysboy, si tu me lis, ce serait vraiment génial de refaire une petite correction de ce TP en plus détaillé :-) Mais un énorme bravo pour le reste !
Hors ligne leRoiDi # Posté le 20/04/2012 à 13:22:06
Avatar

Bravoooooooooo =))
Hors ligne akrouti # Posté le 06/05/2012 à 13:12:04
Avatar

Lorsque je transforme un projet a un fichier jar puis .exe lorsque je l’exécute sur mon pc, ça va ça marche, mais sur un autre ordinateur il me dit q'un fichier .dll manquant.
Merci d'avance.

Voir tous les commentaires