horloge universelle
Transcription
horloge universelle
POO et Java TP5 HORLOGE SYNCHRONISEE SUR LE WEB Ce TP est constitue l'évaluation principale des TPs Java. Buts poursuivis par ce TP Assimiler la programmation événementielle Utiliser la programmation socket Assimiler les mécanismes de communications entre objets. Horloge à programmer Lire les diagrammes UML. Sujet Il s'agit de réaliser une horloge synchronisée chaque jour par l'horloge atomique de Boulder dans le Colorado. Cette horloge est accessible à l'adresse : time-A.timefreq.bldrdoc.gov sur le port NTP (port 13) L'IHM dessinée par Visual Editor est fournie. Elle comporte : Un label : labelTime affichant la date et l'heure au format hh:mm:ss Un combo : choiceFuseauHoraire permettant de choisir le fuseau horaire. Le programme comporte les classes suivantes sur les quelles vous aurez à intervenir : La classe de démarrage Horloge : IHM responsable de l'affichage de l'horloge. Cette classe matérialise le boitier de l'horloge. Elle est la classe principale de l'application. Classe Mécanisme Classe contenant le mécanisme de l'horloge. Cette classe est instanciée par la classe Horloge. Le tic-tac de l'horloge est réalisé par un objet de la classe Timer. Classe HeureGMT Cette classe est responsable de l'acquisition de l'heure GMT en secondes depuis minuit en utilisant le serveur NTP du site de Boulder. Elle est utilisée pour mettre à jour l'horloge lors du démarrage de l'application et pour resynchroniser l'horloge toutes les 24H. WindowAdapter HeureGMT File fichier d'entrée fuseauxTriés.txt Anonyme1 Frame Tuer l’application dans WindowClosing() FileReader Lire 1 car. BufferedReader Régler période 1 seconde Mécanisme Lire 1 ligne Signaler « Fichier fuseauxTriés.txt NON trouvé » Timer Démarrer Démarrer Mémoriser les fuseaux horaires Choice Obtenir l’heure GMT Tic MAJ et obtenir l’heure Anonyme2 Horloge Afficher l’heure Afficher l’heure Label ActionListener Figure 1: relations entre classes. En couleur les classes à définir (hors V.E.) Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 1/14 POO et Java Description détaillée des classes ATTENTION : certains éléments faisant partie des questions posées ne figurent pas dans ces descriptions. 1. Classe Horloge Object java.awt.Component java.awt.Container java.awt.Window java.awt.Frame Horloge IHM affichant l'horloge Field Summary private Choice choiceFuseauHoraire Permet de choisir le fuseau horaire. (package private) int décalageFuseau Décalage fuseau horaire en secondes. private Label labelTime Label dans lequel est inscrit l'heure par la méthode afficheHeure appelée par une méthode de la classe Mecanisme. private static long serialVersionUID Généré par V.E. Constructor Summary Horloge() . Constructeur par défaut Method Summary private private Choice getChoiceFuseauHoraire() Instancie le contrôle choiceFuseauHoraire Détermine, dans l'écouteur, le décalage horaire en secondes et le mémorise dans l'attribut décalageFuseau. Met à jour le booléen fuseauChanged. void getDecalageFuseau(int item) Détermine le décalage horaire en secondes à partir de l'item dont le numéro est passé en paramètre et le mémorise dans l'attribut décalageFuseau. private void initialize() Généré par V.E. static void main(java.lang.String[] arg) Instancie l'horloge et l'affiche. Field Detail serialVersionUID private static final long serialVersionUID choiceFuseauHoraire private Choice choiceFuseauHoraire Permet de choisir le fuseau horaire. décalageFuseau int décalageFuseau Décalage fuseau horaire en secondes. Initialisé par la classe Horloge et utilisé par la classe Mecanisme. labelTime private Label labelTime Label dans lequel est inscrit l'heure par la méthode afficheHeure appelée par un objet de la classe Mecanisme. Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 2/14 POO et Java Constructor Detail Horloge public Horloge() Constructeur par défaut. Appelle le constructeur du parent. Met en place les contrôles (appel de initialize()). Lit le fichier fuseauxTries.txt contenant les fuseaux horaires. et les charge dans le contrôle choiceFuseauHoraire. Throws: IOExeption, Exception. Method Detail initialize private void initialize() Généré par V.E. Met en place les contrôles. getDecalageFuseau private void getDecalageFuseau(int item) Détermine le décalage horaire en secondes à partir de l'item dont le numéro est passé en paramètre et mémorise le décalage dans l'attribut décalageFuseau. Parameters: item - : numéro de l'tem sélectionné dans le contrôle getChoiceFuseauHoraire private java.awt.Choice getChoiceFuseauHoraire() Instancie le contrôle choiceFuseauHoraire. Appelle decalageFuseau en lui passant l'item choisi dans le contrôle Returns: java.awt.Choice, AFFICHEHEURE public void afficheHeure(int h, int m, int s) Affiche l'heure sur le label labelTime Parameters: h, m, s main public static void main(java.lang.String[] arg) Instancie l'horloge et l'affiche. Parameters: arg - non utilisé 2. Classe Mécanisme Object Mécanisme Field Summary private private Horloge horloge . private int h, m, s private int time javax.swing.Timer timer Constructor Summary Mécanisme(Horloge theHorloge) Constructeur du mécanisme Method Summary private javax.swing.Timer createTimer() (package private) void hms() Calcule les H, M, S dans le fuseau et les mémorises dans les attributs h, m ,s void Daniel Tschirhart & Pierre Sosinski Instancie une classe anonyme contenant l'écouteur start() Lance le tic-tic (timer) TP5 Horloge synchronisée sur le Web v1.3 3/14 POO et Java Field Detail timer private javax.swing.Timer timer Référence d'un objet de la classe Timer. private int time : Heure GMT : nbr de secondes écoulées depuis minuit GMT. Ne doit être modifié que par le tic tic et par la synchronisation de l'heure. private Horloge horloge : Référence de l'objet de la horloge contenant l'IHM. private int s : Secondes private int m : Minutes GMT private int h : Heures GMT Constructor Detail public Mécanisme(Horloge theHorloge) Récupère la référence de l'horloge et la mémorise. Récupère le nb de secondes GMT depuis minuit à partir de l'horloge atomique de Boulder. Crée le timer. Parameters: theHorloge - référence de l'horloge Method Detail public void start() Lance le tic-tic (timer) void hms() Met à jour les attributs h, m, s en tenant compte du fuseau horaire. private javax.swing.Timer createTimer() Instancie une classe anonyme contenant les actions exécutée par l'écouteur à chaque tic horloge Returns: Timer (référence vers un objet de cette classe) Veillez noter les points suivants : l'heure GMT (la référence de temps) est mémorisée dans int time. Cette valeur ne doit être modifiée par aucun décalage horaire sinon il devient impossible déterminer l’heure locale en cas de changement multiple de fuseau. Seul le battement du timer de 1 seconde a le droit de modifier time. le décalage horaire n'intervient que pour calculer h,m,s et rien d'autre l'heure d'été que l'on valide ou non, n'intervient qu'au dernier moment : celui de l'affichage de hms dans la méthode afficheHeure (car seule horloge connait la valeur du CheckBox) Exemples de valeurs des décalages horaires en secondes Décalage 0h 3h 3 h 30 10 h 12 h -10 h -12 h - 3 h 30 Secondes affichées 0 10800 12600 36000 43200 50400 43200 73800 Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 4/14 POO et Java Diagramme de séquence du constructeur de Mécanisme créer (theHorloge) :Mécanisme Objet anonyme de la classe Mécanisme Message trouvé. Cela veut simplement dire que l'objet appelant ne nous intéresse pas ici. La classe HeureGMT ne possède qu'une méthode statique get(). mémoriser theHorloge HeureGMT L'appel de la méthode privée CreateTimer est ici mis en exergue par 3 éléments : - l'auto-message "createTimer", - la barre d'activation grisée, qui se détache de la ligne de vie de l'objet :Mécanisme - l'auto-message "retourne t" qui indique la fin de l'exécution de createTimer et la reprise du contrôle dans le constructeur de Mécanisme. Le constructeur ne fait alors rien d'autre que de rendre le contrôle à son appelant. time = get(theHorloge) calculer s, m, h = f(time) timer = createTimer() créer() créer(1000, aL) Message perdu. Cela veut simplement dire que l'objet appelant ne nous intéresse pas ici retourne Daniel Tschirhart & Pierre Sosinski aL : ActionListener t : Timer retourne t Ligne de vie de l'objet :Mécanisme TP5 Horloge synchronisée sur le Web v1.3 5/14 POO et Java 3. Classe HeureGMT. Cette classe expose une méthode statique get permettant d'obtenir le nombre de secondes écoulées depuis minuit GMT en récupérant l'heure sur le serveur NTP de Boulder dans le Colorado. Object HeureGMT Method Summary static int get(Horloge appli) Cette fonction statique lit l'heure sur le serveur NTP de Boulder et retourne le nombre de secondes GMT écoulées depuis minuit. Reçoit une référence de l'IHM. UnknownHostException Créer un accès à l’horloge atomique de Boulder Signaler « Serveur NON trouvé » HeureGMT Signaler « Pas de mise à l’heure » Socket Lire 1 ligne BufferedReader Lire 1 car. InputStreamReader Lire Horloge IOException Obtenir l’heure GMT Mécanisme Diagramme de classes montrant les liens sémantiques entre les classes intervenant dans l'obtention de l’heure GMT grâce à l’horloge atomique de Boulder Figure 2: liens entre classes intervenant dans l'obtention de l'heure à l'aide du serveur de Boulder Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 6/14 POO et Java Diagramme de séquence montrant la lecture de l'heure GMT sur le site de Boulder La classe HeureGMT et sa méthode de classe get (static) 1 objet Horloge : Horloge Bloc try-catch bâti à l'aide d'un cadre d'interaction stéréotypé. Ceci n'est pas de l'UML normalisé mais permet de représenter utilement une structure de contrôle utilisée en C++, java et C#. HeureGMT get(this) try créer("time-A.timefreq.bldrdoc.gov",13) s : Socket is = getInputStream() créer(is) isr : InputStreamReader créer(isr) in : BufferReader loop line = readLine() break [line == null] [line.lenght > 30] opt ts = extrait l'heure de la ligne close() close() catch [UnknownHostException [UnknownHostExceptione]e] setTitle("Serveur non trouvé") [IOException e] setTitle("Pas de mise à l'heure") retourne ts Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 7/14 POO et Java Travail demandé. Travail préparatoire 1. Familiariser vous avec l’horloge (répertoire TP5 sur le serveur de l’école) 2. Lancer eclipse, créer un projet TP5 avec répertoires séparé pour les fichiers .java et les fichiers .class 3. Au choix Décompacter l’archive fournie fourni sur le réseau de l'école dans un dossier temporaire puis copier le contenu de ce dossier dans votre répertoire TP5. Ou décompacter l’archive fournie sur votre site de cours dans un dossier temporaire puis copier le contenu de ce dossier dans votre répertoire TP5. 4. Actualiser votre projet. Rédaction des classes 1. Classe Horloge Attributs de la classe : /** Contrôle permettant de choisir le fuseau horaire. */ private Choice choiceFuseauHoraire = null; /** * Décalage fuseau horaire en secondes.<br> * Initialisé par la méthode getDecalageFuseau et utilisé par la fonction hms<br> * de la classe Mecanisme. */ int décalageFuseau = 0; /** * Indique que le fuseau horaire a été changé<br> * Peut être utilisé facultativement par la classe Mécanisme pour minimiser la * consommation d'énergie. */ boolean fuseauChanged = false; /** Label sur lequel est inscrit l'heure par la méthode afficheHeure */ private Label labelTime = null; a) Affichage de l'heure : fonction afficheHeure. Compléter la fonction afficheHeure, lancer l’application Horloge et faites valider par votre professeur. public void afficheHeure(int h, int m, int s) { // Afficher l'heure fourni par les paramètres formels sur le label // time dans le format HH:MM:SS // Pour la validation de cette question, l'appel de cette fonction // est effectué à la fin du constructeur de cette classe. // Supprimer cet appel après validation. } b) Constructeur Ce constructeur a pour but : d’initialiser le contrôle choiceFuseauHoraire avec le contenu du fichier fuseauxTries.txt, d’instancier la classe Mécanisme en lui passant la référence de l’objet courant et de lancer le tic-tac par la méthode start(). Compléter le constructeur, tester et faites le valider par votre professeur. Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 8/14 POO et Java public Horloge() { super(); initialize(); // Toutes les exceptions sont traitées ci-dessous. // Attention tout code hors bloc try-catch arrête l’application si une // une exception est lancée. try { // Instancier un objet in permettant de lire le fichier "fuseauxTries.txt" // lignes par lignes // Ajouter ligne par ligne le contenu du fichier dans le contrôle // choiceFuseauHoraire (méthode add de l’objet choiceFuseauHoraire // Instancier et lancer le mécanisme de l'horloge } catch (IOException e) { // Inscrire dans le titre de la fenêtre "fuseauxTries non trouvé" } catch (Exception e) { // Inscrire dans le titre de la fenêtre "Erreur de lecture" } } c) Fonction getDecalageFuseau Cette méthode est appelée par l’écouteur du contrôle choiceFuseauHoraire avec comme paramètre effectif l’item sélectionné dans le contrôle. A l’aide de cet item, la méthode récupère la chaine de caractère spécifiant le fuseau et en extrait les informations de décalage. Comme le décalage horaire est toujours situé à la même position dans la chaine, une simple méthode substring permettra de l’extraire. Compléter la fonction getDecalageFuseau, tester et faites le valider par votre professeur. Utiliser le tableau de test donné au bas de la page 4. Nota : les décalages peuvent contenir des minutes : (GMT+05:45) Katmandou ou peuvent être négatifs (GMT-03:30) Terre-Neuve private void getDecalageFuseau(int item) { // Récupérer le fuseau horaire dans le contrôle choiceFuseauHoraire par getItemd // et le mémoriser dans une chaine de caractère fuseau. // Extraire les minutes et les heures à l’aide de la fonction d'instance substring // l'objet fuseau. // Calculer le décalage horaire en secondes et mémoriser le résultat du calcul // dans l'attribut décalageFuseau. // Attention les décalages peuvent être négatifs. // Exemple un décalage de -2H correspond à 23H si l'heure GMT // est 01H soit un décalage positif de +22H // VALIDATION: afficher le décalage en secondes sur la console. // puis mettre cette ligne en commmentaires. System.out.println(décalageFuseau); } Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 9/14 POO et Java 2. Classe HeureGMT. Cette classe expose une méthode statique get permettant d'obtenir le nombre de secondes écoulées depuis minuit GMT en récupérant l'heure sur le serveur NTP de Boulder dans le Colorado. Compléter la fonction get de la classe HeureGMT et faites la valider par votre professeur. static public int get(Horloge appli) { int ts = 0; // Heure GMT en secondes try { // Instancier un objet sock de la classe Socket sur le serveur NTP de Boulder Socket s = new Socket("time-A.timefreq.bldrdoc.gov", 13); // Utiliser cet objet pour obtenir un flux lu lignes par lignes BufferedReader in = new BufferedReader( new InputStreamReader(s.getInputStream())); while (true) { // Lire une ligne sur le flux String line = in.readLine(); // Si null quitter la boucle (break) if (line == null) break; // Si la ligne contient plus de 30 caractères Alors if (line.length()> 30) { // Mise au point : afficher la ligne sur la console. // Mémoriser dans ts le nombre de secondes écoulées depuis minuit. // Nota : les secondes sont situées aux positions 21..23 de la ligne line // les minutes aux positions 18..20, les heures aux positions 15..17 } } // Clore le socket // Clore le flux } // Gérer les exceptions en écrivant un message sur la barre // de titre de l'horloge suivant figure page 6. // catch ... catch (Exception e) // dernier catch { // Écrire le message "Erreur inconnue sur le titre de la fenêtre horloge } return ts; } Validation : effectuer un appel de cette fonction dans le constructeur de l’horloge et afficher sur la console la valeur retournée (commenter ensuite cet appel). Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 10/14 POO et Java 3. Classe Mécanisme. Lire la note au bas de la page 4 La classe Mécanisme contient le mécanisme de l’horloge. Le système d’échappement est assuré l’écouteur de l’objet Timer. La méthode hms()constitue le système d’engrenages permettant de calculer l’heure et les minutes. Veuillez noter que c’est le système d’échappement qui entraine les engrenages. Attributs de la classe : /** Référence d'un objet de la classe Timer. */ private Timer timer; /** Nbr de secondes écoulées depuis minuit.*/ private int time; /** Référence de l'objet de la horloge contenant l'IHM.*/ private Horloge horloge; /** Heures, minutes, secondes */ private int s, h, m; a) Constructeur Le constructeur reçoit comme paramètre la référence de l’horloge. Cette référence permettra l’accès aux attributs et aux méthodes publics dans la classe Horloge. Il initialise ensuite l’attribut time contenant les secondes écoulées depuis minuit GMT à l’aide de la méthode statique get de la classe HeureGmt, puis crée ensuite le timer ; Compléter le constructeur, tester et faites valider par votre professeur. public Mécanisme(Horloge theHorloge) { // Mémoriser theHorloge dans un attribut refHorloge // Récupérer l'heure GMT en secondes (fonction statique get, classe HeureGMT) // Créer le Timer timer = createTimer(); } b) Fonction hms Cette méthode appelée par l’écouteur du timer, calcule les heures, minutes et secondes locales. Compléter la fonction hms, tester et faites la valider par votre professeur. void { // // // // // // } hms() Incrémenter les secondes GMT Si minuit remettre l'horloge à l'heure en relisant l'heure GMT sur l'horloge de Boulder Calculer les secondes écoulées depuis minuit en tenant compte du décalage horaire Calculer les H, M, S et mettre à jour les attributs correspondants Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 11/14 POO et Java c) Fonction createTimer Cette méthode créer une instance anonyme contenant l’écouteur abonné au timer. Compléter l'écouteur, tester et faites valider l'application par votre professeur. private Timer createTimer () { ActionListener action = new ActionListener () { // Le tic-tac : méthode appelée à chaque tic du timer public void actionPerformed (ActionEvent event) { // Appelle la fonction hms() // Appelle la fonction afficheHeure(h, m, s) de la classe horloge } }; return new Timer (1000, action); // Timer de période 1000 ms } 4. Fuseau horaire par défaut Dans la version actuelle, le fuseau horaire par défaut est premier fuseau présent dans le contrôle. Modifier la classe Horloge pour que le fuseau par défaut soit celui de Paris. 5. Heure d'été Dans la version actuelle, l'horloge ne tient pas compte de l'heure d'été. On se propose d'ajouter une case à cocher sur de la fenêtre (Chekbox AWT) de façon à ajouter une heure dans la fonction afficheHeure lorsque celle-ci est cochée. Noter que l'heure doit rester dans l'intervalle 0..23. Le contrôle Checkbox peut déclencher un événement chaque fois que son état est modifié et son état (coché ou non) peut être testée par la fonction membre getState(). Ajouter cette fonctionnalité à l'horloge en utilisant WindowsBuilder Editor note1 , tester et faites valider l'application par votre professeur. 6. BONUS : Extraction des fuseaux horaire de la base de registre La base de registre de Windows contient toutes les informations concernant les différents fuseaux horaires. Ces informations ont été enregistrées dans un fichier fuseau.reg. En voici un extrait : Note 1 : sélectionner le fichier Horloge.java dans le navigateur de projet puis faire un clic droit et valider ouvrir avec WindowBuider Editor. Sélectionner ensuite la vue dans l’onglet Design. Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 12/14 POO et Java [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones] [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Afghanistan Standard Time] "TZI"=hex:f2,fe,ff,ff,00,00,00,00,c4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,\ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 "MUI_Display"="@tzres.dll,-460" "MUI_Dlt"="@tzres.dll,-461" "MUI_Std"="@tzres.dll,-462" "Display"="(GMT+04:30) Kaboul" "Dlt"="Afghanistan (heure d'été)" "Std"="Afghanistan" Le fuseau horaire est spécifié à la ligne "Display"=". Extraire toutes ces informations de façon manuelle est long et fastidieux et nécessite un tri manuel des fuseaux en fonction du décalage horaire. On se propose d'extraire ces informations à l'aide un programme indépendant en mode console : FuseauExtract.java o Le diagramme de classes montrant les liens sémantiques entre les classes intervenant dans l'extraction des fuseaux horaires depuis le fichier de données brutes "fuseaux.reg" est donnée page suivante. o L'extraction des fuseaux horaire est effectuée dans la fonction main dont l'algorithme est donné cidessous : import java.io.*; import java.util.*; import java.util.regex.*; // Extrait les fuseaux horaire à partir des informations fournies // par le fichier fuseaux.reg obtenu par la base de registre de Windows. // Fournit un fichier contenant les fuseaux triés. public class FuseauExtract { public static void main(String[] args) { try { // Instancier un objet in permettant de lire le fichier fuseaux.reg // ligne par ligne // Instancier un objet liste de classe List à l'aide d'une classe // d'implémentation (S.D.F.). On choisira la classe la plus appropriée. // // // // // // // // // // // Lire le fichier ligne par ligne. Ne conserver que la ligne contenant "Display"=" Extraire de cette ligne le fuseau horaire (utiliser substring) et l'ajouter à la liste Trier la liste Instancier un objet out permettant d'écrire la liste dans un fichier fuseaux.txt Enregistrer chaque élément de la liste dans le fichier fuseaux.txt en ajoutant un retour à la ligne et un saut de ligne ("\r\n"). Nota : on utilisera la boucle forEach de Java 5. Fermer le fichier out } // Autres catch catch (Exception e) { System.out.println(e); } } } Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 13/14 POO et Java Nota : les fuseaux ne comportant pas de décalage horaire ne portent pas de mention horaire. (GMT) Casablanca (GMT) Heure de Greenwich : Dublin, Édimbourg, Lisbonne, Londres (GMT) Monrovia, Reykjavik On ajoutera ces informations de façon manuelle. Diagramme de classes montrant les liens sémantiques entre les classes intervenant dans l'extraction des fuseaux horaires depuis le fichier de données brutes "fuseaux.reg". File Fichier de sortie fuseauxTriés.txt fichier d'entrée fuseaux.reg FileReader FileWriter Lire 1 car. Ecrire 1 car. BufferedReader BufferedWriter Lire données brutes 1 ligne à la fois Pattern Compiler l’expression régulière (pattern) "Display"=" Analyser une ligne Indiquer le résultat de l’analyse de la ligne La ligne contient-elle le pattern ? Matcher Ecrire fuseaux triées 1 ligne à la fois FuseauExtract Ecrire fuseau horaire List Lire les fuseaux dans l'ordre Trier les fuseaux Données à trier Collection Figure 3 : diagramme de classes montrant les liens sémantiques entre les classes intervenant dans l'extraction des fuseaux horaires depuis le fichier de données brutes "fuseaux.reg" Compléter la fonction main, tester et faites la valider par votre professeur. Daniel Tschirhart & Pierre Sosinski TP5 Horloge synchronisée sur le Web v1.3 14/14