import javax.microedition.lcdui.*; import javax.microedition.midlet.*; // N'oubliez pas qu'en Java il faut respecter les minuscules/MAJUSCULES. /** * Classe principale de la mobilette, celle-ci calcule la consommation * d'un véhicule à partir de son kilométrage et de la quantité d'essence.
* Comme c'est une mobilette, c'est une classe dérivée de Midlet.
* Cette classe implémente les interfaces suivantes (elle définit les * méthodes de ces interfaces) : * * @author Thibaut REGNIER, mobilette@club-java.com */ public class EcoLogic extends MIDlet implements ItemStateListener, CommandListener { /** * Ecran sur lequel la mobilette est affichée.
* Vaut null au lancement (car non affectée), sera initialisée par notre * code lors du premier appel à startApp() par le système.
* Attention! display ne pourrait pas être initialisée dans * le constructeur de la classe, l'écran n'étant défini par le système * qu'à partir du moment où startApp() est appelée pour la première fois. * N'oubliez pas que certains téléphones ont 2 écrans * (ex:Nokia Communicator) et le système décide au lancement sur quel * écran on sera affiché. */ private Display display; /** * Formulaire affiché à l'écran contenant les textes et zones de saisies. */ private Form formulaire; /** * Zone de saisie contenant le nombre de kilomètres parcourus. */ private TextField kilometrageTF; /** * Zone de saisie contenant le nombre de litres d'essence consommés. */ private TextField litresEssenceTF; /** * Texte affichant le résultat de la consommation. */ private StringItem consommationSI; /** * Commande pour lancer le calcul quand l'utilisateur le décide. */ private Command calculerCommand; /** * Commande pour quitter la mobilette. */ private Command quitterCommand; /** * Prévient la mobilette qu'elle va être affichée, soit pour la * première fois, soit après après été mise en pause (pendant la réception * d'un appel téléphonique par exemple).
* Si c'est notre premier lancement (notre variable display est alors null) * on initialise tout, y compris display qui du coup ne sera plus null * si la même méthode est appelée après une pause. * @see javax.microedition.midlet.MIDlet#startApp() */ protected void startApp() throws MIDletStateChangeException { // Teste si on vient de démarrer (null) // ou si on est réveillé après une pause (non null) if (display == null) { // on vient de démarrer => initialisations. display= Display.getDisplay(this); // récupère l'écran // construit un tableau qui contiendra tous les éléments de l'écran Item[] item= new Item[3]; // Ajout des 2 zones de saisie kilometrageTF= new TextField("Kilométrage", "", 4, TextField.NUMERIC); // "Kilométrage" est le nom de la zone affiché à l'écran // "": la zone est initialement vide vide // 4 : est le nombre de caractère maximum saisissables dans la zone // TextField.NUMERIC : on ne peut saisir que des chiffres et // éventuellement le signe '-' au début. Attention la zone peut // être vide, ce qui n'est pas une valeur nuérique. item[0]= kilometrageTF; litresEssenceTF= new TextField("Litres d'essence", "", 3, TextField.NUMERIC); item[1]= litresEssenceTF; // Ajout de l'affichage du résultat consommationSI= new StringItem("Consommation (l/100km) ", "0"); // Le premier paramètre est le titre. Il est suivi de ':' sur // certains mobiles, sur d'autres il est en gras. On peut // utiliser null si on n'a pas besoin de titre. // Le 2ème est le texte à afficher après le titre. On le mettra // à jour plus tard avec la valeur calculée. item[2]= consommationSI; // Construit le formulaire formulaire= new Form("EcoLogic", item); // Nous voulons être prévenu quand il y a des saisies formulaire.setItemStateListener(this); // Construction et ajout des commandes à l'écran calculerCommand= new Command("Calculer", Command.SCREEN, 1); // "Calculer" : Texte apparaissant dans le menu du téléphone. // Ne mettez pas des textes longs (+ de 10 caractères) ils // pourraient être tronqués. // Command.SCREEN est le type de la commande. Le téléphone placera // la commande à un endroit logique suivant son type et peut // changer son texte, voir ne pas en mettre du tout. Ainsi // Command.BACK peut être affecté à une touche spéciale du // téléphone, mais ne pas apparaître à l'écran. Donner // un bon type vous garantira une ergonomie correcte sur tous les // modèles. Tricher améliorera l'usage sur 2-3 modèles et rendra // l'application non ergonomique sur des dizaines d'autres! // Ici avec Command.SCREEN on informe que la commande est relative // aux informations affichées à l'écran. Lisez la doc de la // classe Command pour connaître tous les types. // 1: c'est la priorité de la commande, 1 étant la plus importante. // Une autre commande de même type et de priorité 2 sera placée // en dessous dans les menus. Notez que les commandes peuvent // être classées par type, puis par priorité sur certains modèles // alors que d'autres calsseront seulement par priorité. formulaire.addCommand(calculerCommand); quitterCommand= new Command("Quitter", Command.EXIT, 2); formulaire.addCommand(quitterCommand); // Nous voulons être prévenu quand une commande est utilisée formulaire.setCommandListener(this); // Affiche le formulaire maintenant qu'il est configuré display.setCurrent(formulaire); } } /** * Met la mobilette en pause. Dans notre cas on ne fait pas de traitement * dans des threads en tâche de fond, donc cette méthode est vide. * @see javax.microedition.midlet.MIDlet#pauseApp() */ protected void pauseApp() { } /** * Indique à la mobilette qu'elle va être arrêtée et qu'elle doit tout * de suite libérer ses ressources (connexions réseau, fermer ses flux * vers la mémoire flash,...). Ici on n'utilise aucune ressource qui * doive être fermée donc on ne fait rien. * @see javax.microedition.midlet.MIDlet#destroyApp(boolean) */ protected void destroyApp(boolean arg0) throws MIDletStateChangeException { } /** * Appelée quand un des TextField est mis à jour par l'utilisateur, * on met alors à jour la consommation affichée.
* C'est une méthode de l'interface ItemStateListener que nous implémentons. * @param item Item dont le contenu a changé. * @see javax.microedition.lcdui.ItemStateListener */ public void itemStateChanged(Item item) { // on ne tient pas compte de l'item à l'origine du changement, // on raffraîchit dans tous les cas. calculeConso(); } /** * Calcule la consommation à partir des 2 zones de saisie et met à jour * le résultat à l'écran. * @return String La consommation si le calcul a bien eu lieu, ou * null en cas de problème (pas de saisie, division par 0). */ private String calculeConso() { String conso; String resultat; try { int km, litres; km= Integer.parseInt(kilometrageTF.getString()); litres= Integer.parseInt(litresEssenceTF.getString()); // on utilise la valeur absolue, évite pb si saisie d'un négatif // on arrondit en multipliant par 10, ajoutant 5 et divisant par 10. int consoEnDeciLitres= Math.abs((10000 * litres / km + 5) / 10); int consoEntiere= consoEnDeciLitres / 10; // construit la chaîne de caractère avec le nombre à virgule conso= consoEntiere + "," + (consoEnDeciLitres - consoEntiere * 10); // Relarquez qu'on a pas de float en CLDC 1.0 mais qu'on peut // se débrouiller sans et affciher des nombres à virgule. resultat= conso; } catch (Exception e) { // En cas d'erreur (valeur non remplie, division par 0...) // on affiche une consommation de 0; conso= "0"; resultat= null; } // on met à jour le texte. consommationSI.setText(conso); return resultat; } /** * Appelée quand l'utilisateur choisit une commande affichée à l'écran. * @param commande Command choisie par l'utilisateur. * @param ecran Displayable sur lequel la commande était présente. Dans * cette application nous n'en avons pas besoin (un seul écran). * @see javax.microedition.lcdui.CommandListener */ public void commandAction(Command commande, Displayable ecran) { if (commande == quitterCommand) { notifyDestroyed(); // on signale au système qu'on a fini } else if (commande == calculerCommand) { // on affiche une fenêtre d'information avec le résultat // ou un message d'erreur si le calcul est impossible. String conso= calculeConso(); String titre, texte; AlertType type; if (conso != null) { titre= "Résultat"; texte= "Vous avez consommé " + conso + "l/100km"; type= AlertType.INFO; // la fenêtre ser une fenêtre d'information. Certaines marques // ajoutent un bip spécial et une icône (un i vert par exemple) // D'autres marques ne tiennent pas compte du type, toutes // les fenêtres d'Alert ayant le même aspect. } else { titre= "Erreur"; texte= "Calcul impossible! Saisissez un kilométrage non nul " + "et une quantité d'essence."; type= AlertType.ERROR; } Alert alert= new Alert(titre, texte, null, type); // on veut que la fenêtre reste affichée jusqu'à ce que // l'utilisateur valide le message alert.setTimeout(Alert.FOREVER); // On demande l'affichage de l'alerte en indiquant quel écran // sera affiché ensuite (ici notre formulaire de saisie) display.setCurrent(alert, formulaire); } } }