2013-04-26 3 views
1

У меня есть программа MIDI-фортепиано, которая запускает ноту для воспроизведения, когда нажимают на мышь, или набирается конкретная клавиатура. Я хотел бы, чтобы событие keyPressed вел себя так же, как это делает событие mousePressed, запуская ноту, которая будет воспроизводиться один раз во время нажатия клавиши.java keyPressed event продолжает запускать при нажатой клавише

Однако он продолжает играть заметку снова и снова, пока клавиша все еще нажата. Я рассмотрел некоторые темы, касающиеся этой темы, но я до сих пор не знаю, как решить проблему (я не совсем понял, как я могу применить другие подходы).

Вот keyPressed код у меня сейчас:

@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); 
     } 
    } 
+0

Как насчет реализации keyDown вместо этого? –

+0

Спасибо, что ответили! Извините мое невежество, но как бы реализовать keyDown, поскольку он не является частью интерфейса KeyListener? Мне также нужен keyReleased метод в интерфейсе keyListener. – AFinch

ответ

1

Я не мог найти событие, которое будет срабатывать один раз при нажатии клавиши. Однако вы можете использовать логическое значение, которое будет установлено при нажатии клавиши и только сбрасывается при отпускании ключа. Затем вы можете воспроизводить миди-мелодию только в том случае, когда логическое значение false, которое будет только один раз за нажатие клавиши.

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; 
    } 
+0

Рад, что я мог помочь. Пожалуйста, отметьте правильный ответ. :) – user0

+0

Не используйте KeyListener. Вместо этого вы должны использовать [Key Bindings] (http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html). Тогда логическое значение является частью действия, используемого привязкой ключа. – camickr

Смежные вопросы