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.

Reply via email to