IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Interfaces Graphiques en Java Discussion :

2 JPanel et des boutons


Sujet :

Interfaces Graphiques en Java

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Points : 1
    Points
    1
    Par défaut 2 JPanel et des boutons
    Bonjour, bonsoir,

    Je fais appel à vous car je me retrouve dans une impasse et j'avoue ne plus savoir où donner de la tête pour arriver à mes fins.
    Je travaille sur NetBeans IDE version 8.0.2.

    Je vous explique: j'ai le projet de créer une portée de musique pour permettre à l'utilisateur de composer. J'aimerais que, lorsque ce dernier clique sur la portée, le programme affiche des ronds noirs qui correspondent aux notes souhaitées.

    J'ai donc créé des boutons qui représentent les lignes de la portée qui sont positionnés sur un premier JPanel. Je voudrais que, lorsque je clique sur un bouton (soit une ligne), cela affiche un rond noir sur le bouton cliqué. Du coup j'ai créé un deuxième JPanel qui va afficher ces ronds. Seulement lorsque je veux afficher mon JPanel, celui se place derrière mes boutons de telle sorte que mon rond noir n'apparaît pas sur les boutons.

    Je pensais au départ crée un JPanel transparent qui se positionne sur mon premier JPanel avec les boutons et affiche des ronds noirs, mais je n'ai trouvé que l'opération "setOpaque(false)" qui met ce JPanel derrière le premier JPanel. Ainsi, les ronds noirs s'affiche bien sur le JPanel 2 mais ils sont cachés par les boutons du JPanel 1.

    Je vous joins mon code en vous remerciant par avance de m'avoir lue et de vous être penché (de près ou de loin) sur mon problème.

    PS: Pour l'instant je souhaite juste afficher un rond noir sur un bouton quelconque. Je n'ai pas encore essayé d'afficher un rond noir que si je clique sur un bouton.

    Code:
    Projet.java
    ou en image pdf page1.pdf page2.pdf page3.pdf (désolé d'insérer le code de cette manière, je ne sais pas comment faire sinon.. je suis une vraie débutante)

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    setOpaque rend bien transparent. Par contre l'ordre de dessin des composant quand tu ne définis pas de layout, c'est l'ordre inverse de l'ordre d'ajout. Tu rajoute ton panneau noir en dernier, il est dessiné en premier, puis les bouton sont dessinés au dessus.
    Vu ce que tu cherche à faire, tu va galérer avec les bouton et autres. Personellement j'opterais pour un simple JPanel, que tu met aux dimension qui t'intéressent (set prefered/minimum/maximun Size()) et ensuit tu fais tout ton dessin (ligne, notes) toi même dedans. Ce n'est pas bien compliqué et je suis sur que tu le fais déjà dans tes bouton / panneau pour dessiner les éléments individuels.

    Bref pas besoin de créer un composant graphique pour chaque note/ligne. Un composant unique "Partition" peut se charger de dessiner toute une partition et de réagir aux clics.

  3. #3
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Points : 1
    Points
    1
    Par défaut
    "Personellement j'opterais pour un simple JPanel, que tu met aux dimension qui t'intéressent (set prefered/minimum/maximun Size()) et ensuit tu fais tout ton dessin (ligne, notes) toi même dedans. Ce n'est pas bien compliqué et je suis sur que tu le fais déjà dans tes bouton / panneau pour dessiner les éléments individuels.
    Bref pas besoin de créer un composant graphique pour chaque note/ligne. Un composant unique "Partition" peut se charger de dessiner toute une partition et de réagir aux clics. "

    Tu veux dire que je crée un seul JPanel aux dimensions de ma portée (puis dedans je dessine les lignes de cette même portée) et qu'ensuite je crée un unique bouton qui va dessiner des points noirs en fonction de la position de mon clic ?
    Le problème c'est que je voudrais aussi qu'en fonction du clic, et donc en fonction du bouton cliqué, il joue la note correspondante. Par exemple je clique sur la ligne de la note fa, ça m'affiche une noire et en plus ça me joue le son fa (j'ai déjà créé ma fonction qui joue le son).

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Citation Envoyé par MC.LAPE Voir le message
    et qu'ensuite je crée un unique bouton qui va dessiner des points noirs en fonction de la position de mon clic ?
    Non, tu gère le clic directement sur ton JPanel, pas de bouton. en fonction des coordonnées X/Y de ton click dans le panel, tu dois sans aucun soucis être capable de savoir quelle note de la portée a été cliquée. La position en Y te donnera la ligne, la position en X si c'est la première, deuxième, troisième etc note.

  5. #5
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    en fonction des coordonnées X/Y de ton click dans le panel, tu dois sans aucun soucis être capable de savoir quelle note de la portée a été cliquée.
    Mais comment je récupère la position de mon clic ? Parce qu'avec les boutons, je pouvais les mettre sur écoute et ensuite je savais quel était le bouton cliqué..Est-ce que je peux mettre un JPanel sur écoute ?

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    de la même manière que tu faisait bouton.addActionListener, tu peux faire panel.addMouseListener()

    http://docs.oracle.com/javase/7/docs...eListener.html

    dans le listener, sur la méthode mouseClicked, l'évènement que tu reçois contient getX() et getY()

  7. #7
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Points : 1
    Points
    1
    Par défaut
    D'accord je vais essayer de faire ça. Merci encore pour votre aide qui m'est très précieuse!

  8. #8
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Points : 1
    Points
    1
    Par défaut
    En fait j'ai essayé de faire ce que vous m'avez conseillé mais je n'arrive pas à faire réagir mon panneau ne serait-ce que pour afficher un autre panneau de couleur.

  9. #9
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    montre ton code?

  10. #10
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Points : 1
    Points
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    public class Partition9 {
     
     
        static JFrame f;
    static JPanel panneau, panneau2;
    static ecouteurbouton eb;
     
    static public class ecouteurbouton implements MouseListener {
     
            @Override
            public void mouseClicked(MouseEvent e) {
               e.getPoint();
    panneau2.setSize(200, 300);
    panneau2.setLocation(e.getX(),e.getY());
    panneau2.setBackground(Color.GREEN);
        f.add(panneau2);
    }
     
     
     
            @Override
            public void mousePressed(MouseEvent e) {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }
     
            @Override
            public void mouseReleased(MouseEvent e) {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }
     
            @Override
            public void mouseEntered(MouseEvent e) {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }
     
            @Override
            public void mouseExited(MouseEvent e) {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }}
     
    //fonction dessin du panneau avec un simple rond noir dessus
    //static class Dessin extends JPanel {
    //    @Override
    //        
    //public void paintComponent(Graphics g){
    //    super.paintComponent(g);
    //    
    //    //dessiner un rond noir sur la portée
    //    g.setColor(Color.BLACK);
    //    g.fillOval(10,10,10,10);
    //    
    //    panneau2.repaint();
    //    
    //}
    //}
     
        public static void main(String[] args) {
             f = new JFrame("portée");
            panneau = new JPanel ();
            panneau2 = new JPanel();
            eb = new ecouteurbouton();
     
        //panneau
    panneau.setBounds(50,50,500,300);
    panneau.setBackground(Color.CYAN);
    panneau.addMouseListener(eb);
     
     
            //caractéristiques fenêtre + affichage
        f.setLayout(null);
        f.setSize(1000, 350);
        f.add(panneau);
        f.setVisible(true);
        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
     
        }}

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Heuuu, pourquoi tu balance plein d'exceptions délibérément dans ton listener. Vu que t'interrompt tout le process avec tes exceptions, le clic n'est jamais enregistré. Un fois les exceptions retirées, ton code marche correctement. Bon il dessine le rectangle vert derrière le cyan, mais en cliquant sur le bord on vois que ça marche.

  12. #12
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Points : 1
    Points
    1
    Par défaut
    Ah ben oui, maintenant ça marche. Comme quoi parfois il en faut peu..

    Citation Envoyé par tchize_ Voir le message
    il dessine le rectangle vert derrière le cyan, mais en cliquant sur le bord on vois que ça marche.
    Mais alors comment faire pour que ce panneau se superpose au premier? Parce que j'aimerais que les ronds affichés sur le panneau2 soient sur le panneau 1 (avec les lignes).

  13. #13
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Comme je t'ai dit, tu ne met pas de panneau2, tu dessine ta partition dans panneau1 via sa méthode paintComponent.

  14. #14
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Comme je t'ai dit, tu ne met pas de panneau2, tu dessine ta partition dans panneau1 via sa méthode paintComponent.
    Ah oui d'accord je comprends. Seulement je ne vois pas trop quand appeler ma fonction dessin. Quelque chose s'affiche mais sans avoir cliqué sur le panneau au préalable.

    Mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    package partition9;
     
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
     
     
    public class Partition9 {
     
     
        static JFrame f;
    static JPanel panneau;
    static ecouteurpanneau ep;
    static int X,Y;
    static Dessin des;
     
    static public class ecouteurpanneau implements MouseListener {
     
            @Override
            public void mouseClicked(MouseEvent e) {
               e.getPoint();
    X = e.getX();
    Y = e.getY();
    }
     
            @Override
            public void mousePressed(MouseEvent e) {
     
            }
     
            @Override
            public void mouseReleased(MouseEvent e) {
     
            }
     
            @Override
            public void mouseEntered(MouseEvent e) {
     
            }
     
            @Override
            public void mouseExited(MouseEvent e) {
     
            }
     
            }
     
    static class Dessin extends JPanel {
        @Override
     
    public void paintComponent(Graphics g){
        super.paintComponent(g);
     
        //dessiner un rond noir sur la portée
        g.setColor(Color.BLACK);
        g.drawOval(X,Y,10,10);
     
        panneau.repaint();
     
    }
    }
     
        public static void main(String[] args) {
             f = new JFrame("portée");
            panneau = new JPanel ();
            ep = new ecouteurpanneau();
            des = new Dessin();
        X = 0;
        Y = 0;
        //panneau
     
    panneau.setBounds(50,50,500,300);
    panneau.setBackground(Color.CYAN);
    f.add(panneau);
    panneau.addMouseListener(ep);
    panneau.add(des);
     
            //caractéristiques fenêtre + affichage
        f.setLayout(null);
        f.setSize(1000, 350);
        f.setVisible(true);
        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
     
        }}

  15. #15
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Il faut que tu prévoies une liste pour stocker toutes les notes (par exemple, une liste de Point : List<Point> notes=new ArrayList<>()). A chaque clic souris (mouseClicked()), tu ajoutes le mouseEvent.getPoint() à cette liste (notes.add(mouseEvent.getPoint());, et tu appelles repaint();. Dans la méthode paintComponent, tu parcours toutes les notes de la liste pour les desisner :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    protected void paintComponent(Graphics g) {
        g.setColor(Color.BLACK);
     
        dessinerLignes(g); // dessiner les lignes de la portée
     
        for(Point note : notes) {
             dessine(g, note);
        }
     
    }
    private void dessine(Graphics note, Point note) {
         g.drawOval(note.x, note.y, LARGEUR, HAUTEUR);  // par exemple
    }
    C'est le principe de base. Ensuite, au lieu de Point, tu devrais faire une classe Note, qui a pour attributs la longueur(Ronde, blanche, noire...), la hauteur (DO, RE...), etc.., qui a une methode dessine(Graphics g) qui dessine le bon dessin (la tête, la hampe...), et au lieu de stocker des coordonnées en pixels, tu pourrais stocker des coordonnées sur la portée (position en temps depuis le début pour le x, et la hauteur servant pour le y), et faire une conversion vers x et y...

  16. #16
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Points : 1
    Points
    1
    Par défaut
    joel.drigo,
    D'abord merci pour l'affichage des codes, maintenant je sais comment les insérer et c'est vrai que c'est beaucoup plus joli.
    Ensuite je n'arrive toujours pas à afficher un rond sur le panneau parce qu'il ne veut pas ajouter le MouseEvent à ma liste. Il me dit "non-static method getPoint() cannot be referenced from a static context"
    Je sais pas si c'est en lien mais j'ai déclaré ma liste_notes en static pour qu'elle puisse être "vu" par tout mon programme. Seulement quand je fais ça il ne dit qu'il ne connaît pas le symbole Point...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static List <Point> liste_notes= new ArrayList<>();
    Citation Envoyé par joel.drigo Voir le message
    tu devrais faire une classe Note, qui a pour attributs la longueur(Ronde, blanche, noire...), la hauteur (DO, RE...), etc.., qui a une methode dessine(Graphics g) qui dessine le bon dessin (la tête, la hampe...), et au lieu de stocker des coordonnées en pixels, tu pourrais stocker des coordonnées sur la portée (position en temps depuis le début pour le x, et la hauteur servant pour le y), et faire une conversion vers x et y...
    Dans mon programme, je n'avais pas réellement prévu d'intégrer tous ces paramètres du coup est-ce que j'ai tout de même besoin de créer une classe note ? Parce que je voudrais pouvoir rejouer les notes de la partition mais pour ça je n'ai qu'à parcourir la liste, non ? J'associerai un intervalle de y à une note et ainsi de suite pour toutes les lignes et interlignes de la portée. Et avec des boucles "if", l'élément de la liste se reconnaitra dans tel ou tel "if" et jouera le son correspondant.

  17. #17
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par MC.LAPE Voir le message
    joel.drigo,
    D'abord merci pour l'affichage des codes, maintenant je sais comment les insérer et c'est vrai que c'est beaucoup plus joli.
    Ensuite je n'arrive toujours pas à afficher un rond sur le panneau parce qu'il ne veut pas ajouter le MouseEvent à ma liste. Il me dit "non-static method getPoint() cannot be referenced from a static context"
    Je sais pas si c'est en lien mais j'ai déclaré ma liste_notes en static pour qu'elle puisse être "vu" par tout mon programme. Seulement quand je fais ça il ne dit qu'il ne connaît pas le symbole Point...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static List <Point> liste_notes= new ArrayList<>();
    J'évoquais la classe java.awt.Point (le type de MouseEvent.getPoint()) : il faut l'importer pour qu'elle soit utilisable. Si tu as un message du type "non-static méthode getPoint()", c'est que tu appelles la méthode de cette façon : MouseEvent.getPoint() bien sûr la méthode n'est pas static, il faut l'appeller sur l'instance de MouseEvent reçu en paramètre de la méthode mouseClicked().

    Voici un exemple de principe qui dessine des ovales à chaque endroit où on clique (j'ai fait ça sur l'évenement mousePressed() plutôt que mouseClicked() parce que je trouve que c'est plus dynamique. TU remarqueras, qu'à part la méthode main(), et des constantes, je n'ai rien de statique :

    Je mets les imports à part, pour pas que ça prenne de place dans le message :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.RenderingHints;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.util.ArrayList;
    import java.util.List;
     
    import javax.swing.JFrame;
    import javax.swing.JPanel;


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    public class Exemple extends JPanel {
     
    	protected static final int LARGEUR = 10;
    	protected static final int HAUTEUR = 8;
     
    	private final List<Point> points = new ArrayList<Point>();
     
    	public Exemple() {
    		addMouseListener(new MouseAdapter() {
    			@Override
    			public void mousePressed(MouseEvent e) {
    				points.add(e.getPoint());
    				repaint();
    			}
     
    		});
    	}
     
    	@Override
    	protected void paintComponent(Graphics g) {
    		super.paintComponent(g);
     
    		((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
     
    		g.setColor(Color.BLACK);
    		for(Point point : points) {
    			g.fillOval(point.x-LARGEUR/2, point.y-HAUTEUR/2, LARGEUR, HAUTEUR);
    		}
    	}
     
    	public static void main(String[] args) {
    		JFrame frame = new JFrame("Démo");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		frame.getContentPane().add(new Exemple());
     
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);	
    	}
     
    }


    Dans mon programme, je n'avais pas réellement prévu d'intégrer tous ces paramètres du coup est-ce que j'ai tout de même besoin de créer une classe note ? Parce que je voudrais pouvoir rejouer les notes de la partition mais pour ça je n'ai qu'à parcourir la liste, non ? J'associerai un intervalle de y à une note et ainsi de suite pour toutes les lignes et interlignes de la portée. Et avec des boucles "if", l'élément de la liste se reconnaitra dans tel ou tel "if" et jouera le son correspondant.
    Si tu veux pouvoir jouer une note de musique, il te faut au moins la hauteur de la note (à la limite je veux bien qu'on simplifie en se passant de la longueur, tout les notes pouvant être jouées avec la même longueur), mais la hauteur, si tu t'en passes, c'est que toute les notes on la même hauteur : je ne vois pas l'intérêt de les dessiner sur une portée dans ce cas. Maintenant, bien sûr que tu peux déduire la hauteur de la position en y au moment de jouer la note, mais c'est quand même plus propre de pouvoir jouer la note en dehors de tout contexte graphique, donc de déduire la note du y au moment du dessin, et après de se baser sur cette hauteur pour déterminer comment jouer la note.

    Par contre, une boucle "if" ça n'existe pas. Il y a des boucles for, while, repeat dans certains autres langages, mais aucune boucle if. "If" c'est pour tester une condition. Si tu parles de faire des if pour déduire en fonction de différente y la note à jouer, genre l'horeur suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if ( y==0 ) {
       // jouer un do
    } else if ( y==5 ) {
       // jouer un si
    } else if ( y==10 ) {
       // jouer un la
    }
    oublie absolument cette ignominie. Déjà ça va être pénible à écrire, mais ce n'est absolument pas évolutif : si tu dois écrire ça pour 5 octaves, tu vas avoir 60 ifs (et encore, sans demi-tons) : non seulement ça va être pénible à écrire, et à lire, mais si tu te rend compte que 5 c'est trop petit, il te faut changer 60 lignes de code : fastidieux, et ça favorise les oublis et les erreurs ! Même un switch() qui serait plus adapté à ce genre de structure, est proscrit pour les mêmes raisons.
    Tu peux t'en sortir bien plus simplement par une division entière et un modulo :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int hauteurNote = yNote/5; // la hauteur de la note sur toutes les octaves : si tu veux changer 5 en 10, tu l'auras qu'une seule ligne à changer
    int octave = hauteurNode/7; // 7 notes par octave (sans demi-tons)
    int hauteurNoteDansOctave = hauteurNode%7;
    Attention, toutefois avec ce code : les notes se place sur une portée de bas en haut (le do est en bas, le si au-dessus), alors que les y vont de haut en bas. Il suffit de faire un symétrie horizontale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int yNote = hauteurDuComposant - y; // y est la position en pixels, hauteurDuComposant est la hauteur en pixels - ainsi les yNote vont de bas en haut
    int hauteurNote = yNote/5; // la hauteur de la note sur toutes les octaves : si tu veux changer 5 en 10, tu l'auras qu'une seule fois à changer
    int octave = hauteurNode/7; // 7 notes par octave (sans demi-tons)
    int hauteurNoteDansOctave = hauteurNode%7;
    4 lignes de code contre 60, en gros.

    Si tu stockes la note dans une classe Note, il suffit de redéduire le y de la hauteur et de l'octave : ainsi, tes notes seront correctement positionnés sur la partition, sans avoir à faire un traitement particulier à chaque fois que tu dessines (si tu ne fais pas ce traitement, à un moment ou à un autre, tu auras exactement comme dans mon exemple de dessin d'ovales, des notes un peu n'mporte où)

  18. #18
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Points : 1
    Points
    1
    Par défaut
    Merci pour le code qui dessine des ronds: ça marche nickel!

    Citation Envoyé par joel.drigo Voir le message
    Voici un exemple de principe qui dessine des ovales à chaque endroit où on clique (j'ai fait ça sur l'évenement mousePressed() plutôt que mouseClicked() parce que je trouve que c'est plus dynamique. TU remarqueras, qu'à part la méthode main(), et des constantes, je n'ai rien de statique
    Oui c'est vrai. Alors du coup je me demandais à quoi ça correspondait "protected" "final". Parce que si je mets "static" tout simplement, le programme marche quand même. Aussi, je ne comprends pas à quoi sert cette ligne de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    Parce que si je l'enlève, ça marche également.

    Citation Envoyé par joel.drigo Voir le message
    Tu peux t'en sortir bien plus simplement par une division entière et un modulo
    Je suis d'avis que les "if" ne sont pas de super outils lorsqu'il y a beaucoup de valeurs à traiter mais je ne comprends pas trop le code que vous avez affiché et notamment le modulo.
    Vous parlez aussi qu'il serait mieux de stocker les valeurs dans une classe Note. Un tableau ne fonctionnerait-il pas ?

    Par ailleurs, je voudrais dessiner des lignes pour la portée. Comment faire pour qu'elles aient une épaisseur? (toutefois ce n'est pas primordial, ce n'est qu'un détail)

  19. #19
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par MC.LAPE Voir le message
    Merci pour le code qui dessine des ronds: ça marche nickel!



    Oui c'est vrai. Alors du coup je me demandais à quoi ça correspondait "protected" "final". Parce que si je mets "static" tout simplement, le programme marche
    final c'est parce que je ne veux pas qu'un code puisse changer ces valeurs. Le but des constantes c'est d'avoir la valeur à un endroit dans le programme, et de s'y référer, pour éviter d'avoir à mettre la valeur litéral à plusieurs endroits (si on a besoin de la modifier, on le fait qu'à un seul endroit dans le code, et pas à plusieurs, ce qui multiplierait le risque d'oublis, ou d'erreur (2 valeurs différentes).
    protected c'est parce que j'ai estimé qu'aucune autre classe n'aurait besoin d'y accèder, sauf éventuellement une classe specialisée (qui étendrait). J'aurais pu la mettre private dans le programme d'exemple.

    Le fait qu'un exemple isolé (ou un code) fonctionne ne veut pas dire qu'il fonctionnera dans tout contexte.

    Citation Envoyé par MC.LAPE Voir le message
    quand même. Aussi, je ne comprends pas à quoi sert cette ligne de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    Parce que si je l'enlève, ça marche également.
    ça active l'antialiassage. Les petits cercles sont pas très jolis sans ça.

    Citation Envoyé par MC.LAPE Voir le message
    Je suis d'avis que les "if" ne sont pas de super outils lorsqu'il y a beaucoup de valeurs à traiter mais je ne comprends pas trop le code que vous avez affiché et notamment le modulo.
    Essaye de faire le calcul à la main ! Si tu as par exemple 4 caisses de 3 oranges : ça fait 12 oranges possibles de 0 à 11 :
    • caisse 0
      • Orange 0
      • Orange 1
      • Orange 2
    • caisse 1
      • Orange 3
      • Orange 4
      • Orange 5
    • caisse 2
      • Orange 6
      • Orange 7
      • Orange 8
    • caisse 3
      • Orange 9
      • Orange 10
      • Orange 11


    La caisse de l'orange 7 est bien 7/3=2 et sa position dans la caisse est 7%2=7-(7/3)*3=7-6=1 !

    Citation Envoyé par MC.LAPE Voir le message
    Vous parlez aussi qu'il serait mieux de stocker les valeurs dans une classe Note. Un tableau ne fonctionnerait-il pas ?
    Il ne suffit pas d'utiliser n'importe quoi pour stocker n'importe quoi. Des types sont plus adéquates que d'autres, plus pratiques, plus simples à utiliser, mieux opmisés et plus souples, plus évolutifs.
    C'est comme pour stocker un nombre en vu de faire des calculs : on peut le stocker dans une String et faire des conversions en int, mais c'est quand même plus pratique d'utiliser directement des int. On pourrait même stocker des nombres dans des tableaux de chiffres pourquoi pas et réécrire toutes les fonctions de calcul. C'est quand même pratique et lisible, sans parler du temps à écrire toutes les fonctions de calcul d'utiliser du int, ou du long.
    En outre, Java est un langage orienté objet : pourquoi ne pas faire des des classes, qui permettent de représenter plus lisiblement chaque propriété, qui permettre plus d'évolutivité et plus de souplesse au niveau modèle. Et ça permet de simplifier également, parce que ça isole le code : joueur un do c'est jouer un do noire de 12ième position dans une partition, pas faire une formule de calcul pour traduire des coordonnées en pixels vers un do noire de 12ième position ! Un tableau est fait pour stocker un ensemble de taille fixe d'éléments de même type. Une note n'est pas un point de coordonnées x et y.

    Citation Envoyé par MC.LAPE Voir le message
    Par ailleurs, je voudrais dessiner des lignes pour la portée. Comment faire pour qu'elles aient une épaisseur? (toutefois ce n'est pas primordial, ce n'est qu'un détail)
    2 solutions :
    • Dessiner un rectangle (Au lieu d'utiliser drawLine(), utiliser fillRect()). Fonctionne parce que les lignes d'une portée sont horizontales
    • Dans le cas plus général, on peut modifier l'épaisseur des traits de dessin, en rédéfissant la Stroke (utiliser une BasicStroke) en faisant ((Graphcis2D)g).setStroke(new BasicStroke(2f));, pour une épaisseur de 2. On peut utiliser drawLine(). Attention, ça s'applique à tout ce qui est dessiné après, donc il faudrait rétablir la valeur initiale au cas où.

    Ici on voit qu'on a plusieurs solutions pour faire la même chose, et les deux peuvent fonctionner. Mais on voit que la première est plus simple que la première, et suffit pour des lignes horizontales.

Discussions similaires

  1. Redimensionner des boutons et centrer un JPanel
    Par sihamnet dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 20/10/2014, 15h24
  2. Ajouter/Supprimer des boutons dans un JPanel
    Par zamborta dans le forum AWT/Swing
    Réponses: 3
    Dernier message: 29/05/2013, 09h52
  3. Avoir des boutons au dessus d'un JPanel
    Par auranx dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 08/05/2012, 01h34
  4. Décalage des boutons suite à un Zoom sur JPanel
    Par fantomasmusic dans le forum 2D
    Réponses: 2
    Dernier message: 26/01/2009, 10h25
  5. Réponses: 13
    Dernier message: 18/04/2007, 09h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo