Hello,
Could you review the fix:
bug: https://bugs.openjdk.java.net/browse/JDK-8133453
webrev: http://cr.openjdk.java.net/~alexsch/8133453/webrev.00
The class KeyStroke has been added to the javax.swing package first
and then copied to the java.awt.AWTKeyStroke class.
Most of KeyStroke class methods looks like registering KeyStroke
class and call to the parent AWTKeyStroke method.
AWTKeyStroke class is intended to contain keyChar, keyCode,
modifiers, and keyRelease flag and it seems
there are no reasons that this class can be subclassed.
The suggestion is to remove the AWTKeyStroke.registerSubclass(Class)
method.
The AWTKeyStroke.registerSubclass(Class) method can be deprecated so
only AWTKeyStroke and KeyStroke instances is allowed to be created.
The result will be that a user code get ClassCastException when
casting a returned key stroke to the custom key stroke which has the
similar effect.
Removing the method in question leads to the binary compatibility
issue if someone uses the method. The following code will not work:
--------------------------
public class CustomKeyStroke extends AWTKeyStroke {
public static void registerCustomKeyStroke() {
AWTKeyStroke.registerSubclass(CustomKeyStroke.class); //
removed method
}
}
CustomKeyStroke.registerCustomKeyStroke();
AWTKeyStroke keyStroke = AWTKeyStroke.getAWTKeyStroke('C');
CustomKeyStroke customKeyStroke = (CustomKeyStroke) keyStroke; //
CustomKeyStroke instance is not returned
--------------------------
The proposed workaround is to use a map between unique AWTKeyStroke
instances and custom key strokes:
--------------------------
private static HashMap<AWTKeyStroke, CustomKeyStroke> keyStrokeMap
= new HashMap<>();
public static CustomKeyStroke getCustomKeyStroke(char c) {
AWTKeyStroke ketStroke = AWTKeyStroke.getAWTKeyStroke(c);
CustomKeyStroke customKeyStroke = keyStrokeMap.get(ketStroke);
if (customKeyStroke == null) {
customKeyStroke = new CustomKeyStroke(ketStroke);
keyStrokeMap.put(ketStroke, customKeyStroke);
}
return customKeyStroke;
}
--------------------------
AWT/Swing library only registers KeyStroke class
(AWTKeyStroke.registerSubclass(KeyStroke.class) calls in the KeyStroke
class)
and never registers AWTKeyStroke.class.
After the first KeyStroke.getKeyStroke(...) call in the keyStroke
class only KeyStroke instances will be created by AWTKeyStroke.
The solution proposed in the fix is to always create
javax.swing.KeyStroke instances.
Thanks,
Alexandr.