com.brianziman.ui
Class UsefulKeyAdapter

java.lang.Object
  extended by com.brianziman.ui.UsefulKeyAdapter
All Implemented Interfaces:
java.awt.event.KeyListener, java.util.EventListener

public class UsefulKeyAdapter
extends java.lang.Object
implements java.awt.event.KeyListener

This class wraps your KeyAdapter and supresses spurious repeated events.

Rationale

When running in an X11 environment, it appears as though either Java or the windowing system stupidly generate lots of repeated key events when you hold a key down. As it is impractical to get users to reconfigure their systems, and Sun seems unable to fix this issue (having been reported nearly ten years ago), This adapter is an attempt to filter out the useless events.

Many people have whined about this, but few have fixed it. Some have tried, but their solutions are not as clean as my OCD nature requires. Here are some examples of what this is meant to handle:

The goal... to generate a KeyPressed event when a key is pressed, and to generate a KeyReleased event when a key is released. And ONLY when a key is pressed or released.

Compatibility

The class is tested with Java 1.6.0 on Ubuntu 8.10, but should theoretically work on any platform, even if that platform issues events properly anyway. That is, this SHOULD work in a cross platform manner. If it doesn't, please let me know and I may fix it.

Usage

You don't actually call any of the methods on this class, directly. When Java thinks it is receiving an event, it will call the methods in this class, which will, in turn, decide whether an event has actually occurred, and call YOUR methods when you probably intended them to be called.

Replace:

 addKeyListener(new KeyAdapter() {
      public void keyPressed(KeyEvent e) { ... }
      public void keyReleased(KeyEvent e) { ... }
 });
 

with

 addKeyListener(new UsefulKeyAdapter(new KeyAdapter() {
      public void keyPressed(KeyEvent e) { ... }
      public void keyReleased(KeyEvent e) { ... }
 }));
 

Don't use this for keyTyped() events. If you are interested in these sorts of events, the default behaviour is probably what you actually want.

See How to Write a Key Listener on Sun's web site for more details.

Algorithm:

On KeyPressed

On KeyReleased

Queue Thread

License

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Copyright 2009 Brian Ziman

Please contact me if you find flaws in this software, or have any other comments or suggestions.


Constructor Summary
UsefulKeyAdapter(java.awt.event.KeyListener gKeyListener)
           
 
Method Summary
 void finalize()
          Disable the background thread when the adapter goes out of scope.
 void keyPressed(java.awt.event.KeyEvent e)
           
 void keyReleased(java.awt.event.KeyEvent e)
          In my testing, the fastest I can release a key and repress it, is about 40 ms.
 void keyTyped(java.awt.event.KeyEvent e)
          Don't use the UsefulKeyAdapter for keyTyped events.
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

UsefulKeyAdapter

public UsefulKeyAdapter(java.awt.event.KeyListener gKeyListener)
Method Detail

keyPressed

public void keyPressed(java.awt.event.KeyEvent e)
Specified by:
keyPressed in interface java.awt.event.KeyListener

keyReleased

public void keyReleased(java.awt.event.KeyEvent e)
In my testing, the fastest I can release a key and repress it, is about 40 ms. Also in my testing, I found that the auto-repeat delay is 0 ms between bogus release and the next bogus press. I assume that no keyboard is more than three times as responsive as mine, and that no computer will use an auto-repeat algorithm slower than 10ms. If you find these assumptions in error, please let me know.

Specified by:
keyReleased in interface java.awt.event.KeyListener

keyTyped

public void keyTyped(java.awt.event.KeyEvent e)
Don't use the UsefulKeyAdapter for keyTyped events.

Specified by:
keyTyped in interface java.awt.event.KeyListener

finalize

public void finalize()
Disable the background thread when the adapter goes out of scope. Not guaranteed to be called, but it's polite to clean up resources.

Overrides:
finalize in class java.lang.Object