1

This might be a dup - I can't find it exactly though - I'm basically simply trying to customize a JComboBox display by providing my own ListCellRenderer:

targetCombo = new JComboBox();
targetCombo .setRenderer(new BasicComboBoxRenderer(){
    public Component getListCellRendererComponent(JList list, Object value, int index,              boolean isSelected, boolean cellHasFocus){
        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        if (value != null){
            MyObj myObj = (myObj)value;
            setText(myObj.getName());
        }
        return this;
    }
});

The component properly displays the name when I expand the JComboBox list. However, on item selection, the display reverts to the toString() value of myObj.

Am I missing something?

Dan
  • 1,763
  • 4
  • 26
  • 40
  • Let's start with the fact you shouldn't be using components from the look and feel packages (`BasicComboBoxRenderer`) and probably should be using a `DefaultListCellRenderer` instead – MadProgrammer Jan 21 '13 at 22:14

2 Answers2

4

Replace the use of BasicComboBoxRenderer with DefaultListCellRenderer

public class TestComboBox04 {

  public static void main(String[] args) {
    new TestComboBox04();
  }

  public TestComboBox04() {
    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception ex) {
        }

        JComboBox targetCombo = new JComboBox();
        targetCombo.setRenderer(new DefaultListCellRenderer() {
          public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if (value != null) {
              MyObj myObj = (MyObj) value;
              setText(myObj.getName());
            }
            return this;
          }
        });
        targetCombo.addItem(new MyObj("A"));
        targetCombo.addItem(new MyObj("B"));
        targetCombo.addItem(new MyObj("C"));
        targetCombo.addItem(new MyObj("D"));

        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new GridBagLayout());
        frame.add(targetCombo);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

      }
    });
  }

  public class MyObj {

    private String name;

    public MyObj(String name) {
      this.name = name;
    }

    public String getName() {
      return name;
    }

  }

}

You should never have a need to use the components from the look and feel packages, unless you are planning on creating your own look and feel.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • agreed - i grabbed code from a sample and didn't bother to look at that :) – Dan Jan 21 '13 at 22:18
  • actually, I'm having the same problem with this code. The display is fine when the combobox is expanded. As soon as I choose an item - reverts. Could it be another setting? – Dan Jan 21 '13 at 22:21
  • This example works for me fine. Can you provide a running example that demonstrates the problem? – MadProgrammer Jan 21 '13 at 22:45
  • your example works for me too. It's weird. My JComboBox is declared exactly like yours. I add the items to the JComboBox model instead of the component directly. Also, my object class is a Scala class. I can't think how would that be a problem though. – Dan Jan 22 '13 at 00:23
  • Wow. It was a buried setEditable(false) on the combobox. I didn't realize it was causing that – Dan Jan 22 '13 at 00:40
  • @MadProgrammer http://stackoverflow.com/questions/2812850/how-to-use-map-element-as-text-of-a-jcombobox camickr answer uses basicComboBoxRender is it bad? – nachokk Aug 03 '13 at 14:56
  • Generally, its not recommended. The DefaultCellRenderer (for example) uses the installed look and feel, meaning the renderer conforms to the style of the application – MadProgrammer Aug 03 '13 at 20:58
0

...the display reverts to the toString() value of myObj.

unless you need toString() for something specific, override it to return 'name',

then you don't need the renderer - the comboBox will display the toString() value

Michael Dunn
  • 818
  • 5
  • 3
  • no - overriding toString is _not_ what you should do: custom rendering is the job of a custom .. renderer :-) – kleopatra Jan 22 '13 at 10:23