Reputation: 116
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.
Upvotes: 0
Views: 253
Reputation: 443
Under macOS, there is the com.apple.eawt.AppForegroundListener
which will tell you when the App is moved to background (which happens when the user presses CMD + TAB, which in turn corresponds to ALT + TAB under Windows). An AppForegroundEvent
is fired when the App is moved to background (i.e. another App is active) or when it is moved to foreground again.
I suppose under Windows there would be a similar package that allows to keep track of those events that are handled on OS basis.
com.apple.eawt
itself seems to be no longer available since Java 9, so have a look around the net to see more up-to-date implementations.
If your intention is to handle the ALT + TAB key in your application, you should implement appMovedToBackground(AppForegroundEvent e)
, detect whether the app was moved to background by ALT + TAB or by clicking on another applications icon/window (guess that will be the hard part). Then put your application to foreground again and do whatever you intended to do with the ALT + TAB key-Event.
Upvotes: 1