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); } }
正如你所看到的, ToStringListCellRenderer
从ToString
实现中获得一个自定义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的。