这里有一个公用设施接口和类,它可以很容易地得到一个组合框使用不同的标签。而不是创建一个替代品ListCellRenderer
(并且如果外观变化时冒着不适当的风险),它会使用默认的ListCellRenderer
(不管可能如何),但是将自己的字符串换成标签文本而不是那些在您的值对象中由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
实现自定义字符串,然后把它传递给原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)));
除了使用该制作自定义标签,如果你犯了一个ToString
实现创建基于系统区域设置字符串,就可以轻松国际化组合框,而不必改变你的价值对象中的任何东西。
这将工作,但会打破键盘导航,这是基于组合项目的toString。 – 2011-04-14 10:12:18
@JB Nizet:那么键盘导航是坏的;-)要走的方法是解决它而不是肮脏的黑客在toString – kleopatra 2011-04-15 12:46:18
@kleopatra:键盘导航代码深藏在javax.swing的一个不可访问的内部类中.plaf.basic.BasicComboUI,除了重新实现它并将其与渲染器耦合,并没有简单的方法来覆盖它。我同意你的原则,但这部分Swing的设计使得遵循这个原则非常痛苦。我认为一个通用的包装器对象重新定义toString并委托一切(equals,hashCode)包装对象是一个更好的解决方案。 – 2011-04-15 14:26:17