Coloration Syntaxique

Télécharger le script ! - mod phpBB

// Figure 22.10 : DemoMidi.java
// Simuler un clavier de piano permettant de jouer plusieurs instruments
// ainsi que des caractéristiques d'enregistrement, de lecture de séquences
// et de simulation de l'action d'un piano mécanique lors de la lecture MIDI.

// Packages de noyau Java.
import java.awt.*;
import java.awt.event.*;
import java.io.*;

// Packages d'extension Java.
import javax.swing.*;
import javax.swing.event.*;
import javax.sound.midi.*;

public class DemoMidi extends JFrame {

   // Enregistrement de données MIDI.
   private EnregistreurMidi enregistreurMidi;

   // Accès aux fonctions MIDI de synthétiseur.
   private SynthetiseurMidi synthetiseurMidi;

   // Données des fichiers MIDI.
   private DonneesMidi donneesMidi;

   // Minuterie pour la simulation des données MIDI au piano.
   private Timer minuteriePiano;

   // Touches du clavier de piano.
   private JButton boutonNote[];

   // Glissières pour le volume sonore et le tempo.
   private JSlider boutonVolume, boutonTempo;

   // Conteneurs et panneaux pour mettre la GUI en place.
   private Container conteneur;
   private JPanel panneauControle, panneauBoutons;

   // GUI incluant le sélecteur d'instrument et les boutons.
   private JComboBox selecteurInstrument;
   private JButton boutonReecouter, boutonEnregistrer,
      boutonSauvegarder, boutonPiano, boutonOuvrirMidi;

   // Tempo, dernière note de piano invoquée et volume MIDI.
   private int tempo, derniereNoteOn = -1, volumeMidi = 40;

   // Valeur boolean indiquant si le programme est en mode d'enregistrement.
   private boolean modeEnregistrement = false;

   // 1er numéro de note MIDI de la 1ere touche, quantité maximale de touches.
   private static int PREMIERE_NOTE = 32, QTE_MAX_TOUCHES = 64;

   // Constructeur de DemoMidi.
   public DemoMidi()
   {
      super( "Programme de démonstration MIDI" );

      conteneur = getContentPane();
      conteneur.setLayout( new BorderLayout() );

      // Le synthétiseur doit être instancié pour permettre la synthèse.
      synthetiseurMidi = new SynthetiseurMidi();

      // Créer les touches de piano.
      creerTouches();

      // Ajouter le panneau de contenu dans le cadre.
      panneauControle = new JPanel( new BorderLayout() );
      conteneur.add( panneauControle, BorderLayout.NORTH );

      creerCommandesConfig();

      // Ajouter le panneau de boutons dans le cadre.
      panneauBoutons = new JPanel( new GridLayout( 5, 1 ) );
      panneauControle.add( panneauBoutons, BorderLayout.EAST );

      // Créer la GUI.
      creerBoutonsReecouterSauvegarder();
      creerBoutonEnregistrer();
      creerBoutonPianoMecanique();

   }  // fin du constructeur

   // Méthode utilitaire pour créer les touches de piano.
   private void creerTouches()
   {
      // Panneau contenant les touches.
      JPanel panneauTouches = new JPanel( null );
      conteneur.add( panneauTouches, BorderLayout.CENTER );

      // Touches du clavier de piano.
      boutonNote = new JButton[ QTE_MAX_TOUCHES ];

      // Définir les boutons des notes selon la QTE_MAX_TOUCHES et leur hauteur.
      for ( int i = 0; i < QTE_MAX_TOUCHES; i++ ) {

         final int note = i;

         boutonNote[ i ] = new JButton();

         // Définir des touches blanches.
         boutonNote[ i ].setBackground( Color.white );

         // Définir un espacement adéquat pour les boutons.
         boutonNote[ i ].setBounds( ( i * 11 ), 1, 11, 40 );
         panneauTouches.add( boutonNote[ i ] );

         // Inscrire un écouteur de souris pour les événements de souris.
         boutonNote[ i ].addMouseListener(

            // Classe interne anonyme de gestion des événements de souris.
            new MouseAdapter() {

               // Invoquer la note de la touche quand la souris survole la touche.
               public void mouseEntered( MouseEvent mouseEvent )
               {
                  // Si en mode d'enregistrement, envoie un message au récepteur.
                  if ( modeEnregistrement )
                     synthetiseurMidi.sendMessage(
                        ShortMessage.NOTE_ON,
                        note + PREMIERE_NOTE, volumeMidi );

                  // Sinon, ne jouer que la note.
                  else
                     synthetiseurMidi.midiNoteOn(
                        note + PREMIERE_NOTE, volumeMidi );

                  // Changer la touche blanche en touche bleue.
                  boutonNote[ note ].setBackground(
                     Color.blue );
               }

               // Message qui désactive la note quand la souris quitte la touche.
               public void mouseExited( MouseEvent mouseEvent )
               {
                  if ( modeEnregistrement )
                     synthetiseurMidi.sendMessage(
                        ShortMessage.NOTE_OFF,
                        note + PREMIERE_NOTE, volumeMidi );
                  else
                     synthetiseurMidi.midiNoteOff(
                        note + PREMIERE_NOTE );

                  boutonNote[ note ].setBackground(
                     Color.white );
               }

            }  // fin du MouseAdapter

         ); // fin de l'appel à addMouseListener

      }  // fin de la boucle for

   }  // fin de la méthode creerTouches

   // Définir les commandes de configuration.
   private void creerCommandesConfig()
   {
      JPanel panneauConfig =
         new JPanel( new GridLayout( 5, 1 ) );

      panneauControle.add( panneauConfig, BorderLayout.WEST );

      selecteurInstrument = new JComboBox(
         synthetiseurMidi.getInstruments() );

      panneauConfig.add( selecteurInstrument );

      // Inscrire un ActionListener pour les événements selecteurInstrument.
      selecteurInstrument.addActionListener(

         // Classe interne anonyme de gestion des événements selecteurInstrument.
         new ActionListener() {

            // Changer l'instrument courant.
            public void actionPerformed( ActionEvent e )
            {
               // Changer l'instrument du synthétiseur.
               synthetiseurMidi.changeInstrument(
                  selecteurInstrument.getSelectedIndex() );
            }

         }  // fin d'ActionListener

      ); // fin de l'appel à la méthode addActionListener

      JLabel etiquetteVolume = new JLabel( "Volume" );
      panneauConfig.add( etiquetteVolume );

      boutonVolume = new JSlider(
         SwingConstants.HORIZONTAL, 5, 80, 30 );

      // Inscrire un ChangeListener pour les variations du curseur de volume.
      boutonVolume.addChangeListener(

         // Classe interne anonyme de gestion des événements du curseur de volume.
         new ChangeListener() {

            // Changer le volume MIDI.
            public void stateChanged( ChangeEvent changeEvent )
            {
               volumeMidi = boutonVolume.getValue();
            }

         }  // fin de la classe ChangeListener

      ); // fin de l'appel à la méthode addChangeListener

      panneauConfig.add( boutonVolume );

      JLabel etiquetteTempo = new JLabel( "Tempo" );
      panneauConfig.add( etiquetteTempo );

      boutonTempo = new JSlider(
         SwingConstants.HORIZONTAL, 1, 10, 1 );

      // Inscrire un ChangeListener pour les variations du curseur de tempo.
      boutonTempo.addChangeListener(

         // Classe interne anonyme de gestion des événements du curseur de tempo.
         new ChangeListener() {

            // Changer le tempo MIDI si la valeur est changée.
            public void stateChanged( ChangeEvent changeEvent )
            {
               tempo = boutonTempo.getValue();
            }

         }  // fin du ChangeListener

      ); // fin de l'appel à la méthode addChangeListener

      boutonTempo.setEnabled( false );
      panneauConfig.add( boutonTempo );

   }  // fin de la méthode creerCommandesConfig

   // Définir les boutons de réécoute et de sauvegarde.
   private void creerBoutonsReecouterSauvegarder()
   {
      boutonReecouter = new JButton( "Réécouter" );

      // Inscrire un ActionListener pour les événements boutonReecouter.
      boutonReecouter.addActionListener(

         // Classe interne anonyme de gestion des événements boutonReecouter.
         new ActionListener() {

            // Jouer la dernière séquence MIDI enregistrée.
            public void actionPerformed( ActionEvent e )
            {
               if ( enregistreurMidi != null )
                  enregistreurMidi.lecture();
            }

         }  // fin de l'ActionListener

      ); // fin de l'appel à la méthode addActionListener

      panneauBoutons.add( boutonReecouter );
      boutonReecouter.setEnabled( false );

      boutonOuvrirMidi = new JButton( "Ouvrir fichier MIDI" );

      // Inscrire un ActionListener pour les événements boutonOuvrirMidi.
      boutonOuvrirMidi.addActionListener(

         // Classe interne anonyme de gestion des événements boutonOuvrirMidi.
         new ActionListener() {

            // Lire le fichier MIDI.
            public void actionPerformed( ActionEvent e )
            {
               File fichierMidi = getFichier();

               if ( fichierMidi == null )
                  return;

               donneesMidi = new DonneesMidi();

               // Préparer la piste MIDI.
               if ( donneesMidi.initialiser( fichierMidi ) == false )
                  return;

               // Jouer les données MIDI.
               donneesMidi.lecture();
            }

         }  // fin de l'ActionListener

      ); // fin de l'appel à la méthode addActionListener

      panneauBoutons.add( boutonOuvrirMidi );

      boutonSauvegarder = new JButton( "Sauvegarder MIDI" );

      // Inscrire un ActionListener pour les événements boutonSauvegarder.
      boutonSauvegarder.addActionListener(

         // Classe interne anonyme de gestion des événements boutonSauvegarder.
         new ActionListener() {

            // Obtenir le fichier requis et sauvegarder les données MIDI.
            public void actionPerformed( ActionEvent e )
            {
                File fichierSauvegarde = getFichierSauvegarde();

                if ( fichierSauvegarde != null )
                   enregistreurMidi.sauvegarderSequence( fichierSauvegarde );
            }

         }  // fin de l'ActionListener

      ); // fin de l'appel à la méthode addActionListener

      panneauBoutons.add( boutonSauvegarder );
      boutonSauvegarder.setEnabled( false );

   }  // fin de la méthode creerBoutonsReecouterSauvegarder

   // Créer le bouton d'enregistrement.
   private void creerBoutonEnregistrer()
   {
      boutonEnregistrer = new JButton( "Enregistrer" );

      // Inscrire un ActionListener pour les événements boutonEnregistrer.
      boutonEnregistrer.addActionListener(

         // Classe interne anonyme de gestion des événements boutonEnregistrer.
         new ActionListener() {

            // Démarrer ou arrêter l'enregistrement.
            public void actionPerformed( ActionEvent e )
            {
               // Enregistrer les données MIDI si le bouton est "Enregistrer".
               if ( boutonEnregistrer.getText().equals("Enregistrer") ) {

                  if ( enregistreurMidi == null ) {

                     // Créer une nouvelle instance d'enregistreur en
                     // passant via le transmetteur du synthétiseur.
                     enregistreurMidi = new EnregistreurMidi(
                        synthetiseurMidi.getTransmitter() );

                     if ( enregistreurMidi.initialiser() == false )
                        return;
                  }

                  else
                     enregistreurMidi.makeTrack();

                  enregistreurMidi.startRecord();

                  // Désactiver la réécoute durant l'enregistrement.
                  boutonReecouter.setEnabled( false );

                  // Changer le bouton Enregistrer en bouton Arrêter.
                  boutonEnregistrer.setText( "Arrêter" );
                  modeEnregistrement = true;

               }  // fin du if

               // Arrêter l'enregistrement si le bouton est "Arrêter".
               else {
                  enregistreurMidi.stopRecord();

                  boutonEnregistrer.setText( "Enregistrer" );
                  modeEnregistrement = false;

                  boutonReecouter.setEnabled( true );
                  boutonSauvegarder.setEnabled( true );
               }

            }  // fin de la méthode actionPerformed

         }  // fin de l'ActionListener

      ); // fin de l'appel à la méthode addActionListener

      panneauBoutons.add( boutonEnregistrer );

   } // fin de la méthode creerBoutonEnregistrer

   // Créer le bouton et les fonctionnalités du piano mécanique.
   private void creerBoutonPianoMecanique()
   {
      boutonPiano = new JButton( "Piano mécanique" );

      // Inscrire un ActionListener pour les événements de boutonPiano.
      boutonPiano.addActionListener(

         // Classe interne anonyme de gestion des événements boutonPiano.
         new ActionListener() {

            // Initialiser les données MIDI et la minuterie pour le piano.
            public void actionPerformed( ActionEvent e )
            {
               File fichierMidi = getFichier();

               if ( fichierMidi == null )
                  return;

               donneesMidi = new DonneesMidi();

               // Préparer la piste MIDI.
               if ( donneesMidi.initialiser( fichierMidi ) == false )
                  return;

               if ( donneesMidi.initialiserPiste() == false )
                  return;

               // Définir le tempo initial de la séquence MIDI.
               tempo = donneesMidi.getResolution();

               // Nouvelle instance de la minuterie pour la gestion des notes
               // du piano et le déclenchement des touches suivant le tempo.
               minuteriePiano = new Timer(
                  donneesMidi.getDelai() * tempo,
                  new GestionnaireMinuterie() );

               boutonOuvrirMidi.setEnabled( false );
               boutonPiano.setEnabled( false );
               boutonTempo.setEnabled( true );

               minuteriePiano.start();

            }  // fin de la méthode actionPerformed

         }  // fin de l'ActionListener

      ); // fin de l'appel à la méthode addActionListener

      panneauBoutons.add( boutonPiano );

   }  // fin de la méthode creerBoutonPianoMecanique

   // Classe interne de gestion des événements MIDI chronométrés.
   private class GestionnaireMinuterie implements ActionListener {

      // Simuler action de touche pour la note s'il existe un événement, passer
      // à l'événement suivant de la piste et définir le prochain intervalle
      // de la méthode de minuterie invoquée à l'atteinte du nouvel événement.
      public void actionPerformed( ActionEvent actionEvent )
      {
         // Si la dernière touche valide est à "ON", la recolorer en blanc.
         if ( derniereNoteOn != -1 )
            boutonNote[ derniereNoteOn ].setBackground(
               Color.white );

         noteAction();
         donneesMidi.allerEvenementSuivant();

         // Stopper le piano mécanique à la fin de la piste MIDI.
         if ( donneesMidi.isFinDePiste() == true ) {

            if ( derniereNoteOn != -1 )
               boutonNote[ derniereNoteOn ].setBackground(
                  Color.white );

            minuteriePiano.stop();

            boutonOuvrirMidi.setEnabled( true );
            boutonPiano.setEnabled( true );
            boutonTempo.setEnabled( false );

            return;

         }  // fin du if de isFinDePiste

         // Définir l'intervalle avant le prochain événement musical.
         minuteriePiano.setDelay(
            donneesMidi.getDelai() * tempo );

      }  // fin de la méthode actionPerformed

   }  // fin de la classe interne GestionnaireMinuterie

   // Déterminer quelle note est jouée
   // conformément au message MIDI reçu.
   private void noteAction()
   {
      // Pour un message NOTE_ON, jouer la note et enfoncer la touche du piano.
      if ( donneesMidi.getCommandeEvenement() ==
         ShortMessage.NOTE_ON ) {

         // S'assurer que la note valide est comprise dans le clavier du piano.
         if ( ( donneesMidi.getNote() >= PREMIERE_NOTE ) &&
            ( donneesMidi.getNote() < PREMIERE_NOTE + QTE_MAX_TOUCHES ) ) {

            derniereNoteOn = donneesMidi.getNote() - PREMIERE_NOTE;

            // Colorer la touche en rouge.
            boutonNote[ derniereNoteOn ].setBackground( Color.red );

            // Transmettre et joue la note via le synthétiseur.
            synthetiseurMidi.sendMessage( 144,
               donneesMidi.getNote(), donneesMidi.getVolume() );

         }  // fin du if

         // Sinon, aucune dernière touche actionnée.
         else
            derniereNoteOn = -1;

      }  // fin du if

      // Pour un message NOTE_OFF, termine la note MIDI
      // et recolore la touche correspondante en blanc.
      else

         // Si la commande du message est NOTE_OFF.
         if ( donneesMidi.getCommandeEvenement() ==
            ShortMessage.NOTE_OFF ) {

            if ( ( donneesMidi.getNote() >= PREMIERE_NOTE ) &&
               ( donneesMidi.getNote() < PREMIERE_NOTE + QTE_MAX_TOUCHES ) ) {

               // Recolorer la touche correspondante en blanc.
               boutonNote[ donneesMidi.getNote() -
                  PREMIERE_NOTE ].setBackground( Color.white );

               // Envoyer un message NOTE_OFF au récepteur.
               synthetiseurMidi.sendMessage( 128,
                  donneesMidi.getNote(), donneesMidi.getVolume() );
            }  

         }  // fin du if

   }     // fin de la méthode noteAction

   // Obtenir le fichier de sauvegarde de l'ordinateur.
   public File getFichierSauvegarde()
   {
      JFileChooser choixFichier = new JFileChooser();

      choixFichier.setFileSelectionMode(
         JFileChooser.FILES_ONLY );
      int resultat = choixFichier.showSaveDialog( this );

      if ( resultat == JFileChooser.CANCEL_OPTION )
         return null;

      else
         return choixFichier.getSelectedFile();
   }

   // Obtenir le fichier de l'ordinateur.
   public File getFichier()
   {
      JFileChooser choixFichier = new JFileChooser();

      choixFichier.setFileSelectionMode(
         JFileChooser.FILES_ONLY );
      int resultat = choixFichier.showOpenDialog( this );

      if ( resultat == JFileChooser.CANCEL_OPTION )
         return null;

      else
         return choixFichier.getSelectedFile();
   }

   // Exécuter l'application.
   public static void main( String args[] )
   {
      DemoMidi midiTest = new DemoMidi();

      midiTest.setSize( 711, 225 );
      midiTest.setDefaultCloseOperation ( EXIT_ON_CLOSE );
      midiTest.setVisible( true );
   }

}  // fin de la classe DemoMidi


/******************************************************************************
 * (C) Copyright 2002 par Deitel & Associates, Inc. et Prentice Hall          *
 * Tous droits réservés.                                                      *
 *                                                                            *
 * RENONCIATION: Les auteurs et l'éditeur de cet ouvrage ont fait tous        *
 * les efforts pour préparer ce livre et les programmes qu'il contient,       *
 * y compris dans l'élaboration, la recherche et les contrôles sur l'effica-  *
 * cité des théories et programmes. Les auteurs et l'éditeur n'offrent        *
 * aucune garantie de quelque ordre que ce soit, expresse ou implicite,       *
 * pour ce qui concerne ces programmes ni la documentation présentés          *
 * dans ce livre. L'auteur et l'éditeur ne pourront être tenus pour           *
 * responsables de tout dommage accessoire ou indirect, lié à ou causé        *
 * par la fourniture, la performance ou l'utilisation de ces programmes.      *
 *****************************************************************************/
106617 octets
590 lignes générées en 0.06054 secondes,
soit une vitesse de 9729 lignes par seconde

Apache/2.4.38 (Debian)

Texte à analyser:

Langage :