Mis à jour le 05/10/2017
  • 4 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

TP : Création d'un Mélordi - début

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Nous allons commencer dans ce chapitre une application que nous allons développer tout au long de ce tutoriel. J'ai choisi de vous faire faire un programme qui permettrait de jouer du piano sur son clavier d'ordinateur. On pourrait ainsi jouer des mélodies sur son ordinateur, je l'ai donc baptisée : le Mélordi ;) .

A travers le développement de cette application, nous aborderons les principaux éléments qui composent une interface graphique : les nœuds graphiques, les événements utilisateurs, les animations, etc... Commençons par poser les bases de notre application.

Cahier des charges

Notre application permettrait donc à l'utilisateur de jouer de la musique en appuyant sur les touches de son clavier. Voici toutes les fonctionnalités que je vous propose de développer dans ce programme :

  • 1.Émettre un son à chaque fois que l'utilisateur appuie sur l'une des touches.

  • 2.Pouvoir choisir son instrument entre le piano, la guitare et l'orgue.

  • 3.Régler le volume du son.

  • 4.Créer un petit métronome pour indiquer le tempo.

Voilà ce qui va nous occuper dans les prochains chapitres. Pour commencer, essayons de nous représenter la forme que prendra notre application.

Le clavier

Pour ce qui est du clavier qui permettra à l'utilisateur de jouer des notes de musique, je propose de lui donner la forme suivante :

Image utilisateur

Ainsi, quand l'utilisateur appuierait sur le U l'application jouerait un Do, quand il appuierait sur le I un Ré, sur le O un Mi, sur le P un Fa, sur le J un Sol, sur le K un La, sur le L un Si et sur le M un Do. On pourrait ainsi jouer sur une octave.
De plus, à chaque fois que l'utilisateur appuierait sur une touche de son clavier ou cliquerait sur une touche du Mélordi, celle-ci descendrait de quelques pixels pour donner l'impression de s'enfoncer et changerait de couleur.

Autres fonctionnalités

Il reste trois autres fonctionnalités : changer d'instrument, régler le volume et créer un métronome. Je propose de disposer ces fonctionnalités de la façon suivante :

Image utilisateur

Le slider situé en bas à gauche permettrait à l'utilisateur de régler le son des notes qu'il joue, la liste des trois instruments au-dessus du clavier permettrait de choisir entre le piano, l'orgue et la guitare, et le métronome situé à droite permettrait d'indiquer un tempo.

Voilà le programme ;) . Intéressons nous maintenant à la façon dont nous allons structurer notre code, quels types d'objets, quelles classes allons nous créer et que mettrons nous à l'intérieur...

Structure de notre programme

Je vois en tout sept classes dont nous aurons besoin :

  • 1. La classe principale Melordi qui contiendra la fonction main().

  • 2. La classe Touche qui modélisera une touche du clavier graphique.

  • 3. La classe Clavier qui modélisera l'ensemble du clavier graphique et qui contiendra notamment huit objets de type Touche, un par touche.

  • 4. La classe Volume qui contiendra le slider permettant de régler le volume sonore.

  • 5. La classe Change_instrument qui contiendra la liste des boutons radio des trois instruments et qui permettra de changer de type d'instrument.

  • 6. La classe Metronome qui modélisera notre métronome.

  • 7. Et enfin la classe Instru qui contiendra toutes les fonctions sonores : jouer une note, augmenter ou baisser le volume, changer l'instrument. Cette classe ne correspondra à aucun élément graphique.

Voici le diagramme UML correspondant à notre application.

C'est quoi un diagramme UML ??

UML signifie Unified Modeling Langage, c'est un langage de modélisation graphique qui permet justement de représenter graphiquement la structure d'un programme comme le nôtre. Je ne vais pas vous faire un cours d'UML (si ça vous intéresse, vous pouvez lire le chapitre de cysboy sur le sujet : Apprendre à modéliser), mais la structure de notre programme est tellement simple que vous pourrez sûrement comprendre intuitivement ce que ce diagramme représente :

Image utilisateur

Ce schéma ne respecte pas exactement le langage UML mais il représente les sept classes qui constitueront notre programme.

Maintenant qu'on a représenté la forme qu'aurait notre interface et la structure de notre code, nous allons pouvoir attaquer...

Nouveau projet

Pour commencer, on peut fermer le projet Test avec lequel nous avons travaillé jusqu'ici. Pour ça vous pouvez faire un click droit sur le projet Test dans le panel de gauche puis sélectionner Close.

Création du projet Mélordi

Très bien, créons maintenant notre nouveau projet Melordi : File >> New Project
Dans la cathégorie Java, sélectionnez le type de projet Java FX Application (comme d'habitude), puis cliquez sur Next. Enfin, entrez le nom de projet Melordi et cliquez sur Finish.

Les dossiers de notre nouveau projet devraient apparaître dans le panel de gauche et la feuille de code Melordi.java pré-remplie devrait apparaître dans le panel central. On peut commencer par modifier le contenu de la fonction start() de façon à ce que notre application ne contienne qu'une scène vide de taille 500x500 et de fond blanc. On devrait obtenir le code suivant :

package melordi;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Melordi extends Application {

    public static void main(String[] args) {
        Application.launch(Melordi.class, args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Melordi");
        Group root = new Group();
        Scene scene = new Scene(root, 500, 500, Color.WHITE);
        
        primaryStage.setScene(scene);
        primaryStage.setVisible(true);
    }
}

Compilez pour être sûr que tout va bien et passons à l'étape suivante. Vous devriez voir une belle fenêtre carrée et vide, avec quand même un fond blanc :p .

Je propose maintenant de réaliser dans ce chapitre la seule classe qui ne corresponde pas à un élément graphique : la classe Instru.

Création de la classe Instru

Avant toute chose, précisons que les sons que générera notre application seront des sons MIDI. Je ne préfère pas rentrer dans les détails sur ce qu'est un son MIDI mais ce qui est important de savoir, c'est que pour générer ce type de son, notre application aura besoin d'une banque de sons que vous n'avez peut-être pas...

Pour remédier à ce problème, je vous propose de télécharger la banque de sons suivante : soundbank-deluxe.gm et de la ranger dans le dossier : C:\Program Files\Java\jdk1.6.0_25\jre\lib\audio de votre ordinateur (s'il y a déjà une banque de son ça ne fait rien, ajoutez la quand même) et aussi dans le dossier C:\Program Files\Java\jre6\lib\audio. Vous êtes maintenant équipé pour générer tous les sons d'instruments que vous souhaitez :) .

Nous avions dit que l'objet de type Instru devait gérer toutes les fonctions relatives aux sons. Commençons par faire la liste de ces différentes fonctions :

  • 1. Régler le volume. Nous créerons pour cela une variable volume qui règlera le volume des notes jouées par l'utilisateur.

  • 2. Jouer une note. Nous créerons pour cela deux fonctions : note_on() et note_off().

  • 3. Changer d'instrument. Nous créerons pour cela une fonction set_instrument() qui permettra de modifier l'instrument courant.

Créons maintenant cette classe. Pour cela : faites un click droit sur le package melordi dans le panel de gauche, puis aller dans New et sélectionnez Java Class...
Appelez cette nouvelle classe Instru puis cliquez sur Finish.

Parfait, la feuille Instru.java devrait apparaître. Avant de créer nos variables et fonctions, il nous faut créer et initialiser un synthétiseur de sons MIDI que Java met à notre disposition dans le package javax.sound.midi. C'est grâce à un synthétiseur que nous pourrons jouer des notes MIDI d'une certaine tonalité et d'un certain type d'instrument.

Pour synthétiser des sons MIDI nous devons procéder en deux étapes :

  • 1.Créer un objet de type Synthesizer et l'initialiser.

  • 2.A partir de cet objet de type Synthesizer, récupérer un objet de type MidiChannel. Cet objet est un canal qui nous permettra de jouer des notes MIDI.

Nous pouvons créer le constructeur de notre classe Instru qui nous permettra de créer nos objets de types Synthesizer et MidiChannel :

package melordi;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Synthesizer;

public class Instru {
    
    private Synthesizer synthetiseur;
    private MidiChannel canal;
    
    public Instru(){
        
        try {
            //On récupère le synthétiseur, on l'ouvre et on obtient un canal
            synthetiseur = MidiSystem.getSynthesizer();
            synthetiseur.open();
        } catch (MidiUnavailableException ex) {
            Logger.getLogger(Instru.class.getName()).log(Level.SEVERE, null, ex);
        }
        canal = synthetiseur.getChannels()[0];
        
        //On initialise l'instrument 0 (le piano) pour le canal
	canal.programChange(0);
    }
}

Il y a en tout 16 canaux MIDI qui permettent de jouer des notes, nous n'utiliseront que le canal 0 que nous avons récupéré dans notre variable canal. Nous sommes maintenant parés pour créer les variables et fonctions que nous avons décrites plus haut :

  • 1. La variable de type int qui contiendra la valeur du volume sonore auquel seront jouées les notes :

    public int volume = 100;
    
  • 2. Les fonctions note_on() et note_off() qui permettront de jouer des notes de musique :

    //Joue la note dont le numéro est en paramètre
        public void note_on(int note){
            canal.noteOn(note, volume);
        }
        //Arrête de jouer la note dont le numéro est en paramètre
        public void note_off(int note){
            canal.noteOff(note);
        }
    
  • 3. La fonction set_instrument() qui permet de changer le type d'instrument :

    public void set_instrument(int instru){
            canal.programChange(instru);
        }
    

Et voilà, nous avons là toutes les fonctionnalités dont nous aurons besoin pour notre application Mélordi. Voici ce que devrait maintenant contenir votre feuille Instru.java :

package melordi;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Synthesizer;

public class Instru {
    
    public int volume = 100;
    
    private Synthesizer synthetiseur;
    private MidiChannel canal;
    
    public Instru(){
        
        try {
            //On récupère le synthétiseur, on l'ouvre et on obtient un canal
            synthetiseur = MidiSystem.getSynthesizer();
            synthetiseur.open();
        } catch (MidiUnavailableException ex) {
            Logger.getLogger(Instru.class.getName()).log(Level.SEVERE, null, ex);
        }
        canal = synthetiseur.getChannels()[0];
        
        //On initialise l'instrument 0 (le piano) pour le canal
	canal.programChange(0);
    }
    
    //Joue la note dont le numéro est en paramètre
    public void note_on(int note){
        canal.noteOn(note, volume);
    }
    //Arrête de jouer la note dont le numéro est en paramètre
    public void note_off(int note){
        canal.noteOff(note);
    }
    //Set le type d'instrument dont le numéro MIDI est précisé en paramètre
    public void set_instrument(int instru){
        canal.programChange(instru);
    }
}

Vous pouvez compiler pour vérifier que tout va bien :) .

Nous pouvons terminer par créer un objet de type Instru que nous venons de définir dans la fonction start() de notre feuille de code Melordi.java. Nous appellerons cet objet mon_instru :

@Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Melordi");
        Group root = new Group();
        Scene scene = new Scene(root, 500, 500, Color.WHITE);
        
        Instru mon_instru = new Instru();
        
        primaryStage.setScene(scene);
        primaryStage.setVisible(true);
    }

Pour vérifier que notre objet marche bien, vous pouvez rajouter en dessous de la création de mon_instru la ligne de code suivante :

mon_instru.note_on(65);

Si vous compilez, vous devriez entendre une note de musique...

Très bien, vous pouvez retirer cette ligne de code.

Dans le chapitre suivant, nous allons pouvoir passer à la partie graphique et apprendre à créer nos propres nœuds graphiques.

Exemple de certificat de réussite
Exemple de certificat de réussite