I started writing a custom KeyAdaptor so that releasing the alt key would fire an event highlighting the first item in the menu bar, to simulate how native Windows programs usually work. Then I noticed that when I alt-tab out and release alt, the program would lose focus and simultaneously highlight the menu item, which causes the defocused program to flash a notification.
I found this behaviour annoying, so I tried to disable the alt release event when tab is pressed. I then found out that since tab is a focus traversal key, it's consumed by the focus system. So I read about KeyEventDispatcher, which pre-listens for key events, and switched to that. Now it does detect tab presses, but not when the alt key is down. Why does this happen, and how do I work around it?
private class KeyController implements KeyEventDispatcher {
//true == pressed, false == not pressed
private boolean[] keyStates = new boolean[256];
private boolean ignoreNextAltRelease = false;
private void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ALT) {
if (!ignoreNextAltRelease) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
menuBar.getMenu(0).doClick();
}
});
}
ignoreNextAltRelease = false;
}
}
private void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_TAB) {
if (keyStates[KeyEvent.VK_ALT]) {
ignoreNextAltRelease = true;
}
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
keyStates[e.getKeyCode()] = true;
keyPressed(e);
}
else if (e.getID() == KeyEvent.KEY_RELEASED) {
keyStates[e.getKeyCode()] = false;
keyReleased(e);
}
return false;
}
When I have alt pressed down and then press tab, the keyPressed method is never called on tab, but when tab is released, the keyReleased method is called on tab. When I release both keys simultaneously, the keyReleased method is called on both alt and tab.