Problems overriding a package visible method from a JDK-class
To provide a fix/work-around for a JDK-bug I need to override a package
visible method (BasicMenuItemUI.updateAcceleratorBinding()) in class from
the JDK. IMHO this should be possible by placing my own class in the same
package (here javax.swing.plaf.basic). Unfortunately, it seems not to work -
although the class instance is my own class, the method invocations call the
JDK method.
Do I have a thinking barrier to see the obvious or do behave JDK packages
different than my own packages?
Thanks in advance.
Tom
Please sign in to leave a comment.
Does somebody knows why overriding a package visible JDK method does not
work? Should it work like for "normal" packages?
Tom
The standard library packages are sealed, so you cannot add to them from a separate JAR file.
Randall Schulz
Thanks for the help.
Tom
I haven't checked recently, but I believe it's also a violation of the
licensing terms to add classes in the java.* and javax.* package
hierarchies.
I'm not familiar with the sealed jars feature, In distant times you could do that by using the bootclasspath I think, would it still work ?
Extending the JDK that way is not something I've tried, and is definitely not recommended (if permitted at all) by Sun, but an alternative may be to override the methods that call updateAcceleratorBinding() - as far as I can see, there are only two: the protected method installKeyboardActions(), a 2-liner, and the public method propertyChange(..) in the nested Handler class, which is quite short. A fly in the ointment may be that the nested Handler class is subclassed elsewhere...
Edited by: Dave Lorde on Apr 16, 2008 2:04 PM
OK, I've finally found a way to solve the problem in an PLAF-independent way.
For those who are interested about the problem:
We wanted to use the accelerator KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,
0) to mark some items as read (it must be an accelerator, because it should
be customizable by the user like other accelerators). Unfortunately, when
having the focus in a text field, the text field itself consumed the key
press as well as the menu item was invoked. We could work around this by
using the KeyStroke.getKeyStroke(' ') instead, but in this case the
accelerator did not show up in the menu (you know, white text on white
background).
Tom
And what solution did you find? I assume the workaround you mention was not good enough for you?
Bas
Nice! Thanks for the update.
Bas
Tom wrote:
When setting an accelerator to a menu item, the look and feel maps the
keystroke to a "doClick" action in the input map. Fortunately, there was
only one central place in our code setting a menu item's accelerator, so I
just replace the old keystroke from the input map with the corrected one (if
necessary) after the accelerator was set. This trivial solution works as
expected (e.g. 'space' is only processed as accelerator if the component or
its parents did not consume it already) and the accelerator is displayed
correctly in the menu.
Tom