在上一节中我们利用ListCellRenderer interface在JList中加入Icon图像,而要在JComboBox中加入图像的方法也是一样的。我们必须实作ListCellRenderer interface所定义的方法getListCellRendererComponent.以下为这个方法的定义:
要先了解ListCellRenderer interface.我们必须由这个interface所定义的方法,将图像画在JComboBox中的每个项目。
ListCellRenderer interface里只定义了一个方法,那就是getListCellRendererComponent,不过这个参数有点多,我们把它列出来 看看:
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
上面这4个参数会在你设置JComboBox的绘图样式(setCellRenderer())时自动的由JComboBox组件提供,你只要关心怎么控制 getListCellRendererComponent()方法中的4个参数,而无需担心怎么参数传入。
要在JList中加入Icon图像的技巧就是将JComboBox中的每一个项目当作是JLabel,因为JLabel在使用文字与图像上非常的方便,要设置JComboBox的图像, 必须使用setRenderer(ListCellRenderer cellRenderer){注:我们在JList中画上图像是利用JList所提供的setCellRenderer(ListCellRenderer cellRenderer)方法,读者请小心}这个方法。我们来看下面这个范例,你就能明白了!
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class JComboBox4 { String[] s = { "西瓜", "苹果", "草莓", "香蕉", "葡萄" }; public JComboBox4() { JFrame f = new JFrame("JComboBox"); Container contentPane = f.getContentPane(); JComboBox combo = new JComboBox(s); combo.setBorder(BorderFactory.createTitledBorder("你最喜欢吃哪些水果?")); combo.setRenderer(new ACellRenderer()); combo.setMaximumRowCount(3); contentPane.add(combo); f.pack(); f.show(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } public static void main(String[] args) { new JComboBox4(); } } class ACellRenderer extends JLabel implements ListCellRenderer { ACellRenderer() { setOpaque(true); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (value != null) { setText(value.toString()); setIcon(new ImageIcon(".\\icons\\fruit" + (index + 1) + ".jpg")); } if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } return this; } }
各们读者在运行这个程序时会发现,即使JComboBox的选项中有图标,但在选后图标却不会显示在显示列中,原因是在上面程序中 我们以String Array s建立JComboBox:
JComboBox combo=new JComboBox(s);
String Array s里面放的只是水果名称,而并没有图标。当我们使用setRenderer()方法来JComboBox时,只会绘制JComboBox的 选项部份,而最后显示在JComboBox上的值还是以String Array s为依据。因此JComboBox显示列就只会显示文字而已,而不会显示出 图形。要解决这个问题,我们必须改变JComboBox所传入的参数内容,也就是将原来的String Array s更改成具有图形的数据项。在 此我们是利用JComboBox(Object[] items)来建立有图像的JComboBox,我们所传进去的Object Array不应该只有文字,而必须连图标一 并传入。我们修改上个范例修改如下:
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class JComboBox5 { String[] s = { "西瓜", "苹果", "草莓", "香蕉", "葡萄" }; ImageIcon[] icons = new ImageIcon[5];; public JComboBox5() { JFrame f = new JFrame("JComboBox"); Container contentPane = f.getContentPane(); ItemObj[] obj = new ItemObj[5]; for (int i = 0; i < 5; i++) { icons[i] = new ImageIcon(".\\icons\\fruit" + (i + 1) + ".jpg"); obj[i] = new ItemObj(s[i], icons[i]); } JComboBox combo = new JComboBox(obj);// 利用ItemObj Array // obj当作是JComboBox的参数传入,构造出JComboBox. combo.setBorder(BorderFactory.createTitledBorder("您喜欢吃哪些水果?")); combo.setRenderer(new ACellRenderer()); combo.setMaximumRowCount(3); contentPane.add(combo); f.pack(); f.show(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } public static void main(String args[]) { new JComboBox5(); } } class ItemObj { String name; ImageIcon icon; public ItemObj(String name, ImageIcon icon) { this.name = name; this.icon = icon; } } class ACellRenderer extends JLabel implements ListCellRenderer { ACellRenderer() { setOpaque(true); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (value != null) { setText(((ItemObj) value).name); setIcon(((ItemObj) value).icon); } if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } return this; } }
你可以发现,第一栏显示有图标显示出来了。当然你也可以利用ComboBoxModel方式来构造出有图标的JComboBox.我们来看下面 的例子:
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class JComboBox6 { String[] s = { "西瓜", "苹果", "草莓", "香蕉", "葡萄" }; ImageIcon[] icons = new ImageIcon[5]; public JComboBox6() { JFrame f = new JFrame("JComboBox"); Container contentPane = f.getContentPane(); for (int i = 0; i < 5; i++) { icons[i] = new ImageIcon(".\\icons\\fruit" + (i + 1) + ".jpg"); } ComboBoxModel mode = new AModel(); JComboBox combo = new JComboBox(mode); combo.setBorder(BorderFactory.createTitledBorder("您喜欢吃哪些水果?")); combo.setRenderer(new ACellRenderer()); combo.setMaximumRowCount(3); contentPane.add(combo); f.pack(); f.show(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } public static void main(String[] args) { new JComboBox6(); } /* * 我们用JComboBox(ComboBoxModel * aModel)来构造图标的JComboBox,因此我们在程序中编写一个继承DefaultComboBoxModel的 ComboBoxModel. */ class AModel extends DefaultComboBoxModel { AModel() { for (int i = 0; i < s.length; i++) { ItemObj obj = new ItemObj(s[i], icons[i]); addElement(obj); } } } } class ItemObj { String name; ImageIcon icon; public ItemObj(String name, ImageIcon icon) { this.name = name; this.icon = icon; } } class ACellRenderer extends JLabel implements ListCellRenderer { ACellRenderer() { setOpaque(true); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (value != null) { setText(((ItemObj) value).name); setIcon(((ItemObj) value).icon); } if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } return this; } }
我们用JComboBox(ComboBoxModel aModel)来构造图标的JComboBox,因此我们在程序中编写一个继承DefaultComboBoxModel的 ComboBoxModel.