org.jdesktop.swingx.plaf.basic.CapsLockSupport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swingx-all Show documentation
Show all versions of swingx-all Show documentation
A Maven project to aggregate all modules into a single artifact.
package org.jdesktop.swingx.plaf.basic;
import static java.awt.event.KeyEvent.VK_CAPS_LOCK;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import org.jdesktop.beans.AbstractBean;
/**
* A class for determining the state of the {@link java.awt.event.KeyEvent.VK_CAPS_LOCK CAPS LOCK
* key}. It also supports notification when the locking state changes.
*
* Although it is possible to use {@link Toolkit#getLockingKeyState(int)} to determine the current
* state of the CAPS LOCK key, that method is not guaranteed to work on all platforms. This class
* attempts to handle those shortfalls and provide an easy mechanism for listening to state changes.
*
*
* CapsLockSupport cls = CapsLockSupport.getInstance();
* // for get the current state of the caps lock key
* boolean currentState = cls.isCapsLockEnabled();
* // for listening to changes in the caps lock state
* cls.addPropertyChangeListener("capsLockEnabled", myListener);
*
*
* There is one special case to be aware of. If {@code CapsLockSupport} is not able to determine the
* state of the CAPS LOCK key, then {@link #isInitialized()} will return {@code false} until it is
* able to introspect a {@link KeyEvent} and determine the current locking state. If
* {@code CapsLockSupport} must use delayed initialization, it will fire a property change to notify
* listeners that it is now in an accurate state.
*
* @author kschaefer
*/
public final class CapsLockSupport extends AbstractBean implements KeyEventDispatcher {
private boolean useToolkit;
private boolean capsLockeEnabled;
private boolean updateViaKeyEvent;
private static class SingletonHolder {
private static final CapsLockSupport INSTANCE = new CapsLockSupport();
static {
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(INSTANCE);
}
}
private CapsLockSupport() {
try {
capsLockeEnabled = Toolkit.getDefaultToolkit().getLockingKeyState(VK_CAPS_LOCK);
useToolkit = true;
updateViaKeyEvent = false;
} catch (UnsupportedOperationException e) {
capsLockeEnabled = false;
useToolkit = false;
updateViaKeyEvent = true;
}
}
/**
* Gets the only instance of {@code CapsLockSupport}.
*
* @return the {@code CapsLockSupport} instance
*/
public static CapsLockSupport getInstance() {
return SingletonHolder.INSTANCE;
}
/**
* Determines if {@code CapsLockSupport} is accurately synchronized with the state of the CAPS
* LOCK key. When not initialized, {@link #isCapsLockEnabled()} will always return {@code false}
* . {@code CapsLockSupport} will fail to initialize only if
* {@code Toolkit#getLockingKeyState(int)} throws an exception; in that case, it will initialize
* as soon as it receives a valid key event (that can be used to determine the current locking
* state).
*
* @return {@code true} if {@code CapsLockSupport} accurately knows the state of the CAPS LOCK
* key
*/
public boolean isInitialized() {
return useToolkit || (useToolkit ^ updateViaKeyEvent);
}
/**
* Determines the current state of the {@link java.awt.event.KeyEvent.VK_CAPS_LOCK CAPS LOCK key}.
*
* @return {@code true} if CAPS LOCK is enabled; {@code false} otherwise
*/
public boolean isCapsLockEnabled() {
if (useToolkit) {
try {
return Toolkit.getDefaultToolkit().getLockingKeyState(VK_CAPS_LOCK);
} catch (UnsupportedOperationException shouldNeverHappen) {
return capsLockeEnabled;
}
}
return capsLockeEnabled;
}
void setCapsLockEnabled(boolean capsLockEnabled) {
boolean oldValue = this.capsLockeEnabled;
this.capsLockeEnabled = capsLockEnabled;
firePropertyChange("capsLockEnabled", oldValue, this.capsLockeEnabled); //$NON-NLS-1$
}
// updateViaKeyEvent is use to find the initial state of the CAPS LOCK key when the Toolkit does
// not support it
/**
* This is an implementation detail and should not be considered public.
*/
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
int keyCode = e.getKeyCode();
if (keyCode == VK_CAPS_LOCK) {
if (!updateViaKeyEvent) {
if (useToolkit) {
try {
setCapsLockEnabled(Toolkit.getDefaultToolkit().getLockingKeyState(VK_CAPS_LOCK));
} catch (UnsupportedOperationException shouldNeverHappen) {
setCapsLockEnabled(!capsLockeEnabled);
}
} else {
setCapsLockEnabled(!capsLockeEnabled);
}
}
} else if (updateViaKeyEvent && Character.isLetter(keyCode)) {
if (keyCode == e.getKeyChar()) {
capsLockeEnabled = !e.isShiftDown();
} else {
capsLockeEnabled = e.isShiftDown();
}
updateViaKeyEvent = false;
firePropertyChange("initialized", false, true); //$NON-NLS-1$
}
}
return false;
}
}