Gestion simple des entrées/sorties : clavier/écran

Olivier Capuozzo

25-nov-2002

Résumé

Initiation à une gestion simple d'interface utilisateur (clavier/ecran) en Java.

Exemple de création d'un paquetage (package) utilitaire.


Table des matières

Introduction
Version pseudo-code
Analyse
Conception du package org.vincimelun.util
Classe org.vincimelun.util.Console
Classe org.vincimelun.util.Date
TesterAge : Version console (UITesterAge.java)
TesterAge : Version graphique (GUITesterAge.java)
Conclusion

Introduction

Cette fiche technique montre comment simplement implémenter une interaction entre un utilisateur et un programme écrit en Java.

Cette initiation s'appuie sur un exemple, représenté par le cas d'utilisation simplifié suivant :

  • Cas d'utilisation : Connaître un âge

    • Acteur : un utilisateur lambda

    • Scénario typique

      1. L'utilisateur saisit une date de naissance

      2. Le système affiche l'age correspondant à la date reçue

Nous proposerons successivement une version en mode console (interface de type texte) et une en mode graphique.

Version pseudo-code

Considérons le programme suivant :

    programme testerAge 

      variables utilisées
         age        : entier
         dateNaiss  : chaîne de caractères

      début
         
         afficher("Entrez votre date de naissance : ")
         dateNaiss <- lireClavier()
         age <- getAge(dateNaiss);
         afficher("Bonjour ", nom, ", vous avez ", age, " ans");
         
      fin    
    

Analyse

Dans le respect du principe de "séparation des responsabilités", nous concevrons les composants suivants :

  • Un package utilitaire, nommé org.vincimelun.util, qui contiendra :

    • La classe Console

      Une classe utilitaire gérant les entrées au clavier en mode console.

    • La classe Date

      Offre des services liés à des informations de type date. Par exemple on y trouvera une fonction nous permettant de connaître automatiquement un age en fonction d'une date donnée.

  • UITesterAge

    Cette classe représentera une version console du cas d'utilisation testerAge, décrit par le pseudo-code ci-dessus.

  • GUITesterAge

    Cette classe représentera une version graphique du cas d'utilisation testerAge, décrit par le pseudo-code ci-dessus.

Ce que nous dit ce diagramme : Il y a deux applications (UITesterAge et GUITesterAge) qui dépendent du package org.vincimelun.util. UITesterAge utilise la classe Console, mais pas GUITesterAge.

Conception du package org.vincimelun.util

Classe org.vincimelun.util.Console

Nous gérons les entrées et sorties console par une gestion des flux standard.

package org.vincimelun.util;

import java.io.*;

public class Console {
  /**
    Affiche le message msg puis mémorise les entrées clavier de l'utilisateur
    jusqu'à ce qu'il saisisse un retour chariot.
    
    @return le texte saisi par l'utilisateur
  */
  static public String getString(String msg) {
     String res ="";
     System.out.print(msg);
     BufferedReader clav = new BufferedReader(new InputStreamReader(System.in));
     try {
       res = clav.readLine();
     }
     catch (IOException e) {
       System.out.println(e);
     }
     return res;
  }

  static public void main(String[] args) {  }
  }

Cette classe n'est valable que si l'entrée standard correspond au clavier et la sortie standard à la console vidéo.

Classe org.vincimelun.util.Date

On utilise la classe Calendar du package java.util et la classe java.sql.Date

package org.vincimelun.util;

import java.util.Calendar;

public class Date {

  static public int getAge(String dateNaissance) {
    Calendar now = Calendar.getInstance();
    Calendar dateNaiss = Calendar.getInstance();

    dateNaiss.setTime(java.sql.Date.valueOf(dateNaissance));
    
    return now.get(Calendar.YEAR) - dateNaiss.get(Calendar.YEAR);
  }

  static public void main(String[] args) {
    System.out.println(org.vincimelun.util.Date.getAge("2002-11-10"));
  }
}
  

Conformément aux recommandations de l'API, nous utilisons la classe abstraite Calendar pour la gestion du temps. Cette classe a une méthode (getInstance) dont le rôle est de fournir une instance d'une sous-classe concrète de Calendar, qui tienne compte des spécificités locales.

Nous utilisons java.sql.Date dans le seul but de traduire la date saisie par l'utilisateur en une valeur de type Date afin d'initialiser la valeur de l'objet référencé par dateNaiss.

TesterAge : Version console (UITesterAge.java)

import org.vincimelun.util.Date;
import org.vincimelun.util.Console;
import java.io.*;

public class UITesterAge {

  public void run() {
    String dateNaiss = 
      Console.getString("Entrez votre date de naissance (aaaa-mm-jj) : ");
    
    int age = Date.getAge(dateNaiss);
      
    System.out.println("Vous avez " + age + " ans");
  }

  static public void main(String[] args) {
    UITesterAge test = new UITesterAge();
    test.run();
  }
}

Exemple :

[kpu@kpu seance-7]$ java UITesterAge
Entrez votre date de naissance (aaaa-mm-jj) : 1981-07-2
Vous avez 21 ans

TesterAge : Version graphique (GUITesterAge.java)

Nous nous appuyons ici sur la classe JOptionPane du package swing, et tout particulièrement à deux méthodes static :

  • showInputDialogPrompt pour des entrées au clavier.

  • showMessageDialog comme fenêtre d'information à destination de l'utilisateur.

    La boîte de dialogue est placée au centre de son parentComponent. Lorsque celui n'est pas référencé (valeur du premier argument à null), la boîte de dialogue est alors centrée à l'écran.

import org.vincimelun.util.Date;
import javax.swing.*;

public class GUITesterAge {

  public void run() {
    String dateNaiss = 
      JOptionPane.showInputDialog(
        "Entrez votre date de naissance (aaaa-mm-jj) : ");
      
    int age = Date.getAge(dateNaiss);
      
    JOptionPane.showMessageDialog(null, "Vous avez " + age + " ans");
  }   

  static public void main(String[] args) {
    GUITesterAge test = new GUITesterAge();
    test.run();
  }
}
  

Exemple :

[kpu@kpu seance-7]$ java GUITesterAge

Conclusion

Java ne fournit pas en standard une classe qui simplifie la gestion des entrées au clavier. Nous avons montré comment ajouter cette fonctionalité au langage, en concevant un package utilitaire (composé de méthodes static).

Pour les besoins de l'exemple, nous avons enrichi le package utilitaire d'une classe Date.

Voici les principales étapes pour la construction d'un package physique.

  1. Compiler dans un même répertoire toutes les classes du package.

  2. Créer le package .jar avec l'outil jar. Exemple de construction d'un package nommé ldv.jar.

    [kpu@kpu seance-7]$ jar -cvfM ldv.jar org/
    ajout : org/(entrée = 0) (sortie = 0)(0% stocké)
    ajout : org/vincimelun/(entrée = 0) (sortie = 0)(0% stocké)
    ajout : org/vincimelun/util/(entrée = 0) (sortie = 0)(0% stocké)
    ajout : org/vincimelun/util/Date.class(entrée = 754) (sortie = 480)(36% compressés)
    ajout : org/vincimelun/util/Console.class(entrée = 869) (sortie = 509)(41% compressés)
    [kpu@kpu seance-7]$   
       

Il ne vous reste plus qu'à spécifier ce package au classpath lors de la compilation et de l'exécution d'une application dépendante de ce package. Exemple.

[kpu@kpu test]$ javac -classpath ldv.jar:. UITesterAge.java
[kpu@kpu test]$ java -classpath ldv.jar:. UITesterAge
Entrez votre date de naissance (aaaa-mm-jj) : 2000-1-1
Vous avez 2 ans
[kpu@kpu test]$  
  

Et voilà, le tour est joué...

Vous remarquerez que l'on spécifie un ensemble de chemins à classpath : ldv.jar et . (point). Le point servant à référencer le répertoire courant (package par défaut). La version proposée fonctionne sous Linux, sous Windows vous écririez :

[c:\test] javac -classpath ldv.jar;. UITesterAge.java
[c:\test] java -classpath ldv.jar;. UITesterAge
Entrez votre date de naissance (aaaa-mm-jj) : 2000-1-1
Vous avez 2 ans
[c:\test]   

Le séparateur de chemin est ; (point-virgule et non deux-points).