Java logo
5 mai 2013

Mon Timer Java avec JodaTime et JFrame

Par Jean-Marc Amon

Bonjour cher lecteurs, je reviens encore avec JodaTime qui était l’objet du précédent article que vous trouverez ici. Je vais reprendre le même exercice mais cette fois avec une interface graphique.

L’exercice précédent affichait l’heure, la minute et la seconde dans la console à intervalle régulier d’une seconde donc pour une minute vous avez 60 affichages… Maintenant qu’on à le savoir faire, on va y ajouter l’esthétique.

Nous allons utiliser Swing notamment JFrame(fenêtre), JLabel(texte) et JPanel(cadre). Voici le resultat que vous devrez obtenir après exécution. N’oubliez pas d’importer JodaTime dans votre projet (voir ici).

jodatime

Je fourni le code avec la documentation pour vous aider à comprendre mais vous pouvez toujours poser des questions si vous avez des difficultés;

package com.marc.timer;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import org.joda.time.DateTime;
public class MyTimer extends JFrame {

 private static final long serialVersionUID = 1L;
 private JPanel contentPane;
//La methode main est le point d'entree de l'application
 public static void main(String[] args) {
      EventQueue.invokeLater(new Runnable() {
      public void run() {
          try {
             //On cree la fenetre
             MyTimer frame = new MyTimer();
             //On affiche la fenetre
             frame.setVisible(true);
          } catch (Exception e) {
             e.printStackTrace();
          }
      }
      });
 }

 public MyTimer() {
      //Le programme s'arrete quand l'utilisateur ferme la fenetre
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      //Juste pour fixer les dimensions de la fenetre
      setBounds(100, 100, 450, 300);
      //Le contentPane est le cadre global de la fenetre
      //tous les composant de la fenetre sont dans le contentPane
      contentPane = new JPanel();
      //On lui donne un fond blanc
      contentPane.setBackground(Color.WHITE);
      //Avec une marge intérieur (grace a un bordure vide)
      contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
      //On definit ce cadre comme etant le conteneur global de la JFrame
      setContentPane(contentPane);
      //On lui specifie un layout(sa facon de disposer ses composants)
      contentPane.setLayout(new BorderLayout());
      //Le composant qui se chargera d'afficher l'heure, la minute et la seconde selon le format 00:00:00
      screenLabel = new JLabel("00:00:00");

      //Juste pour centrer le composant
      screenLabel.setHorizontalAlignment(SwingConstants.CENTER);
      //On choisi la police et la taille de la police
      screenLabel.setFont(new Font("Tahoma", Font.PLAIN, 75));
      //On ajoute ensuite le composant dans le cadre global et on le centre (CENTER)
      contentPane.add(screenLabel, BorderLayout.CENTER);
     // On cree un autre cadre qui servira pour la date du jour
      JPanel panel = new JPanel();
     //Et on l'ajoute au sud(en bas) qu conteneur(du cadre global)
      contentPane.add(panel, BorderLayout.SOUTH);
     //On lui donne une disposition qui lui permet d'ajouter des composants en les centrant automatiquement
      panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
     //On cree alors un composant qui permet d'afficher du texte pour l'affichage de la date
      dateLabel = new JLabel("");
     //On choisi une police et sa taille
      dateLabel.setFont(new Font("Tahoma", Font.PLAIN, 16));
     //On l'ajoute alors dans le cadre qui lui est dedie
      panel.add(dateLabel);

      //Ici on cree un objet de type TimerTask et comme c'est une interface on implemente sa méthode obligatoire run
      TimerTask task = new TimerTask(){
          @Override
          public void run(){
             //On recupere la date actuelle
             date = new DateTime();

             //De la date on extrait l'heure
             int heure = date.getHourOfDay();

            //La minute
             int minute = date.getMinuteOfHour();

             //La seconde
             int seconde = date.getSecondOfMinute();

             //Le jour en lettre(ex : mardi)
             String jour = date.dayOfWeek().getAsText();

             //La date du jour
             int dateDuJour = date.getDayOfMonth();

             //Le mois en lettre
             String mois = date.monthOfYear().getAsText();

             //L'annee
             int annee = date.getYear();

             //On ajoute le jour, la date du jour, le mois et l'annee dans le dateLabel
             dateLabel.setText(String.format("%d %d %d %d", jour, dateDuJour, mois, annee));

             //On ajoute l'heure, la minute, la seconde dans le composant reserve
             screenLabel.setText(String.format("%d:%s:%s", heure, minute,seconde));
         }
   };
            //On cree l'objet Timer
            Timer timer = new Timer();

            //Et on lui demande d'executer la tache(task) sans delai(immediatement) et à chaque seconde
            timer.schedule(task, 0, 1 * 1000);
 }
         //Creation de l'objet qui servira pour afficher le Timer
         JLabel screenLabel;

        //declaration d'un objet DateTime qui a servir a afficher recuperer la date du jour
         DateTime date;

         //L'objet qui a servi pour l'affichage de la date
         JLabel dateLabel;
}

Ouff!! Tout ce code rien que pour ça ? Les explications aussi y sont pour quelque chose :). Mais au fond il n’ y a rien de compliquer de ce code. Essayer de l’améliorer à votre guise. Ce code n’est pas LA façon de faire mais UNE façon de faire qui privilégie la pédagogie.

Merci..