默认的JComboBox无法在每个条目上显示图标、缩进等样式。但是Swing的MVC设计结构为各种组件提供了无与伦比的可扩展性。为了实现这一点,我们可以创建一个新的Renderer来负责每个条目的绘制。 
首先我们新写一个类ImagedComboBoxItem,它封装了一个下拉条目的信息,包括图标、文字、缩进等: 
class ImagedComboBoxItem {     private Icon icon = null;     private String text = null;     private int indent = 0; 
    ImagedComboBoxItem(String text, Icon icon, int indent) {         this.text = text;         this.icon = icon;         this.indent = indent;     } 
    public String getText() {         return text;     } 
    public Icon getIcon() {         return icon;     } 
    public int getIndent() {         return indent;     } } 
然后新建JImagedComboBox类并从JComboBox继承。在构造函数中,新建一个DefaultListCellRenderer作为新的Renderer,并覆盖其getListCellRendererComponent方法。在新的getListCellRendererComponent方法中,首先依旧调用父对象的该方法,以便完成普通条目的绘制;然后判断条目是否是ImagedComboBoxItem实例。如果是,则显示ImagedComboBoxItem的文字、图标,并显示缩进。为了更方便的显示左侧缩进,我们直接创建一个EmptyBorder并设置左侧缩进数量,并设置到DefaultListCellRenderer中。DefaultListCellRenderer从JLabel继承而来,所以可直接接受各种Border。这里我们以每个缩进10象素为例。 
好了,以下是完整代码: 
import java.util.*; 
import java.awt.*; import javax.swing.*; 
public class JImagedComboBox extends JComboBox {     public JImagedComboBox(Vector values) {         super(values);         ListCellRenderer renderer = new DefaultListCellRenderer() {             public Component getListCellRendererComponent(                 JList list,                 Object value,                 int index,                 boolean isSelected,                 boolean cellHasFocus) {                 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);                 if (value instanceof ImagedComboBoxItem) {                     ImagedComboBoxItem item = (ImagedComboBoxItem) value;                     this.setText(item.getText());                     this.setIcon(item.getIcon());                     if (isPopupVisible()) {                         int offset = 10 * item.getIndent();                         this.setBorder(BorderFactory.createEmptyBorder(0, offset, 0, 0));                     }                 }                 return this;             }         };         this.setRenderer(renderer);     } 
    public static void main(String[] args) {         JFrame frame = new JFrame();         frame.setSize(400, 400);         Vector values = new Vector();         Icon openIcon = new ImageIcon(JImagedComboBox.class.getResource("Open16.gif"));         Icon newIcon = new ImageIcon(JImagedComboBox.class.getResource("New16.gif"));         for (int i = 0; i < 5; i++) {             values.addElement(new ImagedComboBoxItem("Directory " + i, openIcon, i));         }         for (int i = 0; i < 5; i++) {             values.addElement(new ImagedComboBoxItem("Image Item " + i, newIcon, 5));         }         JImagedComboBox comboBox = new JImagedComboBox(values);         frame.getContentPane().add(comboBox, BorderLayout.NORTH);         frame.show();     } } 
class ImagedComboBoxItem {     private Icon icon = null;     private String text = null;     private int indent = 0; 
    ImagedComboBoxItem(String text, Icon icon, int indent) {         this.text = text;         this.icon = icon;         this.indent = indent;     } 
    public String getText() {         return text;     } 
    public Icon getIcon() {         return icon;     } 
    public int getIndent() {         return indent;     } } 
其中,两个图标在这里 :Open16.gif,New16.gif  
 
  |