FileDocCategorySizeDatePackage
AWTKeyStroke.javaAPI DocJava SE 5 API29340Fri Aug 26 14:56:42 BST 2005java.awt

AWTKeyStroke

public class AWTKeyStroke extends Object implements Serializable
An AWTKeyStroke represents a key action on the keyboard, or equivalent input device. AWTKeyStrokes can correspond to only a press or release of a particular key, just as KEY_PRESSED and KEY_RELEASED KeyEvents do; alternately, they can correspond to typing a specific Java character, just as KEY_TYPED KeyEvents do. In all cases, AWTKeyStrokes can specify modifiers (alt, shift, control, meta, or a combination thereof) which must be present during the action for an exact match.

AWTKeyStrokes are immutable, and are intended to be unique. Client code should never create an AWTKeyStroke on its own, but should instead use a variant of getAWTKeyStroke. Client use of these factory methods allows the AWTKeyStroke implementation to cache and share instances efficiently.

see
#getAWTKeyStroke
version
1.23, 05/05/04
author
Arnaud Weber
author
David Mendenhall
since
1.4

Fields Summary
static final long
serialVersionUID
private static Map
cache
private static AWTKeyStroke
cacheKey
private static Constructor
ctor
private static Map
modifierKeywords
private static VKCollection
vks
Associates VK_XXX (as a String) with code (as Integer). This is done to avoid the overhead of the reflective call to find the constant.
private char
keyChar
private int
keyCode
private int
modifiers
private boolean
onKeyRelease
Constructors Summary
protected AWTKeyStroke()
Constructs an AWTKeyStroke with default values. The default values used are:
PropertyDefault Value
Key Char KeyEvent.CHAR_UNDEFINED
Key Code KeyEvent.VK_UNDEFINED
Modifiers none
On key release? false
AWTKeyStrokes should not be constructed by client code. Use a variant of getAWTKeyStroke instead.

see
#getAWTKeyStroke


     
        /* ensure that the necessary native libraries are loaded */
        Toolkit.loadLibraries();
    
    
protected AWTKeyStroke(char keyChar, int keyCode, int modifiers, boolean onKeyRelease)
Constructs an AWTKeyStroke with the specified values. AWTKeyStrokes should not be constructed by client code. Use a variant of getAWTKeyStroke instead.

param
keyChar the character value for a keyboard key
param
keyCode the key code for this AWTKeyStroke
param
modifiers a bitwise-ored combination of any modifiers
param
onKeyRelease true if this AWTKeyStroke corresponds to a key release; false otherwise
see
#getAWTKeyStroke

        this.keyChar = keyChar;
	this.keyCode = keyCode;
	this.modifiers = modifiers;
	this.onKeyRelease = onKeyRelease;
    
Methods Summary
public final booleanequals(java.lang.Object anObject)
Returns true if this object is identical to the specified object.

param
anObject the Object to compare this object to
return
true if the objects are identical

        if (anObject instanceof AWTKeyStroke) {
            AWTKeyStroke ks = (AWTKeyStroke)anObject;
	    return (ks.keyChar == keyChar && ks.keyCode == keyCode && 
		    ks.onKeyRelease == onKeyRelease &&
		    ks.modifiers == modifiers);
        }
        return false;
    
public static java.awt.AWTKeyStrokegetAWTKeyStroke(java.lang.String s)
Parses a string and returns an AWTKeyStroke. The string must have the following syntax:
<modifiers>* (<typedID> | <pressedReleasedID>)

modifiers := shift | control | ctrl | meta | alt | altGraph
typedID := typed <typedKey>
typedKey := string of length 1 giving Unicode character.
pressedReleasedID := (pressed | released) key
key := KeyEvent key code name, i.e. the name following "VK_".
If typed, pressed or released is not specified, pressed is assumed. Here are some examples:
"INSERT" => getAWTKeyStroke(KeyEvent.VK_INSERT, 0);
"control DELETE" => getAWTKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);
"alt shift X" => getAWTKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);
"alt shift released X" => getAWTKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);
"typed a" => getAWTKeyStroke('a');

param
s a String formatted as described above
return
an AWTKeyStroke object for that String
throws
IllegalArgumentException if s is null, or is formatted incorrectly

	if (s == null) {
	    throw new IllegalArgumentException("String cannot be null");
	}

        final String errmsg = "String formatted incorrectly";

        StringTokenizer st = new StringTokenizer(s, " ");

	int mask = 0;
	boolean released = false;
	boolean typed = false;
	boolean pressed = false;

        if (modifierKeywords == null) {
	    synchronized (AWTKeyStroke.class) {
	        if (modifierKeywords == null) {
		    Map uninitializedMap = new HashMap(8, 1.0f);
		    uninitializedMap.put("shift",
					 new Integer(InputEvent.SHIFT_DOWN_MASK
						     |InputEvent.SHIFT_MASK));
		    uninitializedMap.put("control",
					 new Integer(InputEvent.CTRL_DOWN_MASK
						     |InputEvent.CTRL_MASK));
		    uninitializedMap.put("ctrl",
					 new Integer(InputEvent.CTRL_DOWN_MASK
						     |InputEvent.CTRL_MASK));
		    uninitializedMap.put("meta",
					 new Integer(InputEvent.META_DOWN_MASK
						     |InputEvent.META_MASK));
		    uninitializedMap.put("alt",
					 new Integer(InputEvent.ALT_DOWN_MASK
						     |InputEvent.ALT_MASK));
		    uninitializedMap.put("altGraph",
					 new Integer(InputEvent.ALT_GRAPH_DOWN_MASK
						     |InputEvent.ALT_GRAPH_MASK));
		    uninitializedMap.put("button1",
					 new Integer(InputEvent.BUTTON1_DOWN_MASK));
		    uninitializedMap.put("button2",
					 new Integer(InputEvent.BUTTON2_DOWN_MASK));
		    uninitializedMap.put("button3",
					 new Integer(InputEvent.BUTTON3_DOWN_MASK));
		    modifierKeywords =
		        Collections.synchronizedMap(uninitializedMap);
		}
	    }
	}

	int count = st.countTokens();

	for (int i = 1; i <= count; i++) {
	    String token = st.nextToken();

	    if (typed) {
	        if (token.length() != 1 || i != count) {
		    throw new IllegalArgumentException(errmsg);
		}
		return getCachedStroke(token.charAt(0), KeyEvent.VK_UNDEFINED,
				       mask, false);
	    }

	    if (pressed || released || i == count) {
	        if (i != count) {
		    throw new IllegalArgumentException(errmsg);
		}

		String keyCodeName = "VK_" + token;
		int keyCode = getVKValue(keyCodeName);

		return getCachedStroke(KeyEvent.CHAR_UNDEFINED, keyCode,
				       mask, released);
	    }

	    if (token.equals("released")) {
		released = true;
		continue;
	    }
	    if (token.equals("pressed")) {
	        pressed = true;
		continue;
	    }
	    if (token.equals("typed")) {
		typed = true;
		continue;
	    }

	    Integer tokenMask = (Integer)modifierKeywords.get(token);
	    if (tokenMask != null) {
		mask |= tokenMask.intValue();
	    } else {
	        throw new IllegalArgumentException(errmsg);
	    }
	}

	throw new IllegalArgumentException(errmsg);
    
public static java.awt.AWTKeyStrokegetAWTKeyStroke(char keyChar)
Returns a shared instance of an AWTKeyStroke that represents a KEY_TYPED event for the specified character.

param
keyChar the character value for a keyboard key
return
an AWTKeyStroke object for that key

        return getCachedStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false);
    
public static java.awt.AWTKeyStrokegetAWTKeyStroke(java.lang.Character keyChar, int modifiers)
Returns a shared instance of an AWTKeyStroke, given a Character object and a set of modifiers. Note that the first parameter is of type Character rather than char. This is to avoid inadvertent clashes with calls to getAWTKeyStroke(int keyCode, int modifiers). The modifiers consist of any combination of:
  • java.awt.event.InputEvent.SHIFT_DOWN_MASK
  • java.awt.event.InputEvent.CTRL_DOWN_MASK
  • java.awt.event.InputEvent.META_DOWN_MASK
  • java.awt.event.InputEvent.ALT_DOWN_MASK
  • java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
The old modifiers
  • java.awt.event.InputEvent.SHIFT_MASK
  • java.awt.event.InputEvent.CTRL_MASK
  • java.awt.event.InputEvent.META_MASK
  • java.awt.event.InputEvent.ALT_MASK
  • java.awt.event.InputEvent.ALT_GRAPH_MASK
also can be used, but they are mapped to _DOWN_ modifiers. Since these numbers are all different powers of two, any combination of them is an integer in which each bit represents a different modifier key. Use 0 to specify no modifiers.

param
keyChar the Character object for a keyboard character
param
modifiers a bitwise-ored combination of any modifiers
return
an AWTKeyStroke object for that key
throws
IllegalArgumentException if keyChar is null
see
java.awt.event.InputEvent

        if (keyChar == null) {
	    throw new IllegalArgumentException("keyChar cannot be null");
	} 
        return getCachedStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED,
			       modifiers, false);
    
public static java.awt.AWTKeyStrokegetAWTKeyStroke(int keyCode, int modifiers, boolean onKeyRelease)
Returns a shared instance of an AWTKeyStroke, given a numeric key code and a set of modifiers, specifying whether the key is activated when it is pressed or released.

The "virtual key" constants defined in java.awt.event.KeyEvent can be used to specify the key code. For example:

  • java.awt.event.KeyEvent.VK_ENTER
  • java.awt.event.KeyEvent.VK_TAB
  • java.awt.event.KeyEvent.VK_SPACE
The modifiers consist of any combination of:
  • java.awt.event.InputEvent.SHIFT_DOWN_MASK
  • java.awt.event.InputEvent.CTRL_DOWN_MASK
  • java.awt.event.InputEvent.META_DOWN_MASK
  • java.awt.event.InputEvent.ALT_DOWN_MASK
  • java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
The old modifiers
  • java.awt.event.InputEvent.SHIFT_MASK
  • java.awt.event.InputEvent.CTRL_MASK
  • java.awt.event.InputEvent.META_MASK
  • java.awt.event.InputEvent.ALT_MASK
  • java.awt.event.InputEvent.ALT_GRAPH_MASK
also can be used, but they are mapped to _DOWN_ modifiers. Since these numbers are all different powers of two, any combination of them is an integer in which each bit represents a different modifier key. Use 0 to specify no modifiers.

param
keyCode an int specifying the numeric code for a keyboard key
param
modifiers a bitwise-ored combination of any modifiers
param
onKeyRelease true if the AWTKeyStroke should represent a key release; false otherwise
return
an AWTKeyStroke object for that key
see
java.awt.event.KeyEvent
see
java.awt.event.InputEvent

        return getCachedStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers,
			       onKeyRelease);
    
public static java.awt.AWTKeyStrokegetAWTKeyStroke(int keyCode, int modifiers)
Returns a shared instance of an AWTKeyStroke, given a numeric key code and a set of modifiers. The returned AWTKeyStroke will correspond to a key press.

The "virtual key" constants defined in java.awt.event.KeyEvent can be used to specify the key code. For example:

  • java.awt.event.KeyEvent.VK_ENTER
  • java.awt.event.KeyEvent.VK_TAB
  • java.awt.event.KeyEvent.VK_SPACE
The modifiers consist of any combination of:
  • java.awt.event.InputEvent.SHIFT_DOWN_MASK
  • java.awt.event.InputEvent.CTRL_DOWN_MASK
  • java.awt.event.InputEvent.META_DOWN_MASK
  • java.awt.event.InputEvent.ALT_DOWN_MASK
  • java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
The old modifiers
  • java.awt.event.InputEvent.SHIFT_MASK
  • java.awt.event.InputEvent.CTRL_MASK
  • java.awt.event.InputEvent.META_MASK
  • java.awt.event.InputEvent.ALT_MASK
  • java.awt.event.InputEvent.ALT_GRAPH_MASK
also can be used, but they are mapped to _DOWN_ modifiers. Since these numbers are all different powers of two, any combination of them is an integer in which each bit represents a different modifier key. Use 0 to specify no modifiers.

param
keyCode an int specifying the numeric code for a keyboard key
param
modifiers a bitwise-ored combination of any modifiers
return
an AWTKeyStroke object for that key
see
java.awt.event.KeyEvent
see
java.awt.event.InputEvent

        return getCachedStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers,
			       false);
    
public static java.awt.AWTKeyStrokegetAWTKeyStrokeForEvent(java.awt.event.KeyEvent anEvent)
Returns an AWTKeyStroke which represents the stroke which generated a given KeyEvent.

This method obtains the keyChar from a KeyTyped event, and the keyCode from a KeyPressed or KeyReleased event. The KeyEvent modifiers are obtained for all three types of KeyEvent.

param
anEvent the KeyEvent from which to obtain the AWTKeyStroke
throws
NullPointerException if anEvent is null
return
the AWTKeyStroke that precipitated the event

        int id = anEvent.getID();
        switch(id) {
          case KeyEvent.KEY_PRESSED:
          case KeyEvent.KEY_RELEASED:
	    return getCachedStroke(KeyEvent.CHAR_UNDEFINED,
				   anEvent.getKeyCode(),
				   anEvent.getModifiers(),
				   (id == KeyEvent.KEY_RELEASED));
          case KeyEvent.KEY_TYPED:
	    return getCachedStroke(anEvent.getKeyChar(),
				   KeyEvent.VK_UNDEFINED,
				   anEvent.getModifiers(),
				   false);
          default:
            // Invalid ID for this KeyEvent
            return null;
        }
    
private static synchronized java.awt.AWTKeyStrokegetCachedStroke(char keyChar, int keyCode, int modifiers, boolean onKeyRelease)

	if (cache == null) {
	    cache = new HashMap();
	}
 
	if (cacheKey == null) {
	    try {
		cacheKey = (AWTKeyStroke)ctor.newInstance(null);
	    } catch (InstantiationException e) {
                assert(false); 
            } catch (IllegalAccessException e) {
                assert(false); 
            } catch (InvocationTargetException e) {
                assert(false); 
	    }
	}
	cacheKey.keyChar = keyChar;
	cacheKey.keyCode = keyCode;
	cacheKey.modifiers = mapNewModifiers(mapOldModifiers(modifiers));
	cacheKey.onKeyRelease = onKeyRelease;
 
	AWTKeyStroke stroke = (AWTKeyStroke)cache.get(cacheKey);
	if (stroke == null) {
	    stroke = cacheKey;
	    cache.put(stroke, stroke);
	    cacheKey = null;
	}
	
	return stroke;
    
private static java.lang.reflect.ConstructorgetCtor(java.lang.Class clazz)

        Object ctor = AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                try {
                    Constructor ctor = clazz.getDeclaredConstructor(null);
                    if (ctor != null) {
                        ctor.setAccessible(true);
                    }
                    return ctor;
                } catch (SecurityException e) {
                } catch (NoSuchMethodException e) {
                }
                return null;
            }
        });
        return (Constructor)ctor;
    
public final chargetKeyChar()
Returns the character for this AWTKeyStroke.

return
a char value
see
#getAWTKeyStroke(char)

        return keyChar;
    
public final intgetKeyCode()
Returns the numeric key code for this AWTKeyStroke.

return
an int containing the key code value
see
#getAWTKeyStroke(int,int)

        return keyCode;
    
public final intgetKeyEventType()
Returns the type of KeyEvent which corresponds to this AWTKeyStroke.

return
KeyEvent.KEY_PRESSED, KeyEvent.KEY_TYPED, or KeyEvent.KEY_RELEASED
see
java.awt.event.KeyEvent

	if (keyCode == KeyEvent.VK_UNDEFINED) {
	    return KeyEvent.KEY_TYPED;
	} else {
	    return (onKeyRelease)
		? KeyEvent.KEY_RELEASED
		: KeyEvent.KEY_PRESSED;
	}
    
public final intgetModifiers()
Returns the modifier keys for this AWTKeyStroke.

return
an int containing the modifiers
see
#getAWTKeyStroke(int,int)

        return modifiers;
    
static java.lang.StringgetModifiersText(int modifiers)

        StringBuffer buf = new StringBuffer();

        if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0 ) {
            buf.append("shift ");
        }
        if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0 ) {
            buf.append("ctrl ");
        }
        if ((modifiers & InputEvent.META_DOWN_MASK) != 0 ) {
            buf.append("meta ");
        }
        if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0 ) {
            buf.append("alt ");
        }
        if ((modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0 ) {
            buf.append("altGraph ");
        }
        if ((modifiers & InputEvent.BUTTON1_DOWN_MASK) != 0 ) {
            buf.append("button1 ");
        }
        if ((modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0 ) {
            buf.append("button2 ");
        }
        if ((modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0 ) {
            buf.append("button3 ");
        }

        return buf.toString();
    
private static java.awt.VKCollectiongetVKCollection()

        if (vks == null) {
            vks = new VKCollection();
        }
        return vks;
    
static java.lang.StringgetVKText(int keyCode)

 
        VKCollection vkCollect = getVKCollection();
        Integer key = new Integer(keyCode);
        String name = vkCollect.findName(key);
        if (name != null) {
            return name.substring(3);
        }
        int expected_modifiers = 
            (Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);

        Field[] fields = KeyEvent.class.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            try {
                if (fields[i].getModifiers() == expected_modifiers
                    && fields[i].getType() == Integer.TYPE
                    && fields[i].getName().startsWith("VK_")
                    && fields[i].getInt(KeyEvent.class) == keyCode) 
                {
                    name = fields[i].getName();
                    vkCollect.put(name, key);
                    return name.substring(3);
                }
            } catch (IllegalAccessException e) {
                assert(false);
            }
        }
        return "UNKNOWN";
    
private static intgetVKValue(java.lang.String key)
Returns the integer constant for the KeyEvent.VK field named key. This will throw an IllegalArgumentException if key is not a valid constant.

        VKCollection vkCollect = getVKCollection();

        Integer value = vkCollect.findCode(key);

        if (value == null) {
            int keyCode = 0;
            final String errmsg = "String formatted incorrectly";

            try {
                keyCode = KeyEvent.class.getField(key).getInt(KeyEvent.class);
            } catch (NoSuchFieldException nsfe) {
                throw new IllegalArgumentException(errmsg);
            } catch (IllegalAccessException iae) {
                throw new IllegalArgumentException(errmsg);
            }
            value = new Integer(keyCode);
            vkCollect.put(key, value);
        }
        return value.intValue();
    
public inthashCode()
Returns a numeric value for this object that is likely to be unique, making it a good choice as the index value in a hash table.

return
an int that represents this object

        return (((int)keyChar) + 1) * (2 * (keyCode + 1)) * (modifiers + 1) +
            (onKeyRelease ? 1 : 2);
    
public final booleanisOnKeyRelease()
Returns whether this AWTKeyStroke represents a key release.

return
true if this AWTKeyStroke represents a key release; false otherwise
see
#getAWTKeyStroke(int,int,boolean)

        return onKeyRelease;
    
private static intmapNewModifiers(int modifiers)

       	if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0) {
	    modifiers |= InputEvent.SHIFT_MASK;
	}
	if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0) {
	    modifiers |= InputEvent.ALT_MASK;
	}
	if ((modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) {
	    modifiers |= InputEvent.ALT_GRAPH_MASK;
	}
	if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0) {
	    modifiers |= InputEvent.CTRL_MASK;
	}
	if ((modifiers & InputEvent.META_DOWN_MASK) != 0) {
	    modifiers |= InputEvent.META_MASK;
	}
 	
	return modifiers;
    
private static intmapOldModifiers(int modifiers)

       	if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
	    modifiers |= InputEvent.SHIFT_DOWN_MASK;
	}
	if ((modifiers & InputEvent.ALT_MASK) != 0) {
	    modifiers |= InputEvent.ALT_DOWN_MASK;
	}
	if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
	    modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
	}
	if ((modifiers & InputEvent.CTRL_MASK) != 0) {
	    modifiers |= InputEvent.CTRL_DOWN_MASK;
	}
	if ((modifiers & InputEvent.META_MASK) != 0) {
	    modifiers |= InputEvent.META_DOWN_MASK;
	}

 	modifiers &= InputEvent.SHIFT_DOWN_MASK
 	    | InputEvent.ALT_DOWN_MASK
 	    | InputEvent.ALT_GRAPH_DOWN_MASK
 	    | InputEvent.CTRL_DOWN_MASK
 	    | InputEvent.META_DOWN_MASK
 	    | InputEvent.BUTTON1_DOWN_MASK
 	    | InputEvent.BUTTON2_DOWN_MASK
 	    | InputEvent.BUTTON3_DOWN_MASK;
 	
	return modifiers;
    
protected java.lang.ObjectreadResolve()
Returns a cached instance of AWTKeyStroke (or a subclass of AWTKeyStroke) which is equal to this instance.

return
a cached instance which is equal to this instance

        synchronized (AWTKeyStroke.class) {
	    Class newClass = getClass();
	    if (!newClass.equals(ctor.getDeclaringClass())) {
	        registerSubclass(newClass);
	    }
	    return getCachedStroke(keyChar, keyCode, modifiers, onKeyRelease);
	}
    
protected static voidregisterSubclass(java.lang.Class subclass)
Registers a new class which the factory methods in AWTKeyStroke will use when generating new instances of AWTKeyStrokes. After invoking this method, the factory methods will return instances of the specified Class. The specified Class must be either AWTKeyStroke or derived from AWTKeyStroke, and it must have a no-arg constructor. The constructor can be of any accessibility, including private. This operation flushes the current AWTKeyStroke cache.

param
subclass the new Class of which the factory methods should create instances
throws
IllegalArgumentException if subclass is null, or if subclass does not have a no-arg constructor
throws
ClassCastException if subclass is not AWTKeyStroke, or a class derived from AWTKeyStroke

        if (subclass == null) {
	    throw new IllegalArgumentException("subclass cannot be null");
	}
	if (AWTKeyStroke.ctor.getDeclaringClass().equals(subclass)) {
	    // Already registered
	    return;
	}
	if (!AWTKeyStroke.class.isAssignableFrom(subclass)) {
	    throw new ClassCastException("subclass is not derived from AWTKeyStroke");
	}

        Constructor ctor = getCtor(subclass);

	String couldNotInstantiate = "subclass could not be instantiated";

        if (ctor == null) {
	    throw new IllegalArgumentException(couldNotInstantiate);
	}
	try {
	    AWTKeyStroke stroke = (AWTKeyStroke)ctor.newInstance(null);
	    if (stroke == null) {
	        throw new IllegalArgumentException(couldNotInstantiate);
	    }
	} catch (NoSuchMethodError e) {
	    throw new IllegalArgumentException(couldNotInstantiate);
	} catch (ExceptionInInitializerError e) {
	    throw new IllegalArgumentException(couldNotInstantiate);
	} catch (InstantiationException e) {
	    throw new IllegalArgumentException(couldNotInstantiate);
	} catch (IllegalAccessException e) {
	    throw new IllegalArgumentException(couldNotInstantiate);
	} catch (InvocationTargetException e) {
	    throw new IllegalArgumentException(couldNotInstantiate);
	}

	synchronized (AWTKeyStroke.class) {
	    AWTKeyStroke.ctor = ctor;
	    cache = null;
	    cacheKey = null;
	}
    
public java.lang.StringtoString()
Returns a string that displays and identifies this object's properties. The String returned by this method can be passed as a parameter to getAWTKeyStroke(String) to produce a key stroke equal to this key stroke.

return
a String representation of this object
see
#getAWTKeyStroke(String)

        if (keyCode == KeyEvent.VK_UNDEFINED) {
            return getModifiersText(modifiers) + "typed " + keyChar;
        } else {
            return getModifiersText(modifiers) +
                (onKeyRelease ? "released" : "pressed") + " " +
                getVKText(keyCode);
        }