JComboBox设置标签和值

是否有可能为JComboBox设置一个值和一个标签,这样我可以显示一个标签,但得到一个不同的值?

例如在JavaScript中,我可以这样做:

 document.getElementById("myselect").options[0].value //accesses value attribute of 1st option document.getElementById("myselect").options[0].text //accesses text of 1st option 

您可以将任何对象放在JComboBox中。 默认情况下,它使用对象的toString方法显示标签,使用键盘在combobox中导航。 所以,最好的方法可能是在组合中定义和使用适当的对象:

 public class ComboItem { private String value; private String label; public ComboItem(String value, String label) { this.value = value; this.label = label; } public String getValue() { return this.value; } public String getLabel() { return this.label; } @Override public String toString() { return label; } } 

这里有一个实用程序界面和类,可以很容易地让combobox使用不同的标签。 而不是创build一个replaceListCellRenderer (如果外观变化,冒着ListCellRenderer风险),它使用默认的ListCellRenderer (不pipe是什么),而是将自己的string换成标签文本而不是那些由值对象中的toString()定义。

 public interface ToString { public String toString(Object object); } public final class ToStringListCellRenderer implements ListCellRenderer { private final ListCellRenderer originalRenderer; private final ToString toString; public ToStringListCellRenderer(final ListCellRenderer originalRenderer, final ToString toString) { this.originalRenderer = originalRenderer; this.toString = toString; } public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean cellHasFocus) { return originalRenderer.getListCellRendererComponent(list, toString.toString(value), index, isSelected, cellHasFocus); } } 

正如你所看到的, ToStringListCellRendererToString实现中获得一个自定义string,然后将它传递给原来的ListCellRenderer而不是传入值对象本身。

要使用此代码,请执行以下操作:

 // Create your combo box as normal, passing in the array of values. final JComboBox combo = new JComboBox(values); final ToString toString = new ToString() { public String toString(final Object object) { final YourValue value = (YourValue) object; // Of course you'd make your own label text below. return "custom label text " + value.toString(); } }; combo.setRenderer(new ToStringListCellRenderer( combo.getRenderer(), toString))); 

除了使用它来创build自定义标签,如果您创build一个基于系统Locale创buildstring的ToString实现,则可以轻松实现combobox的国际化,而无需更改任何值对象中的任何内容。

请给我看一个完整的例子?

Enum实例特别方便,因为toString()返回声明中包含的这个枚举常量的名字。

在这里输入图像描述

 import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; /** @see http://stackoverflow.com/questions/5661556 */ public class ColorCombo extends JPanel { private Hue hue = Hue.values()[0]; public ColorCombo() { this.setPreferredSize(new Dimension(320, 240)); this.setBackground(hue.getColor()); final JComboBox colorBox = new JComboBox(); for (Hue h : Hue.values()) { colorBox.addItem(h); } colorBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Hue h = (Hue) colorBox.getSelectedItem(); ColorCombo.this.setBackground(h.getColor()); } }); this.add(colorBox); } private enum Hue { Cyan(Color.cyan), Magenta(Color.magenta), Yellow(Color.yellow), Red(Color.red), Green(Color.green), Blue(Color.blue); private final Color color; private Hue(Color color) { this.color = color; } public Color getColor() { return color; } } private static void display() { JFrame f = new JFrame("Color"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new ColorCombo()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { display(); } }); } } 

使用ListCellRenderer来实现你想要的。 创build一个扩展JLabel并实现ListCellRenderer 。 使用setRenderer()方法将该类设置为JComboBox的渲染器。 现在,当你从你的jcombobox访问值时,它将是jlabeltypes的。