Прочитав несколько связанных вопросов, я думаю, что у меня здесь уникальная ситуация.
Я создаю Java Приложение Swing, помогающее барабанщикам создавать простые стенографические таблицы песен. Имеется диалоговое окно, в котором пользователь может «ввести» ритм, который должен быть записан в MIDI-последовательность
и затем обработан в табулатуре или в нотах. Это предназначено для использования с короткими фрагментами песни.
Настройка
Идея состоит в том, что связанные JButtons запускают свое действие во время выполнения последовательности. во время записи они генерируют MidiMessage с информацией о времени. Я также хочу, чтобы кнопки визуально указывали на то, что они активированы.
Привязанные клавиши в настоящее время срабатывают правильно с использованием привязок клавиш, которые я реализовал (за исключением одновременного нажатия клавиш)...
Проблема
Важно, чтобы одновременные нажатия клавиш регистрировались как одно событие, и время здесь имеет значение.
Так, например, если пользователь одновременно нажмет H (хай-хэт) и S (малый барабан), это будет зарегистрировано как удар в унисон в том же месте на панели.
Я пробовал использовать реализацию KeyListener, подобную этой: https://stackoverflow.com/a/13529058/13113770, но с этой настройкой я столкнулся проблемы с фокусом, и хотя он может обнаруживать одновременные нажатия клавиш, он также обрабатывает их индивидуально.
Может ли кто-нибудь пролить свет на этот вопрос?
Код: Выделить всё
// code omitted
public PunchesDialog(Frame owner, Song partOwner, Part relevantPart)
{
super(owner, ModalityType.APPLICATION_MODAL);
this.partOwner = partOwner;
this.relevantPart = relevantPart;
// code omitted
/*
* Voices Panel
*/
voices = new LinkedHashMap() {{
put("crash", new VoiceButton("CRASH (C)", crashHitAction));
put("ride", new VoiceButton("RIDE (R)", rideHitAction));
put("hihat", new VoiceButton("HI-HAT (H)", hihatHitAction));
put("racktom", new VoiceButton("RACK TOM (T)", racktomHitAction));
put("snare", new VoiceButton("SNARE (S)", snareHitAction));
put("floortom", new VoiceButton("FLOOR TOM (F)", floortomHitAction));
put("kickdrum", new VoiceButton("KICK DRUM (SPACE)", kickdrumHitAction));
}};
Action crashHitAction = new CrashHitAction();
Action rideHitAction = new RideHitAction();
Action hihatHitAction = new HihatHitAction();
Action racktomHitAction = new RacktomHitAction();
Action snareHitAction = new SnareHitAction();
Action floortomHitAction = new FloortomHitAction();
Action kickdrumHitAction = new KickdrumHitAction();
KeyStroke key;
InputMap inputMap = ((JPanel) getContentPane()).
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = ((JPanel) getContentPane()).getActionMap();
key = KeyStroke.getKeyStroke(KeyEvent.VK_C, 0);
inputMap.put(key, "crashHit");
actionMap.put("crashHit", crashHitAction);
key = KeyStroke.getKeyStroke(KeyEvent.VK_R, 0);
inputMap.put(key, "rideHit");
actionMap.put("rideHit", rideHitAction);
key = KeyStroke.getKeyStroke(KeyEvent.VK_H, 0);
inputMap.put(key, "hihatHit");
actionMap.put("hihatHit", hihatHitAction);
key = KeyStroke.getKeyStroke(KeyEvent.VK_T, 0);
inputMap.put(key, "racktomHit");
actionMap.put("racktomHit", racktomHitAction);
key = KeyStroke.getKeyStroke(KeyEvent.VK_S, 0);
inputMap.put(key, "snareHit");
actionMap.put("snareHit", snareHitAction);
key = KeyStroke.getKeyStroke(KeyEvent.VK_F, 0);
inputMap.put(key, "floortomHit");
actionMap.put("floortomHit", floortomHitAction);
key = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0);
inputMap.put(key, "kickdrumHit");
actionMap.put("kickdrumHit", kickdrumHitAction);
final JPanel pnlVoices = new JPanel(new MigLayout(
"Insets 0, gap 0, wrap 2", "[fill][fill]", "fill"));
pnlVoices.add(voices.get("crash"), "w 100%, h 100%, grow");
pnlVoices.add(voices.get("ride"), "w 100%");
pnlVoices.add(voices.get("hihat"), "w 100%");
pnlVoices.add(voices.get("racktom"), "w 100%");
pnlVoices.add(voices.get("snare"), "w 100%");
pnlVoices.add(voices.get("floortom"), "w 100%");
pnlVoices.add(voices.get("kickdrum"), "span");
// code omitted
}
private class CrashHitAction extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e) {
// voices.get("crash").doClick(100);
kfMgr.clearFocusOwner();
logger.debug("hit crash");
}
}
private class RideHitAction extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e) {
// voices.get("ride").doClick(100);
kfMgr.clearFocusOwner();
logger.debug("hit ride");
}
}
private class HihatHitAction extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e) {
// voices.get("hihat").doClick(100);
kfMgr.clearFocusOwner();
logger.debug("hit hihat");
}
}
private class RacktomHitAction extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e) {
// voices.get("racktom").doClick(100);
kfMgr.clearFocusOwner();
logger.debug("hit racktom");
}
}
private class FloortomHitAction extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e) {
// voices.get("floortom").doClick(100);
kfMgr.clearFocusOwner();
logger.debug("hit floortom");
}
}
private class SnareHitAction extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e) {
// voices.get("snare").doClick(100);
kfMgr.clearFocusOwner();
logger.debug("hit snare");
}
}
private class KickdrumHitAction extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e) {
// voices.get("kickdrum").doClick(100);
kfMgr.clearFocusOwner();
logger.debug("hit kickdrum");
}
}
Подробнее здесь: https://stackoverflow.com/questions/716 ... y-bindings