views:

122

answers:

2

Hopefully an easy question.

From the example on http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/uiswing/components/combobox.html on "Providing a Custom Renderer" section, I can make a JComboBox like

Picture 3 - Text 3
-------------------
Picture 1 - Text 1
Picture 2 - Text 2
Picture 3 - Text 3
Picture 4 - Text 4
Picture 5 - Text 5

Where Picture 3 - Text 3 is the currently selected item.

Is it possible to have a custom label? Such as

Text 3
-------------------
Picture 1 - Text 1
Picture 2 - Text 2
Picture 3 - Text 3
Picture 4 - Text 4
Picture 5 - Text 5

Where the image is not displayed when the combo box is in it's minimized state.

I've used a JButton/undecorated popup JFrame to emulate this before, but am wondering if it is possible to do with a pure JComboBox

Thanks

+1  A: 

There seem to be 3 function calls in the render related to displaying the image and text:

setIcon setText setFont

I have not compiled this example, but I would try and comment out setIcon(icon); from the function getListCellRendererComponent as this seems to display the image for the selected item.

If commenting it out breaks the code then I would try overriding with a blank image or something as a workaround.

kniemczak
close, by using `setIcon(null)` when `isSelected` is true. but then there is the undesired effect of the item having no image in the dropdown list when it is the active selection.
brian_d
I'm thinking that the minimized selected component cannot be completely independent of the list without setting JComboBox.setEditable(true). Or possibly setting up an action listener, changing the model first for the selected component (so that just the label is legal) and then updating the selection programmatically. This seems like a lot of work. Anyways, I'll give you the points kniemczak
brian_d
+2  A: 

Is it possible to have a custom label? Such as...

Yes. The same renderer is used to render the drop down list and the selected item in the combo box. The selected value is renderer when the "renderer index" is -1, so you can customize the rendering however you want. Something like:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;

public class ComboBoxItemIcon extends JFrame
{
    public ComboBoxItemIcon()
    {
        Vector model = new Vector();
        model.addElement( new Item(new ImageIcon("copy16.gif"), "copy" ) );
        model.addElement( new Item(new ImageIcon("add16.gif"), "add" ) );
        model.addElement( new Item(new ImageIcon("about16.gif"), "about" ) );

        JComboBox comboBox;

        comboBox = new JComboBox( model );
        comboBox.setRenderer( new ItemRenderer() );
        getContentPane().add(comboBox, BorderLayout.SOUTH );
    }

    class ItemRenderer extends BasicComboBoxRenderer
    {
        public Component getListCellRendererComponent(
            JList list, Object value, int index,
            boolean isSelected, boolean cellHasFocus)
        {
            super.getListCellRendererComponent(list, value, index,
                isSelected, cellHasFocus);

            Item item = (Item)value;

            if (index == -1)
            {
                setText( item.getText() );
                setIcon( null );
            }
            else
            {
                setText( item.getText() );
                setIcon( item.getIcon() );
            }

            return this;
        }
    }

    class Item
    {
        private Icon icon;
        private String text;

        public Item(Icon icon, String text)
        {
            this.icon = icon;
            this.text = text;
        }

        public Icon getIcon()
        {
            return icon;
        }

        public String getText()
        {
            return text;
        }
    }

    public static void main(String[] args)
    {
        JFrame frame = new ComboBoxItemIcon();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible( true );
     }

}
camickr
thanks for making me aware of the -1 value of index. works perfectly!
brian_d