Search code examples
javaswingjcomboboxlistcellrenderer

Difference between these two DefaultListCellRenderer?


I got this class

public class FooBar {
    private String foo, bar;
    public FooBar(String f, String b) { this.foo = f; this.bar = b; }
    public String getFoo() { return this.foo; }
}

I want to put some FooBar objects in a JComboBox, which will display value of foo var. In order to do that without overriding toString(), i have to use a custom renderer. What is the difference between these two DefaultListCellRenderer ?

public class MyCellRenderer1 extends DefaultListCellRenderer {
    @Override
    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus)
    {
        if(value != null && (value instanceof FooBar))
            setText(((FooBar) value).getFoo());
        else
            setText(value.toString());

        return this;
    }
}

public class MyCellRenderer2 extends DefaultListCellRenderer {
    @Override
     public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus)
    {
         Object item = value;

        if(item != null && item instanceof FooBar))
            item = ((FooBar)item).getFoo();     

        return super.getListCellRendererComponent(list, item,
                index, isSelected, cellHasFocus);
    }
}

Solution

  • The difference is ... well... the code. And what they do. But seriously, the main practical difference is that the second one calls the super method. This method will perform basic setup operations, like setting the border and background color based on the isSelected flag etc.

    I'd usually always recommend to call the super method to perform this setup and ensure a consistent look and feel of the list.

    However, the usage pattern in the second case may be a bit confusing, due to item refering either to the object or to its string representation. I'd personally prefer to write it like this:

    public class MyCellRenderer extends DefaultListCellRenderer {
        @Override
         public Component getListCellRendererComponent(JList list, Object item,
             int index, boolean isSelected, boolean cellHasFocus)
         {
             super.getListCellRendererComponent(list, item,
                 index, isSelected, cellHasFocus);
             if (item != null && (item instanceof FooBar))
             {
                 FooBar fooBar = (FooBar)item;
                 String foo = fooBar.getFoo();
                 setText(foo);
             }
             return this;
        }
    }
    

    But this may just be a matter of preferences.