notice
participate

Don’t subclass DefautListCellRenderer for Swing’s Nimbus LAF

If you follow the common practice to subclass JLabel to add some formatting to your combobox you will be surprised that this will break the rendering of JComboBoxes in the Nimbus Look Ant Feel.

Examples of bad JLabel-based CellRenderer

Basically the nice glass like look of the combobox will disappear and the old flat look will be restored. This comes due to Nimbus using a custom CellRenderer:

javax.swing.plaf.synth.SynthComboBoxUI$SynthComboBoxRenderer

Fortunately this renderer is based on JLabel, too. This is why you can simply wrap the renderer and add some blinkenlights when needed:

Good example of renderer wrapping the original renderer

The implementation is straight forward:

[source:java]
public class InstanceWithIconCellRendererWrapper implements ListCellRenderer {
private final ListCellRenderer wrapped;
public InstanceWithIconCellRendererWrapper(ListCellRenderer listCellRenderer) {
this.wrapped = listCellRenderer;
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
String displayName = String.valueOf(value); // customize here
Component renderer = wrapped.getListCellRendererComponent(list, displayName, index, isSelected, cellHasFocus);
if (renderer instanceof JLabel) {
Icon icon = new ImageIcon(); // customize here
((JLabel) renderer).setIcon(icon);
}
return renderer;
}
}
[/source]

Use it as follows:


jComboBox.setRenderer(new InstanceWithIconCellRendererWrapper(jComboBox.getRenderer()));

Tags: , , , ,

research

{ 7 comments to read ... please submit one more! }

  1. Christopher Deckers

    We tried that code and it did not work. The reason is that the label appears opaque and does not show the effects painted by the combo.

    The root cause is located in NimbusComboBoxUI.paint(Graphics, JComponent):

    if(renderer instanceof JComponent) {
    ((JComponent)renderer).setOpaque(false);
    ((JComponent)renderer).setForeground(comboBox.getForeground());
    }

    The wrapper renderer is not a JComponent and so the label that is returned ends up opaque.

    This was tested with nimbus-2008_02_10.jar (latest weekly release) with Java 1.6.0_04.

    -Christopher

  2. Richard Bair

    Hey!

    I actually just fixed this bug and put it back this afternoon, it should show up in build 13 of Java 6 update 10, which I expect will be built and published in 3-4 weeks.

    @Christopher:Oh my! There’s a build system running amok. We haven’t actually done any work on the code in nimbus.dev.java.net for months and months. All our work recently has been for Java 6 update 10, which meant we had to do it in the Teamware workspaces within Sun. We were bummed about it, and want to somehow get the work we’ve done backported to nimbus.dev.java.net, but not sure technically how to go about it (assume we get the legal permissions worked out!). I’ll be sure to disable the weekly builds on hudson so we don’t keep creating nonsense weekly builds!

    The problem is that we’ve made upwards of 100 bugfixes in Synth and core Swing (including classes in the Basic LAF and some core Swing components and Borders). There is also one fix in java.awt.Color. Getting these somehow extracted into a Jar that could be used in nimbus.dev.java.net is going to be very hard. Even if we can do it, you would have to put the jar on the bootclasspath — something that would only really be legal to deploy under Java 7.

    Once we get Java 6 update 10 out the door, the plan is to patch Java 7 to include all the fixes for Nimbus. We’re doing it this way so that we don’t have to maintain two code branches simultaneously. Once it is in Java 7, you can do whatever the GPL allows :-).

  3. Christopher Deckers

    Richard,

    Thanks a lot for the clarifications! So this was a Nimbus version problem.
    As a side note, it is good to know that it does not solve the problem for users of the Nimbus external library.

  4. Off topic.
    I would like to know, how you did this nice screenshot, with irregular
    borders.

    Could not figure out, how to do it in Inkscape.

  5. Philipp Meier

    @jan The border was done with TechSmith’s SnagIt 7.0.3

{ 1 Pingbacks/Trackbacks }

  1. Swing links of the week: February 10, 2008
language
report

Bear
conditions