简体   繁体   中英

How to add icon near arrow icon for JComboBox

I would like to create JComboBox control similar with the URL textbox of Firefox. Does anyone know how to customize the textfield of the JComboBox . I want to add some icons on the ALIGN.HORIZONTAL_RIGHT near the arrow button of the JComboBox


Thanks for your very detail explanation. Actually I will combine DefaultListCellRenderer and add the icon to the combo box like following code

import java.awt.Dimension;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Main extends JFrame {
    public Main() {
        // Create icon "C"
        JButton jb = new JButton("C");
        jb.setMargin(new Insets(0, 0, 0, 0));
        jb.setBounds(245, 2, 18, 18);

        // Create combo box
        String[] languages = new String[]{"Java", "C#", "PHP"};
        JComboBox jc = new JComboBox(languages);
        // jc.setEditable(true);
        jc.add(jb);

        getContentPane().add(jc);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(new Dimension(300, 58));
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        final Main main = new Main();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                main.setVisible(true);
            }
        });
    }
}

But when I put jc.setEditable(true) ; the combo editor hided my icon. I'm thinking another way to simulate Firefox awesome bar. Do you have any idea for this?

To change how a component renders, you generally work with what are called Renderer s.

For combobox, look at how to create a custom combobox renderer . Just a quick glance, but for your case, a simple configuration of DefaultListCellRenderer may be enough, since you can set the JLabel properties to position the text to the image. If not, just extend from it.

Remember also that you have to set a model that includes the icon so that the combobox renderer can get it - might want to do a custom ComboBoxModel too, depending on your data object.

Here is completed example that demonstrate it:

package com.demo.combo.icon;



import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.Map;

import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;


public class ShowConboWithIcons extends JFrame {

private static final long serialVersionUID = 1L;

private static final ImageIcon INFO_ICON  = new ImageIcon("info.png");
private static final ImageIcon NONE_ICON  = new ImageIcon("none.png");
public final String NONE_STR = "None";
private final String INFO_STR = "Info";

private JComboBox comboBox;
private JPanel    topPanel;

private String[] str_arr = null; 


public ShowConboWithIcons(String[] str_arr) {
    this.str_arr = str_arr;     
}


public void createGUI(){

    setMinimumSize(new Dimension(100,100));
    setTitle("Demo");
    setLocation(200, 200);

    topPanel = new JPanel();
    getContentPane().add(topPanel, BorderLayout.CENTER);

    Map<Object, Icon> icons = new HashMap<Object, Icon>(); 

    icons.put(NONE_STR, NONE_ICON); 
    icons.put(INFO_STR, INFO_ICON); 

    comboBox = new JComboBox();
    comboBox.setRenderer(new IconListRenderer(icons));
    comboBox.addItem("None");

    for(String val : str_arr){
        comboBox.addItem(val);
    }

    topPanel.add(comboBox);

    super.addWindowListener(new WindowAdapter() {           
        public void windowClosing(WindowEvent e) {              
            dispose();          
        }           
    }); 
}

public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {

    UIManager.setLookAndFeel( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );   

    String[] str_arr = {"A", "B", "C", "D", "E"};

    ShowConboWithIcons T = new ShowConboWithIcons(str_arr);
    T.createGUI();
    T.setVisible(true);        
}


class IconListRenderer extends DefaultListCellRenderer{ 
    private static final long serialVersionUID = 1L;
    private Map<Object, Icon> icons = null; 

    public IconListRenderer(Map<Object, Icon> icons){ 
        this.icons = icons; 
    } 

    @Override
    public Component getListCellRendererComponent(JList list, Object value, int index,boolean isSelected, boolean cellHasFocus)
    { 
        JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 

        // Get icon to use for the list item value 
        Icon icon = icons.get(value); 

        if(!value.toString().equals(NONE_STR)){
            icon = icons.get(INFO_STR);
        }

        // Set icon to display for value 
        label.setIcon(icon); 
        return label; 
    } 
}
}

Preview:

组合默认模式:

组合选择项:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM