package fr.univParisDiderot.phys; import javax.swing.JOptionPane; import java.awt.HeadlessException; import java.awt.Frame; import java.awt.GraphicsEnvironment; import java.io.*; import java.util.StringTokenizer; /** * La classe <code>ES</code> contient quelques méthodes pour faire des * <b>E</b>ntrées/<b>S</b>orties simplement. * * <P>Voici un exemple d'utilisation de <code>ES</code>: * <PRE> * import static fr.univParisDiderot.phys.ES.*; * * public class Test { * public static void main(String args[]) { * println("coucou"); * println(3.14); * messageDialog("oh c'est joli!"); * float x = stringToFloat(inputDialog("valeur du paramètre x?",1.41)); * println("paramètre x = "+x); * println("Maintenant dans le terminal: valeur du paramètre y?"); * float y = stringToFloat(readToken()); * println("paramètre y = "+y); * exit(); * } * } * </PRE> * * @author Adrian Daerr (adrian.daerr'at'univ-paris-diderot.fr), * inspiré par les fonctionnalités de <a * href="http://www.liafa.jussieu.fr/~yunes/deug/">la classe DEUG de * Jean-Baptiste Yunès</a> (Jean-Baptiste.Yunes'at'liafa.jussieu.fr) * @version 0.1 */ public class ES { // on en a besoin d'une (même invisible) comme parent de nos dialogues... static Frame frame=new Frame(); // et on ouvre l'entrée standard pour d'éventuelles lectures static LineNumberReader input = new LineNumberReader(new InputStreamReader(System.in)); static StringTokenizer tokenizer = null; /** Lit une ligne entière de texte sur l'entrée standard. Renvoie * la chaîne de caractères que l'utilisateur à tapée avant * d'appuyer sur la touche <Entrée>. */ public static String readLine() { String s; try { s = input.readLine(); } catch (IOException e) { yaErreur("Erreur lors de la lecture de l'entrée standard.",e); return null; } return s; } /** Lit un mot de texte sur l'entrée standard. Plutôt que de lire * ligne par ligne, cette méthode lit mot par mot, s'arrêtant à * chaque espace ou retour à la ligne rencontré. Pratique si on * veut lire la valeur d'une variable par exemple:<br /> * * <code>float y = stringToFloat(readToken());</code> */ public static String readToken() { while (tokenizer==null || !tokenizer.hasMoreTokens()) { tokenizer = new StringTokenizer(readLine()); } return tokenizer.nextToken(); } /** Affiche un objet sur la sortie standard. Un objet peut être un * entier, un flottant, etc. */ public static void print(Object o) { System.out.println(o); } /** Affiche un objet sur la sortie standard, et revient à la * ligne. Tout est un objet en Java (un entier, un flottant, * etc.), donc cette fonction peut afficher n'importe quoi. */ public static void println(Object o) { System.out.println(o); } /** Affiche du texte sur la sortie standard. */ public static void print(String s) { System.out.println(s); } /** Affiche du texte sur la sortie standard, et revient à la ligne. */ public static void println(String s) { System.out.println(s); } /** Affiche du texte dans une boîte de dialogue. L'utilisateur * doit fermer le dialogue (en cliquant sur un bouton, ou en * fermant la fenêtre) avant que la fonction retourne et que le * programme puise continuer. * * @see javax.swing.JOptionPane#showMessageDialog * @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/dialog.html">How to make Dialogs (Java tutorial)</a> * @param s Le message à afficher dans le dialogue */ public static void messageDialog(String s) { try { JOptionPane.showMessageDialog(null, s); } catch (HeadlessException e) { yaErreur("Erreur: pas d'écran graphique ?\n"+ "Le message suivant n'a pas pu être affiché "+ "dans un dialogue:\n"+s,e); } return; } /** Demande de l'information à l'utilisateur dans une boîte de * dialogue. Le texte tapé par l'utilisateur est renvoyé sous * forme de String, on peut utiliser une autre fonction de cette * bibliothèque pour le convertir. Pour une conversion en float * par exemple:<br /> * * <code>float x = stringToFloat(inputDialog("valeur du paramètre * x?",3.14));</code> * * @see javax.swing.JOptionPane * @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/dialog.html">How to make Dialogs (Java tutorial)</a> * @param question Question affichée dans le dialogue * @param valeurInit valeur par défaut du texte * @return Texte entré par l'utilisateur */ public static String inputDialog(String question, Object valeurInit) { String s; try { s = JOptionPane.showInputDialog(null, question, valeurInit); } catch (HeadlessException e) { yaErreur("Erreur: pas d'écran graphique ?\n"+ "La question suivante n'a pas pu être posée "+ "dans un dialogue:\n"+question,e); return null; } return s; } /** Affiche une fenêtre de dialogue avec la question donnée en * argument, et deux boutons OUI/NON de réponse. Si l'utilisateur * choisi de répondre oui, cette méthode renvoie la valeur vrai. * Si l'utilisateur choisi non ou qu'une erreur survient, la * méthode renvoie la valeur faux. * * @return true pour le bouton YES, false pour le bouton NO */ public static boolean confirmDialog(String question) { boolean reponse=false; try { int n = JOptionPane.showConfirmDialog(null, question, "Question...", JOptionPane.YES_NO_OPTION); reponse = (n==JOptionPane.YES_OPTION); } catch (HeadlessException e) { yaErreur("Erreur: pas d'écran graphique ?\n"+ "La question suivante n'a pas pu être posée "+ "dans un dialogue:\n"+question,e); } return reponse; } /** Convertit du texte en un nombre flottant de type double. Tente * d'interpréter la chaîne de caractères donnée en entrée comme un * nombre à virgule flottante de double précision. Si la * conversion échoue, un message d'erreur est affiché sur la * sortie erreur standard. */ public static double stringToDouble(String s) { double res; try { res=Double.parseDouble(s); } catch (Exception e) {// il y a eu un problème yaErreur("Erreur à la conversion en (double) de: "+s,e); return (double)0; } return res; } /** Convertit du texte en un nombre flottant de type float. Tente * d'interpréter la chaîne de caractères donnée en entrée comme un * nombre à virgule flottante de simple précision. Si la * conversion échoue, un message d'erreur est affiché sur la * sortie erreur standard. */ public static float stringToFloat(String s) { float res; try { res=Float.parseFloat(s); } catch (Exception e) {// il y a eu un problème yaErreur("Erreur à la conversion en (float) de: "+s,e); return (float)0; } return res; } /** Convertit du texte en un entier de type int. Tente * d'interpréter la chaîne de caractères donnée en entrée comme un * nombre entier. Si la conversion échoue, un message d'erreur est * affiché sur la sortie erreur standard. */ public static int stringToInt(String s) { int res; try { res=Integer.parseInt(s); } catch (Exception e) {// il y a eu un problème yaErreur("Erreur à la conversion en (int) de: "+s,e); return (int)0; } return res; } /** Convertit du texte en un entier de type long. Tente * d'interpréter la chaîne de caractères donnée en entrée comme un * nombre entier. Si la conversion échoue, un message d'erreur est * affiché sur la sortie erreur standard. */ public static long stringToLong(String s) { long res; try { res=Long.parseLong(s); } catch (Exception e) {// il y a eu un problème yaErreur("Erreur à la conversion en (long) de: "+s,e); return (long)0; } return res; } /** Devient vrai si une opération (lecture de l'entrée, * conversion) échoue. Cette variable n'est pas lisible pas * directement, il faut utiliser la méthode erreurSurvenue(). */ static boolean erreur = false; /** méthode appelée en interne quand une erreur est survenue */ static void yaErreur(String message, Exception e) { System.err.println(message); e.printStackTrace(); if (GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadless()) { System.exit(1); } else { int reponse=JOptionPane.NO_OPTION; try { reponse = JOptionPane.showConfirmDialog(frame, message+"\n\nContinuer le programme ?", "Erreur survenue", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); } catch (HeadlessException he) {/*should never reach this*/} if (reponse==JOptionPane.NO_OPTION) System.exit(1); } erreur = true; return; } /** <p>Renvoie 'vrai' si une erreur (lecture p ex dans readln(), * conversion) est survenue depuis le dernier appel à cette * méthode (ou depuis le début, si c'est le premier appel). * </p> * * <p>Exemple d'utilisation:</p> * <pre> * float y; * do {// redemander tant qu'il y a des erreurs * println("valeur du paramètre y?"); * y = stringToFloat(readToken()); * } while (erreurSurvenue()); * println("paramètre y = "+y); * </pre> */ public static boolean erreurSurvenue() { boolean reponse = erreur; erreur = false;// remettre à zéro return reponse; } /** Termine l'execution du programme. */ public static void exit() { try { input.close(); } catch (IOException e) {e.printStackTrace();} System.exit(0); } }