<AWT Dev> [9] Review request for 8133453 Remove AWTKeyStroke.registerSubclass(Class) method

Alexander Scherbatiy alexandr.scherbatiy at oracle.com
Tue Sep 1 10:49:22 UTC 2015


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.



More information about the awt-dev mailing list