Log me in, log me out!
There have been for long time open enhancement request in SwingX for notification about caps lock being switched on in JXLoginPanel. Over a time it acquired quite few votes (in comparison to your average swingx issue, not that 10 votes is much in absolute numbers) so I thought lets do this, it can't be that difficult.
In your average C program you just query the driver when you want to know the state of the caps lock or any other key for that matter. Not so in your average java program. Don't get me wrong, I know there is a method to get the state of the locking key
java.awt.Toolkit.getToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK). However the methods implementation is in the very least not ready for the prime time yet. When you try to use it you might get lucky enough and it will just magically work, but most likely it will not. When you distribute your program or write a library to be used by others, sooner or later you will run into problems. Either you will encounter #4414164 issue (mind you: reported first time for JDK 1.3 in 2001 and from then still "in progress") or you end up with
java.lang.UnsupportedOperationException: Toolkit.getLockingKeyState as I did (JDK 6_u2, linux 64 bit). Ever since I switched my main development enviroment to linux I'm discovering more and more of OUEs, but that's for another story.
The question remains: how to implement support or checking caps lock when function provided by the JDK doesn't do the job properly? You can rely on
KeyEvent when your login panel have a focus, but otherwise? Even with the key events all you get is just the information that the key was pressed (and therefore state of caps lock changed), but not whether it was switched on or off. So as many others before me, I decided to resolve this problem with little trick - using
java.awt.Robot login panel produces fake key event to determine whether caps lock has changed or not. Limitation of this kind of support are obvious:
- First it's tricky and can lead into more issues in the future.
- the notification works reliably only when login panel has focus (so changing caps on visible, but unfocused panel will not be updated until panel regains focus).
The second point could be possibly resolved by adding timer to the implementation which would check for the state by producing fake keyboard events, but it would also increase complexity of the feature (and thus putting even more weight on the first point - possible implementation issues).
Hopefully we can remove all this once the LockingKeyState can be obtained reliably on all platforms by querying jdk method. In the mean time I would be really interested in hearing from you how it works, or doesn't for that matter.
And since everybody naturally loves runnable demos here is one that shows Login Panel at work:
BTW, as you will notice, this little demo is signed and it needs to be signed in order for CapsLock notification to work. While this might be annoying at first consider this: When your application is distributed over the web and you require user to pass their password in, you should sign your application anyway. When running any app locally CapsLock notification will work without signing, when running unsigned app over the web the support will be switched off automatically and no exceptions thrown.