I am making a font chooser using JComboBox
and a custom ListCellRenderer
. I want
the JComboBox
to display all available fonts, with each font name displayed in its own font. I am currently using around 500 fonts.
An example of a ListCellRenerer
that provides this functionality:
private class ComboBoxRenderer extends JLabel implements ListCellRenderer {
private JLabel label = new JLabel("Test");
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
Font tempFont = label.getFont();
setFont(new Font((String) value, tempFont.getStyle(),
tempFont.getSize()));
setText((String) value);
return this;
}
}
The problem is that, when using this renderer, the JComboBox
becomes unresponsive during program execution. The first time one clicks on the combobox to reveal the list, it takes a couple of seconds for the list to load. The second time one clicks, the list is instantly displayed.
If one comments the line
setFont(new Font((String) value, tempFont.getStyle(),tempFont.getSize()));
, the combobox works just fine.
How can one prevent this unresponsiveness?
@kleopatra than you for notice me but
setPrototypeDisplayValue
look like as lazy choise, my amedmentWhat happens is that the combo's internals try to find the preferred size dynamically. For doing so, it loops through all items in the list, feeds the renderer with the items to measure the rendering component's preferred size.
You can prevent that by setting a prototypeValue for measuring, then the size is measured once using that prototype
Edit: as @Boro detected, that's not enough - it sets the prototype for the comboBox itself only, not for the list in the popup (as it should, how crazily buggy can that ... possibly be). To hack around, we have to manually set it, here's a code snippet to play with
Custom ListCellRenderer (slightly changed, to expect items of type Font)