AFAIK, нет способа получить статус ключа, который не имеет ничего общего с:
KeyStroke keyStroke = KeyStroke.getKeyStroke("A");
// NOT supported
if (keyStroke.isPressed()) {
// do something
}
Единственное, что поддерживается, это уведомление о изменении статуса отдельной клавиши, fi на самом низком уровне в KeyListener
public void keyPressed(KeyEvent e) {
if (KeyEvent.VK_A == e.getKeyCode()) {
....
}
}
Для обработки комбинаций клавиш (кроме специальных клавиш-модификаторов) невозможно отследить, какие клавиши были нажаты /выпущен, чтобы узнать, какие являются в нажатом состоянии.
Ниже приведен пример того, как это делается на уровне привязок клавиш.Основные ингредиенты
- Триггер: сущность, содержащая логику накопительного «постановки на охрану» конечного действия для выполнения
- Действие, которое отключает / выключает триггер
- Привязки клавиш для отпущенных / нажатых отдельных нажатий клавиш, привязанных к соответствующему действию постановки на охрану
Некоторый код:
// the logic container
public static interface Trigger {
public void addTrigger(String trigger);
public void arm(ActionEvent e);
public void disarm(ActionEvent e);
}
// a particular implementation which uses the actionCommand
// as identifiers
public static class ActionTrigger implements Trigger {
private Action triggered;
private List<String> triggers = new ArrayList<>();
private List<String> armed = new ArrayList<>();
public ActionTrigger(Action triggered) {
this.triggered = triggered;
}
@Override
public void arm(ActionEvent e) {
String command = e.getActionCommand();
if (!triggers.remove(command)) return;
armed.add(command);
if (triggers.isEmpty()) {
triggered.actionPerformed(e);
}
}
@Override
public void disarm(ActionEvent e) {
String command = e.getActionCommand();
if (!armed.remove(command)) return;
triggers.add(command);
}
@Override
public void addTrigger(String trigger) {
triggers.add(trigger);
}
}
// an Action notifying the trigger of dis/arms
public static class ArmingAction extends AbstractAction {
private Trigger trigger;
private boolean arm;
/**
* @param trigger
*/
public ArmingAction(Trigger trigger, String command, boolean arm) {
this.trigger = trigger;
this.arm = arm;
putValue(ACTION_COMMAND_KEY, command);
}
@Override
public void actionPerformed(ActionEvent e) {
if (arm) {
trigger.arm(e);
} else {
trigger.disarm(e);
}
}
}
// usage
// the action to trigger with multiple keys
Action action = new AbstractAction("real") {
@Override
public void actionPerformed(ActionEvent e) {
LOG.info("******triggered: " + e);
}
};
JComponent comp = new JPanel();
ActionMap actionMap = comp.getActionMap();
InputMap inputMap = comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
Trigger trigger = new ActionTrigger(action);
// the key combination
char[] chars = {'A', 'S', 'D'};
for (int i = 0; i < chars.length; i++) {
// the identifier
String command = "step" + chars[i];
trigger.addTrigger(command);
// binding for pressed
String pressedID = "pressed" + chars[i];
actionMap.put(pressedID, new ArmingAction(trigger, command, true));
inputMap.put(KeyStroke.getKeyStroke("pressed " + chars[i]), pressedID);
// binding for released
String releasedID = "released" + chars[i];
actionMap.put(releasedID, new ArmingAction(trigger, command, false));
inputMap.put(KeyStroke.getKeyStroke("released " + chars[i]), releasedID);
}
comp.add(new JButton("multibindings ... a s d"));