Package memory.chants

Source Code of memory.chants.JLecteurMP3

package memory.chants;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import memory.lecteur.LecteurEvent;
import memory.lecteur.LecteurException;
import memory.lecteur.LecteurListener;
import memory.lecteur.LecteurMP3;

/**
* @author patrice
* Une classe pour représenter graphiquement un lecteur de MP3
* Implémentations :
*      ActionListener   pour réagir aux clics sur des boutons
*      ChangeListener   pour réagir au JSlider (volume)
*      LecteurListener  pour réagir aux modifications du lecteur
*      Observable       pour permettre à la sonothèque de passer automatiquement au chant
*                       suivant (pour les autres modules ce n'est pas nécessaire)
*/
public class JLecteurMP3 extends JPanel implements ActionListener, ChangeListener, LecteurListener, Observable
{
    //un lecteur de MP3
  private LecteurMP3 lecteur;
  //les fichiers son, le nom de l'oiseau, le message "quel est cet oiseau"
  private String mp3, nom, titre, nomLatin;
  //une barre de progression du chant de l'oiseau
  private JProgressBar progression = new JProgressBar(0,100);
  //les boutons play, pause, stop
  private JButton btnPlay,btnPause,btnArret;
  //des booléens qui indiquent si on a appuyé sur pause, sur stop
  //ou si le chant doit boucler (reprise à la fin du morceau)
  //et aussi pour afficher ou non la réponse (jeu ou galerie, sonothèque ...)
  //et enfin pour savoir si on a cliqué sur la barre de progression pour redémarrer le chant
  //à un endroit particulier (en attente de réalisation)
  private boolean paused = false, stopped = true, boucle = true, cache = false;

    //l'état des trois boutons sur 3 bits (001 = btnArret disabled, btnPause disabled, btnPlay enabled)
  private int etatBoutons;
  //un contrôle de volume
  private JSlider volume;
  //le panneau pour contenir les boutons
  private JPanel boutons;
  //un JLabel pour contenir l'image
  private JLabel lblImage;
  //les diverses images pour le jeu et pour les boutons
  private ImageIcon image, //l'image de l'oiseau
//            defaut, //l'image à afficher pendant le jeu (avant de connaître le nom de l'oiseau)
            //l'icone du bouton play
            iconPlay =  new ImageIcon("." + File.separator + "icones" + File.separator + "play.png"),
//            iconPlay = new ImageIcon(JLecteurMP3.class.getResource ("play.png")),           
            //l'icone du bouton pause
            iconPause = new ImageIcon("." + File.separator + "icones" + File.separator + "pause.png"),
            //l'icone du bouton arret
            iconStop =  new ImageIcon("." + File.separator + "icones" + File.separator + "arret.png");
  private static ImageIcon defaut;
  //le JPanel pour contenir le JLabel
  private JPanel panImage;
  //la bordure
  private BordureDouble bordure;
  //la liste des observateurs du lecteur (la sonothèque ... )
  private List<Observateur> observateurs = new ArrayList<Observateur>();
 

    /************** LE CONSTRUCTEUR ***************************************************************/
 
  /**
   * constructeur du lecteur avec un oiseau
   * @param oiseau l'oiseau concerné
   */
  public JLecteurMP3(Oiseau oiseau)
  {
    //le lecteur de base
    this.lecteur = new LecteurMP3();
    //le lecteur est écouté par l'interface
    this.lecteur.addLecteurListener(this);
    //les données : le chant, l'image, le nom
    this.mp3 = oiseau.getChant();
    this.image = oiseau.getImage();
    this.nom = oiseau.getNom();
    this.nomLatin = oiseau.getNomLatin();
//    if (nomLatin.length() == 0) System.out.println(nom);
    //l'image anonyme
    initImageDefaut();

    //le panneau image
    this.panImage = new JPanel();
    this.bordure = new BordureDouble(this.cache ? this.titre : this.nom,
                       this.cache ? this.titre : this.nomLatin);
   
        //on applique la bordure au panneau
        this.panImage.setBorder (bordure);
        //on donne un FlowLayout au panneau
        this.panImage.setLayout(new FlowLayout());
        //l'image, si elle est cachée, est remplacée par une image anonyme
        this.lblImage = new JLabel(this.cache ? defaut : this.image);
        this.panImage.add(this.lblImage);

    //le bouton de volume
    this.volume = new JSlider(JSlider.VERTICAL,0,100,85);
      this.volume.setMajorTickSpacing(20);
      this.volume.setMinorTickSpacing(5);
      this.volume.setPaintTicks(true);
      this.volume.setPaintLabels(true);
      //... que l'on écoute
      this.volume.addChangeListener(this);

      //les boutons d'action
      //démarrer la lecture
      this.btnPlay = new JButton();
      this.btnPlay.setIcon(this.iconPlay);
      this.btnPlay.addActionListener(this);
      this.btnPlay.setEnabled(true);
      //faire une pause dans la lecture
      this.btnPause = new JButton();
      this.btnPause.setIcon(this.iconPause);
      this.btnPause.addActionListener(this);
      this.btnPause.setEnabled(false);
      //arrêter la lecture
      this.btnArret = new JButton();
      this.btnArret.setIcon(this.iconStop);
      this.btnArret.addActionListener(this);
      this.btnArret.setEnabled(false);
      //play = enabled, pause = disabled, stop = disabled ===> etatBoutons = 001
      this.etatBoutons = 1;
     
      //le panneau comportant les boutons d'action
      this.boutons = new JPanel();
      this.boutons.add(this.btnPlay);
      this.boutons.add(this.btnPause);
      this.boutons.add(this.btnArret);
      this.boutons.setBorder (BorderFactory.createLineBorder(Color.black,3));

      //on construit le JLecteurMP3
        //un BorderLayout
        this.setLayout(new BorderLayout());
     
      //la barre de progression
        this.add(this.progression,BorderLayout.NORTH);
        setForeground(Color.CYAN);
      //le voulume
    this.add(this.volume,BorderLayout.EAST);
    this.add(this.boutons,BorderLayout.SOUTH);
    //le panneau image
    this.add(this.panImage,BorderLayout.CENTER);
  }
 

    /************** LES ASSESSEURS ***************************************************************/

  //on construit l'image anonyme
    private static void initImageDefaut()
    {
        if (defaut == null)
        {
            ImageIcon image = new ImageIcon("." + File.separator + "icones" + File.separator + "defaut1.jpg");
            int largeur = image.getIconWidth ();
            int hauteur = image.getIconHeight ();
                       
            int largeurImage = 250;
            if (largeur > hauteur)
            {
                hauteur = (hauteur * largeurImage)/largeur;
                largeur = largeurImage ;
            }
            else
            {
                largeur = (largeur * largeurImage)/hauteur;
                hauteur = largeurImage;
            }
            defaut = new ImageIcon(image.getImage().getScaledInstance(largeur,hauteur,Image.SCALE_DEFAULT));
        }
    }

    /************** LES MODIFICATEURS ************************************************************/

  /**
   * On change la bordure car quand on change de langue, le nom change
   */
  public void changeBordure()
  {
      if (this.cache)
      {
        this.bordure.setTitreHaut(this.titre);
        this.bordure.setTitreBas("");
      }
      else
      {
        this.bordure.setTitreHaut(this.nom);
        this.bordure.setTitreBas(this.nomLatin);
      }
       
      this.panImage.repaint();
  }
 
    /************** LES ACTIONS LIEES AU LECTEUR **************************************************/
 
    /**
   * on lance le chant d'oiseau
   * Pas d'argument donc donc lance le chant au début
   */
  private void joueChant()
  {
//      this.stopped = false;
        try
        {
            this.lecteur.open(new File(this.mp3));
            this.lecteur.play();
        }
        catch (LecteurException e)
        {
            e.printStackTrace();
        }
  }

    /**
     * on lance le chant d'oiseau
     * si x = 0, on lance le chant au début sinon on cemmence à x%
     * @param x pourcentage de chant qu'il faut jouer (en fait on joue (1-x) secondes du morceau)
     */
    private void joueChant (double x)
    {
        try
        {
//          this.lecteur.open(Fichier.chargerChant(mp3));
            this.lecteur.open(new File(this.mp3));
            this.lecteur.skip (x);
            this.lecteur.play ();
        }
        catch (LecteurException e)
        {
            e.printStackTrace();
        }
    }
 
 
  /**
   * on arrête le chant
   */
  public void stopChant()
  {
    this.progression.setValue(0);
    this.lecteur.stop();
  }

 
  /**
   * les actions sur les boutons
   * (non-Javadoc)
   * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
   *
   * Chaque clic sur un des boutons déclenche un évènement du Lecteur qui en retour agit sur
   * le JLecteur. Il faudrait que ces évènements soient filtrés via un booléen pour ne pas
   * mélanger, par exemple,  un arrêt du lecteur du fait de la fin du chant et un arrêt de
   * l'utilisateur
   */
  @Override
  public void actionPerformed(ActionEvent evt)
  {
    if (evt.getSource() == this.btnPlay)
    {
        joue();
      return;
    }
    if (evt.getSource() == this.btnPause)
    {
      this.stopped = false;
      this.paused = ! this.paused;
        if (this.paused)
        {
            this.btnPause.setIcon(this.iconPlay);
            if (this.etatBoutons != 2) gererBoutons(false,true,false);
            pauseChant();
        }
        else
        {
            this.btnPause.setIcon(this.iconPause);
            if (this.etatBoutons != 6) gererBoutons(false,true,true);
            resumeChant();
        }
      return;
    }
    if (evt.getSource() == this.btnArret)
    {
        stop();
      return;
    }
  }

  //on joue le chant depuis le début
  public void joue()
  {
        this.stopped = false;
        this.paused = false;
        this.btnPause.setIcon(this.iconPause);
        if (this.etatBoutons != 6) gererBoutons(false,true,true);
        joueChant();
  }

  //on joue le chant à partir de x (un nombre entre 0 et 1)
    public void joue (double x)
    {
        this.stopped = false;
        this.paused = false;
        this.btnPause.setIcon(this.iconPause);
        if (this.etatBoutons != 6) gererBoutons(false,true,true);
        joueChant(x);
    }
 
 

    public void stop()
  {
            this.stopped = true;
            this.paused = false;
            this.btnPause.setIcon(this.iconPause);
            if (this.etatBoutons != 1) gererBoutons(true, false, false);
            stopChant();
  }
 
    /**
     * reprise après pause
     */
    public void resumeChant()
  {
    this.lecteur.resume();
  }

    /**
     * pause dans la lecture
     */
    public void pauseChant()
    {
      this.lecteur.pause();
    }

    /**
     * on modifie le volume
     * (non-Javadoc)
     * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
     */
    @Override
    public void stateChanged(ChangeEvent evt)
    {
      if (evt.getSource() == this.volume)
      {
        double valeur = (double) this.volume.getValue() / 100 ;
        try
        {
          this.lecteur.setGain(valeur);
        }
        catch (LecteurException e)
        {
          e.printStackTrace();
        }
      }
    }


    /**
     * un test
     * @param args
     */
    public static void main(String[] args)
    {
      GestionDonnees gd = new GestionDonnees();
      Oiseau oiseau = new Oiseau(gd.getNom(0), gd.getNomLatin(0), gd.getFichierSon(0), gd.getFichierImage(0), 300);
      final JLecteurMP3 lecteurMP3 = new JLecteurMP3(oiseau);
      lecteurMP3.setCache(true);
     
      javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
        public void run()
            {
              JFrame fenetre = new JFrame();
              fenetre.add(lecteurMP3);
              fenetre.pack();
              fenetre.setVisible(true);
                fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });

      lecteurMP3.setBoucle (true);
        lecteurMP3.joue(0.90);
    }

    /**
     * ici les échanges LecteurMP3 vers JlecteurMP3
     * En fait seuls les codes EOM et STOPPED sont à traiter car tous les autres codes soit n'ont
     * pas d'influence sur le composant (OPENED, PLAYING) soit sont commandés par lui (OPENED,
     * PAUSED, RESUMED, GAIN)
     * Seul STOPPED est soit commandé par le composant (ne rien faire) soit est lié à la
     * fin du morceau. Dans ce cas soit on rejoue le morceau, soit on passe à un autre.
     */
    @Override
    public void stateUpdated(LecteurEvent event)
    {
        if ((event.getCode () == LecteurEvent.STOPPED) && (! this.stopped))
        {
            if (boucle)
            {
                try
                {
                    this.lecteur.play();
                }
                catch (LecteurException e)
                {
                    e.printStackTrace();
                }
            }
            else updateObservateurs();
        }
       
    }

    private void gererBoutons(final boolean etatRun, final boolean etatPause, final boolean etatStop)
    {
      this.etatBoutons = (etatStop ? 4 : 0) + (etatPause ? 2 : 0) + (etatRun ? 1 : 0);
      SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
              JLecteurMP3.this.btnPlay.setEnabled(etatRun) ;
              JLecteurMP3.this.btnPause.setEnabled(etatPause);
              JLecteurMP3.this.btnArret.setEnabled(etatStop);
              revalidate();
            }
        });
    }

    /**
     * on modifie le statut de l'image : cachée elle est remplacée par une image anonyme et le nom
     * par "quel est le nom de cet oiseau ?" (dans la langue choisie)
     * il faut penser à changer l'affichage
     * @param b
     */
    public void setCache(boolean b)
    {
      //on change la valeur de cache et l'affichage 
      this.cache = b;
      //si l'image est cachée
      if (b)
      {
        this.lblImage.setIcon(defaut);
        this.bordure.setTitreHaut(titre);
        this.bordure.setTitreBas("");
      }
      else
      {
        this.lblImage.setIcon(this.image);
        this.bordure.setTitreHaut(this.nom);
        this.bordure.setTitreBas(this.nomLatin);
      }
    }

    /**
     * on change d'oiseau
     * @param oiseau l'oiseau
     */
    public void change(Oiseau oiseau)
    {
      this.image = oiseau.getImage();
      this.mp3 = oiseau.getChant();
      this.nom = oiseau.getNom();
      this.nomLatin = oiseau.getNomLatin();
    }

    /**
     * On change le nom (changement de langue)
     * @param nom2 le nom de l'oiseau
     */
    public void setNom(String nom2)
    {
      this.nom = nom2;
    }
   
    /**
     * On change le titre si l'image est cachée (changement de langue)
     * @param titre la question "quel est cet oiseau ?" dans diverses langues
     */
    public void setTitre(String titre)
    {
        this.titre = titre;
    }
   
    /**
     * On ajoute un observateur
     * (non-Javadoc)
     * @see memory.chants.Observable#addObservateur(memory.chants.Observateur)
     */
    @Override
    public void addObservateur (Observateur obs)
    {
        this.observateurs.add (obs);
    }

   
    /**
     * On prévient les observateurs de l'arrêt du chant
     *  (non-Javadoc)
     * @see memory.chants.Observable#updateObservateurs()
     */
    @Override
    public void updateObservateurs ()
    {
       
        for (Observateur obs : this.observateurs)
        {
            obs.update ();
        }
    }

    /**
     * On retire tous les observateurs
     *  (non-Javadoc)
     * @see memory.chants.Observable#delObservateurs()
     */
    @Override
    public void delObservateurs ()
    {
        this.observateurs = new ArrayList<Observateur>();
    }


    /**
     * @param boucle on boucle ou non sur le chant d'oiseau
     */
    public void setBoucle (boolean boucle)
    {
        this.boucle = boucle ;
    }

    /**
     * progression dans la lecture
     * @see memory.lecteur.LecteurListener#progress(java.lang.Long)
     */
    @Override
    public void progress (Long microseconds)
    {
        final int progres = (int)(microseconds/1000000);
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                JLecteurMP3.this.progression.setValue(progres) ;
            }
        });
    }

    /* (non-Javadoc)
     * @see memory.lecteur.LecteurListener#opened(java.lang.Long)
     */
    @Override
    public void opened (Long microsecondes)
    {
        final int duree = (int)(microsecondes/1000000);
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                JLecteurMP3.this.progression.setMaximum(duree);
            }
        });
    }
}
TOP

Related Classes of memory.chants.JLecteurMP3

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.