Debugging facility that allows a GUI application to wire up debug "hooks"
that can be invoked by specified key presses (some combination of modifiers and a single key). git-svn-id: https://samskivert.googlecode.com/svn/trunk@797 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// $Id: DebugChords.java,v 1.1 2002/07/17 01:51:53 mdb Exp $
|
||||
|
||||
package com.samskivert.util;
|
||||
|
||||
import java.awt.KeyEventDispatcher;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.samskivert.Log;
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.Tuple;
|
||||
|
||||
/**
|
||||
* Provides a mechanism for causing code to be invoked when a particular
|
||||
* key combination is pressed in a GUI application. The code invoked is
|
||||
* presumed to be global debugging code; this is not a mechanism for
|
||||
* implementing a client's normal user interface.
|
||||
*/
|
||||
public class DebugChords
|
||||
{
|
||||
/**
|
||||
* Provides the mechanism by which code is provided to be run when a
|
||||
* user depresses a particular key combination.
|
||||
*/
|
||||
public static interface Hook
|
||||
{
|
||||
/**
|
||||
* Called when a key combination to which this hook is bound is
|
||||
* invoked.
|
||||
*/
|
||||
public void invoke ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the debug chords services and wires up the key event
|
||||
* listener that will be used to invoke the bound code.
|
||||
*/
|
||||
public static void activate ()
|
||||
{
|
||||
// capture low-level keyboard events via the keyboard focus manager
|
||||
if (_dispatcher == null) {
|
||||
_dispatcher = new KeyEventDispatcher() {
|
||||
public boolean dispatchKeyEvent (KeyEvent e) {
|
||||
return DebugChords.dispatchKeyEvent(e);
|
||||
}
|
||||
};
|
||||
|
||||
KeyboardFocusManager keymgr =
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||
keymgr.addKeyEventDispatcher(_dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the supplied debug hook to be invoked when the specified
|
||||
* key combination is depressed.
|
||||
*
|
||||
* @param modifierMask a mask with bits on for all modifiers that must
|
||||
* be present when the specified key code is received (e.g. {@link
|
||||
* KeyEvent#CTRL_DOWN_MASK}|{@link KeyEvent#ALT_DOWN_MASK}).
|
||||
* @param keyCode the code that identifies the normal key that must be
|
||||
* pressed to activate the hook (e.g. {@link KeyEvent#VK_E}).
|
||||
* @param hook the hook to be invoked when the specified key
|
||||
* combination is received.
|
||||
*/
|
||||
public static void registerHook (int modifierMask, int keyCode, Hook hook)
|
||||
{
|
||||
// store the hooks mapped by key code
|
||||
ArrayList list = (ArrayList)_bindings.get(keyCode);
|
||||
if (list == null) {
|
||||
list = new ArrayList();
|
||||
_bindings.put(keyCode, list);
|
||||
}
|
||||
|
||||
// append the hook and modifier mask to the list
|
||||
list.add(new Tuple(new Integer(modifierMask), hook));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the {@link KeyboardFocusManager} has a key event for us
|
||||
* to scrutinize. Returns whether we've handled the key event.
|
||||
*/
|
||||
protected static boolean dispatchKeyEvent (KeyEvent e)
|
||||
{
|
||||
// ignore non-keypress events
|
||||
if (e.getID() != KeyEvent.KEY_PRESSED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// bail here if we have no hooks registered for this key code
|
||||
ArrayList list = (ArrayList)_bindings.get(e.getKeyCode());
|
||||
if (list == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// scan the list of registered hooks checking for any that match
|
||||
// the depressed set of modifier keys
|
||||
boolean handled = false;
|
||||
int hcount = list.size();
|
||||
for (int ii = 0; ii < hcount; ii++) {
|
||||
Tuple tup = (Tuple)list.get(ii);
|
||||
int mask = ((Integer)tup.left).intValue();
|
||||
if ((e.getModifiersEx() & mask) == mask) {
|
||||
Hook hook = (Hook)tup.right;
|
||||
try {
|
||||
hook.invoke();
|
||||
handled = true;
|
||||
} catch (Throwable t) {
|
||||
Log.warning("Hook failed [event=" + e +
|
||||
", hook=" + hook + "].");
|
||||
Log.logStackTrace(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
/** Intercepts key events and presents them to us for scrutiny. */
|
||||
protected static KeyEventDispatcher _dispatcher;
|
||||
|
||||
/** A mapping from key binding to debug code. */
|
||||
protected static HashIntMap _bindings = new HashIntMap();
|
||||
}
|
||||
Reference in New Issue
Block a user