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

JavaFX Discussion :

KeyReleased et MouseReleased


Sujet :

JavaFX

  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2018
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2018
    Messages : 12
    Par défaut KeyReleased et MouseReleased
    Bonjour,

    J'ai un petit souci avec l'interface graphique que je développe pour un synthé digital. Outre les soucis d'algorithme.

    J'ai prévu le code suivant:

    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
            for (int i = 0; i < buttons.length; i++) {
                buttons[i].setOnMousePressed(new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        playNote(event.getSource());
                    }
                });
                buttons[i].setOnMouseReleased(new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        stopNote(event.getSource());
                    }
                });
                buttons[i].setOnTouchPressed(new EventHandler<TouchEvent>() {
                    @Override
                    public void handle(TouchEvent event) {
     
                        playNote(event.getSource());
     
                    }
                });
                buttons[i].setOnTouchReleased(new EventHandler<TouchEvent>() {
                    @Override
                    public void handle(TouchEvent event) {
                        stopNote(event.getSource());
                    }
                });
            }
    Je ne sais pas si le TouchPressed fonctionne car je n'ai pas d'écran tactile. En tout cas avec le souris c'est ok.

    Par contre le pianotage en clavier ne fonctionne pas avec le code suivant:

    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
     
            titledPanes[0].setOnKeyPressed(event -> {
                for (int i = 0; i < buttons.length; i++) {
                    if (event.getCode().equals(keycode[i])) {
                        playNote(buttons[i]);
                    }
                }
            });
            titledPanes[0].setOnKeyReleased(event -> {
                for (int i = 0; i < buttons.length; i++) {
                    if (event.getCode().equals(keycode[i])) {
                        stopNote(buttons[i]);
                    }
                }
            });
    L'enfoncement des touches ne fonctionne pas bien: c'est le même comportement que pour un "KeyTyped" avec une méthode qui se lance toutes les x millisecondes. Le KeyReleased ne fonctionne pas du tout.

    https://gitlab.com/Graphics3D/MyLittleSynth

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 900
    Billets dans le blog
    54
    Par défaut
    1/ Déjà revenons a l'essentiel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (int i = 0; i < buttons.length; i++) {
                buttons[i].setOnMousePressed(event -> System.out.println("Mouse pressed"));
                buttons[i].setOnMouseReleased(event -> System.out.println("Mouse released"));
    }
    Même en laissant le doigt appuyé sur le bouton de la souris, on a juste un événement de chaque et la sortie est :

    Code console : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Mouse pressed
    Mouse released

    Coté clavier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            titledPanes[0].setOnKeyPressed(event -> System.out.println("Key pressed"));
            titledPanes[0].setOnKeyReleased(event -> System.out.println("Key released"));
    C'est un peu différent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Key pressed
    Key pressed
    Key pressed
    Key pressed
    Key pressed
    Key pressed
    [...]
    Key pressed
    Key pressed
    Key released
    Donc déjà ta boucle et la méthode startNote() vont être invoquées de nombreuses fois même si au final une même note n'est insérée qu'une seule fois.
    Après, j'ai bien événement Key released qui est envoyé mais de la a savoir s'il fonctionne comme prévu...

    2/ Au niveau structuration, je pense qu'il faut que tu revoie un peu ta méthode d’interaction avec le Player et sa liste de notes. Notamment il ne me semble pas normal que la synchronisation sur la liste des notes soit fait dans App alors que ça devrait être fait dans le Player lui-même en interne.

    Je pense notamment a un truc du genre (et je peux totalement me planter par rapport a ce que tu veux faire) :

    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
     private List<Note> currentNotes;
        private List<Note> currentNotesReadOnly;
     
    [...]
            currentNotes = Collections.synchronizedList(new ArrayList<>());
            currentNotesReadOnly = Collections.unmodifiableList(currentNotes);
    [...]
     
        public List<Note> getCurrentNotes() {
            return currentNotesReadOnly;
        }
     
        public void addNote(Note note) {
            synchronized (currentNotes) {
                currentNotes.add(note);
            }
            note.play();
        }
     
         public void stopNote(int tone) {
            synchronized (currentNotes) {
                final List<Note> toRemove = currentNotes.stream()
                        .filter(note -> note.getTone() == tone)
                        .collect(Collectors.toList());
                currentNotes.removeAll(toRemove);
                toRemove.stream()
                        .forEach(Note::stop);
                System.out.printf("Removed %d note(s)", toRemove.size());
            }
        }
     
        public void playCurrentNotes() {
            synchronized (currentNotes) {
                total = 0.0;
                currentNotes.forEach(note -> {
                            if (!note.isFinish()) {
                                double noteTime = note.getTimer().getTimeElapsed();
     
                                double positionRatioPerSecond = note.getPositionNIncr() / 44100.0;
     
                                double angle = positionRatioPerSecond * soundProductionSystem.calculateNoteFrequency(note.getTone()) * 2.0 * Math.PI;
     
                                facteurAmpl = note.getEnveloppe().getVolume(noteTime);
     
                                double ampl = 32767f * facteurAmpl;
     
                                switch (note.getWaveform()) {
                                    case SIN: // SIN
                                        total += (Math.sin(angle) * ampl);  //32767 - max value for sample to take (-32767 to 32767)
                                        break;
                                    case RECT: // RECT
                                        total += (Math.signum(Math.sin(angle)) * ampl);  //32767 - max value for sample to take (-32767 to 32767)
                                    case SAWTOOTH: // SAWTOOTH LINEAR
                                        total += ((1 - angle / 2 * Math.PI) * ampl);  //32767 - max value for sample to take (-32767 to 32767)
                                    case TRI: // TRIANGLE LINEAR
                                        total += ((1 - Math.abs(angle / 2 * Math.PI) * ampl));  //32767 - max value for sample to take (-32767 to 32767)
                                    default: // SIN
                                        total += (Math.sin(angle) * ampl);  //32767 - max value for sample to take (-32767 to 32767)
                                        break;
     
                                }
                            }
                        }
                );
                total /= currentNotes.size() > 0 ? currentNotes.size() : 1;
     
                if (currentNotes.size() > 0) {
     
                    audioViewer.sendDouble(total);
                    audioViewer.sendDouble(total);
     
                    short amplitude = (short) (total * volume / 100.0);
                    //System.out.println(amplitude);
     
                    playBuffer(amplitude);
                } else {
                    //audioViewer.sendDouble(0.0);
                    //audioViewer.sendDouble(0.0);
                }
            }
        }
    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
        private void playNote(Button source) {
            System.out.println("Tone:  " + getTone(source) + "  Note :"
                    + ((Button) source).getText() + "  "
                    + "Octave: " + (int) slider.getValue());
            Note note = noteMap.get(getTone(source));
            assert note != null;
            note.setWaveform(player.getForm());
            assert note != null;
            if (!player.getCurrentNotes().contains(note)) {
                Platform.runLater(() -> player.addNote(note));
            }
        }
     
        private void stopNote(Button source) {
            Note note = noteMap.get(getTone(source));
            assert note != null;
            System.out.println(note.getTimer().getTimeElapsed());
            Platform.runLater(() -> player.stopNote(note.getTone()));
            System.out.println("Key pressed: " + player.getCurrentNotes().size());
        }
    3/ Quand la gestion du touch, si tu veux unifier avec la souris tu peux peut-être aussi directement tenter de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for (int i = 0; i < buttons.length; i++) {
                final Button button = buttons[i];
                buttons[i].armedProperty().addListener((observable, oldValuem, newValue) -> {
                    if (newValue) {
                        playNote(button);
                    } else {
                        stopNote(button);
                    }
                });
            }
    Mais oui il faudrait aussi confirmer que ça fonctionne correctement sur un vrai touch screen car je ne suis pas sur que ce soit le cas !

    4/ au niveau fonctionnel, je peux juste donner un avis sur la boucle run() du Player qui bouffe 100% du temps CPU. J'ai essaye de ménager un temps de repos dans cette boucle mais ça semble gêner la sortie sonore (encore une fois je ne suis pas sur si la manière dont je m'y prend est correcte par rapport a ce que tu veux faire).

    Il faudrait peut-être déclarer la variable playing en volatile puisqu'elle va être accédée depuis plusieurs threads (en gros c'est comme si on mettait un bloc synchronized autour de chacun de ses accès). Sinon mettre le setter et le getter de cette variable en synchronized.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private volatile boolean playing;
    Et il me semble qu'il serait bon de nettoyer la liste après avoir invoque playCurrentNotes() histoire de retirer les notes qui sont terminées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while (isPlaying() {
        playCurrentNotes();
        removeFinishedNotes();
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [GLaux] auxKeyFunc VS keyPressed + keyReleased
    Par CinErarY dans le forum OpenGL
    Réponses: 2
    Dernier message: 18/12/2007, 20h28
  2. [KeyListener] préscision sur keyReleased
    Par mythrys dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 09/07/2007, 18h44
  3. mouseClicked et mouseReleased
    Par hammag dans le forum AWT/Swing
    Réponses: 14
    Dernier message: 18/04/2006, 15h08
  4. [MouseReleased] Probleme de detection....
    Par lilou77 dans le forum AWT/Swing
    Réponses: 3
    Dernier message: 12/12/2005, 10h04
  5. [JFrame] [Win/Linux] Comportement keyPressed/keyReleased
    Par plegat dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 23/11/2004, 18h27

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