AFinch
AFinch

Reputation: 237

java keyPressed event keeps triggering while key pressed

I have a MIDI piano program that triggers a note to be played when either the mouse is clicked on the note, or a particular keyboard key is typed. I'd like the keyPressed event to behave the same way the mousePressed event does, triggering the note to be played once while the key is being pressed.

However, it keeps playing the note over and over while the key is still pressed. I've looked at some threads regarding this topic but I still don't know how to solve the problem (I didn't fully understand how I could apply the other approaches).

Here's the keyPressed code I have now:

    @Override
    public void keyPressed(KeyEvent ke) {
        if(ke.getKeyCode() == KeyEvent.VK_Z)
        {
            channel.noteOn (((WhiteKey) WhiteKeys[0]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_X)
        {
            channel.noteOn (((WhiteKey) WhiteKeys[1]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_C)
        {
            channel.noteOn (((WhiteKey) WhiteKeys[2]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_V)
        {
            channel.noteOn (((WhiteKey) WhiteKeys[3]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_B)
        {
            channel.noteOn (((WhiteKey) WhiteKeys[4]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_N)
        {
            channel.noteOn (((WhiteKey) WhiteKeys[5]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_M)
        {
            channel.noteOn (((WhiteKey) WhiteKeys[6]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_COMMA)
        {
            channel.noteOn (((WhiteKey) WhiteKeys[7]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_PERIOD)
        {
            channel.noteOn (((WhiteKey) WhiteKeys[8]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_SLASH)
        {
            channel.noteOn (((WhiteKey) WhiteKeys[9]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_S)
        {
            channel.noteOn (((BlackKey) BlackKeys[0]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_D)
        {
            channel.noteOn (((BlackKey) BlackKeys[1]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_G)
        {
            channel.noteOn (((BlackKey) BlackKeys[2]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_H)
        {
            channel.noteOn (((BlackKey) BlackKeys[3]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_J)
        {
            channel.noteOn (((BlackKey) BlackKeys[4]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_L)
        {
            channel.noteOn (((BlackKey) BlackKeys[5]).getNote (), 127);
        }

        else if(ke.getKeyCode() == KeyEvent.VK_SEMICOLON)
        {
            channel.noteOn (((BlackKey) BlackKeys[6]).getNote (), 127);
        }
    }

Upvotes: 1

Views: 4031

Answers (1)

user0
user0

Reputation: 163

I couldn't find an event that will fire once when the key is pressed. However you could use a boolean that will be set when the key is pressed and only resets when the key is released. Then you can play the midi tune only while the boolean is false, which will be only once per keystroke.

boolean zPressed = false;

public void keyPressed(KeyEvent ke) {
    if(ke.getKeyCode() == KeyEvent.VK_Z)
    {
        if (!zPressed) {
          channel.noteOn (((WhiteKey) WhiteKeys[0]).getNote (), 127);
          zPressed = true;
       }
    }
  }

public void keyReleased(KeyEvent ke) {
    if(ke.getKeyCode() == KeyEvent.VK_Z)
    {
      zPressed = false;
    }

Upvotes: 1

Related Questions