-
Bug
-
Resolution: Incomplete
-
P4
-
None
-
6
-
x86
-
linux
Consider a JComboBox displaying a model known to always consist of a certain element type. (There is no support for a parameter type on ComboBoxModel and related API classes, but you can usually work as if they were generic.) If toString() on this element type does not produce a human-readable display value, you may wish to set a custom list cell renderer. If this merely produces a string from the model object, you would most simply extend DefaultListCellRenderer:
class NotStringListCellRenderer extends DefaultListCellRenderer/*<NotString>*/ {
public @Override Component getListCellRendererComponent(JList list, /*NotString*/Object value, int index, boolean isSelected, boolean cellHasFocus) {
String text;
if (value == null) {
text = null;
} else {
text = ((NotString) value).getDisplayLabel();
}
return super.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus);
}
}
NotString[] stuff = ...;
ComboBoxModel/*<NotString>*/ model = new DefaultComboBoxModel/*<NotString>*/(stuff);
JComboBox/*<NotString>*/ combo = new JComboBox/*<NotString>*/();
combo.setModel(model);
combo.setListCellRenderer(new NotStringListCellRenderer());
And in JDK 5-compatible code - including that using org.jdesktop.layout.GroupLayout from https://swing-layout.dev.java.net/ - this works fine.
If you switch the form to use javax.swing.GroupLayout (this is a matter of changing a single option in the NetBeans GUI builder), and the combo box model has at least one element (stuff.length > 0 in the above), it also works fine. But if you try to display the combo box with an empty model, suddenly you get a CCE from the renderer, because value is (String) " ". This is rather unexpected, and means that an upgrade to the JDK 6 standard version of GroupLayout can introduce regressions. The regression is not always apparent - you might not think to test an empty model.
The problem is BasicComboBoxUI.getBaseline (called by javax.swing.GroupLayout), which is looking for sample text and assumes that any renderer is capable of rendering a String value. This assumption breaks the programmer's expectation that the renderer is associated with a specific model type.
class NotStringListCellRenderer extends DefaultListCellRenderer/*<NotString>*/ {
public @Override Component getListCellRendererComponent(JList list, /*NotString*/Object value, int index, boolean isSelected, boolean cellHasFocus) {
String text;
if (value == null) {
text = null;
} else {
text = ((NotString) value).getDisplayLabel();
}
return super.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus);
}
}
NotString[] stuff = ...;
ComboBoxModel/*<NotString>*/ model = new DefaultComboBoxModel/*<NotString>*/(stuff);
JComboBox/*<NotString>*/ combo = new JComboBox/*<NotString>*/();
combo.setModel(model);
combo.setListCellRenderer(new NotStringListCellRenderer());
And in JDK 5-compatible code - including that using org.jdesktop.layout.GroupLayout from https://swing-layout.dev.java.net/ - this works fine.
If you switch the form to use javax.swing.GroupLayout (this is a matter of changing a single option in the NetBeans GUI builder), and the combo box model has at least one element (stuff.length > 0 in the above), it also works fine. But if you try to display the combo box with an empty model, suddenly you get a CCE from the renderer, because value is (String) " ". This is rather unexpected, and means that an upgrade to the JDK 6 standard version of GroupLayout can introduce regressions. The regression is not always apparent - you might not think to test an empty model.
The problem is BasicComboBoxUI.getBaseline (called by javax.swing.GroupLayout), which is looking for sample text and assumes that any renderer is capable of rendering a String value. This assumption breaks the programmer's expectation that the renderer is associated with a specific model type.