<Swing Dev> [9] Crash tabbing to a checkbox with custom model (see e.g. 8074883)
Luke
ldubox-coding101 at yahoo.co.uk
Sun Jun 18 22:33:15 UTC 2017
Good day,
I believe I've hit my first bug in occasional testingof the JDK-9 drops.
I hope this is an appropriate way to send feedback?
We use a customised "tri-state" checkbox, which triggers a crash when the
keyboard focus moves to it by pressing the TAB key. The issue seems related
to some focus logic changes with button-groups introduced in JDK-9.
(For example: 8074883?)
The top of the stack trace is:
java.lang.ClassCastException:
com.example.TristateCheckBox$TristateDecorator cannot be cast to
java.desktop/javax.swing.JToggleButton$ToggleButtonModel
at
java.desktop/javax.swing.LayoutFocusTraversalPolicy.accept(LayoutFocusTraversalPolicy.java:243)
at
java.desktop/javax.swing.SortingFocusTraversalPolicy.getComponentBefore(SortingFocusTraversalPolicy.java:435)
at
java.desktop/javax.swing.LayoutFocusTraversalPolicy.getComponentBefore(LayoutFocusTraversalPolicy.java:143)
at
java.desktop/java.awt.Component.transferFocusBackward(Component.java:8201)
at
java.desktop/java.awt.Component.transferFocusBackward(Component.java:8186)
at
java.desktop/java.awt.DefaultKeyboardFocusManager.focusPreviousComponent(DefaultKeyboardFocusManager.java:1388)
at
java.desktop/java.awt.DefaultKeyboardFocusManager.processKeyEvent(DefaultKeyboardFocusManager.java:1183)
at
java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4877)
at
java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2317)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4793)
...
The relevant code in LayoutFocusTraversalPolicy.accept is:
} else if (aComponent instanceof JComponent) {
if (SunToolkit.isInstanceOf(aComponent,
"javax.swing.JToggleButton")) {
JToggleButton.ToggleButtonModel model =
(JToggleButton.ToggleButtonModel) ((JToggleButton)
aComponent).getModel(); // <- Line 243
if (model != null) {
ButtonGroup group = model.getGroup(); // <- Only use of
'model'
For whatever reason (probably to do with the 3 states) the button model
is not a ToggleButtonModel, but derived from a DefaultButtonModel.
I think a simple solution is to (check? and) cast less specifically, to a
DefaultButtonModel instead. That looks to be sufficient here, and is also
what we find similar code in JToggleButton doing. For example in
JToggeleButton.getGroupSelection we see:
if (model instanceof DefaultButtonModel) {
ButtonGroup group = ((DefaultButtonModel) model).getGroup();
//...
I note while JToggleButton creates a ToggleButtonModel by default, it
does not enforce it via setModel().
More background: I think we found this code (over a decade ago) from here
http://www.javaspecialists.eu/archive/Issue082.html
(There are better solutions implementing this GUI control these days, but
I thought you might like to hear about it.)
Kind regards,
Luke Usherwood
More information about the swing-dev
mailing list