【发布时间】:2013-09-19 20:23:51
【问题描述】:
要为任意对象自定义JComboBox 中显示的文本,我知道正确的方法是创建自定义ListCellRenderer。但是,我不确定如何以模仿普通组合框的外观和感觉的方式执行此操作。
考虑下面的 SSCCE。它可以工作,但它有一条令人不快的行,我将一个组件转换为JLabel。这是我不应该拥有也不应该依赖的魔法知识。有没有其他方法可以在不做这么丑陋的事情的情况下达到同样的效果?
public class ListCellRendererExample {
private final JFrame frame;
public ListCellRendererExample() {
frame = new JFrame();
JComboBox<SomeObject> combobox = new JComboBox<>(
new SomeObject[] { new SomeObject("a") });
ListCellRenderer<? super SomeObject> cellRenderer = combobox.getRenderer();
combobox.setRenderer(new CustomRenderer(cellRenderer));
frame.add(combobox);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new ListCellRendererExample();
}
private class CustomRenderer implements ListCellRenderer<SomeObject> {
private final ListCellRenderer<? super SomeObject> defaultRenderer;
public CustomRenderer(ListCellRenderer<? super SomeObject> cellRenderer) {
this.defaultRenderer = cellRenderer;
}
@Override
public Component getListCellRendererComponent(
JList<? extends SomeObject> list, SomeObject value, int index,
boolean isSelected, boolean cellHasFocus) {
Component result = defaultRenderer.getListCellRendererComponent(list,
value, index, isSelected, cellHasFocus);
((JLabel) result).setText(value.value); // <--- URGH!
return result;
}
}
private static class SomeObject {
private final String value;
public SomeObject(String nombre) {
this.value = nombre;
}
}
}
【问题讨论】:
-
演员表(最佳实践)以
instanceof检查为前缀。 -
I know the correct approach is to create a custom ListCellRenderer.- 也许,但每个人都忘记告诉你,这种方法破坏了组合框的默认功能。高级 GUI 用户将使用键盘,而不是鼠标。当您使用自定义渲染器时,您不能再通过键入键来选择组合框中的项目,因为 KeySelectionManager 依赖于模型中 Object 的 toString() 实现。 -
@camickr 迷人 - 我不知道!
-
@AndrewThompson 你说的很对——为了简洁而省略了。
标签: java swing jcombobox tostring listcellrenderer