修改Swing中的ComboBox显示

Kon*_*lph 3 java swing jcombobox

我想以这样的方式修改(不可编辑的)显示JComboBox,使得当前选择的条目在编辑字段中具有一些额外的文本(但不是下拉列表).

像这样的东西:

小样

我的第一个猜测是覆盖ComboBox的模型,以便getSelectedItem返回修改显示的包装器对象:

petList.setModel(new ComboBoxModel() {
    private Object selected;

    public void setSelectedItem(Object anItem) {
        selected = anItem;
    }

    public Object getSelectedItem() {
        return new ActiveComboItem(selected);
    }

    // … The rest of the methods are straightforward.
});
Run Code Online (Sandbox Code Playgroud)

ActiveComboItem如下所示:

static class ActiveComboItem {
    private final Object item;

    public ActiveComboItem(Object item) { this.item = item; }

    @Override
    public boolean equals(Object other) {
        return item == null ? other == null : item.equals(other);
    }

    @Override
    public String toString() { return String.format("Animal: %s", item); }
}
Run Code Online (Sandbox Code Playgroud)

实际上,只要修改显示器就行了.不幸的是,当前条目不再标记为活动:

显示错误

(注意缺少的复选标记......或者操作系统显示选择.)

进一步检查表明,每次用户选择框中的新项目时getElementAt,-1都会使用索引调用模型的方法.这是使用经修改的选择的项目时的情况.当模型的getSelectedItem方法返回而不包装普通对象,则如在下拉框中选择的选择项目被标记,并且getElementAt具有一个参数调用-1.

显然,ComboBox将每个项目依次与当前活动的项目进行比较,但是,尽管我重写了该equals方法,但它找不到匹配项.我怎样才能解决这个问题?

(gist.github.com上针对此问题的完整,可编译的代码)

Rev*_*nzo 7

您需要提供自定义ListCellRenderer.以下作品:

    final JComboBox animalCombo = new JComboBox(animals);
    animalCombo.setRenderer(new DefaultListCellRenderer() {
        @Override
        public Component getListCellRendererComponent(final JList list, Object value, final int index, final boolean isSelected,
                final boolean cellHasFocus) {

            if (index == -1) {
                value = "Animal: " + value;
            }

            return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        }
    });
Run Code Online (Sandbox Code Playgroud)

如果其绘制的值是不在下拉列表中的值,则index为-1.

为了将来参考,当您只想更改Swing中显示内容的方式时,您永远不想修改支持模型.每个组件都有一个渲染器,通常你只需稍微修改一个默认的渲染器.

  • 除了我的previos注释:不是使用`super.getListCellRendererComponent`,而是在设置新渲染器之前存储以前使用的渲染器,并使用它的实现. (3认同)