Java JComboBox自定义渲染器和GTK

问题描述 投票:0回答:3

我有一个Customer对象列表,我需要从JComboBox中选择。根据我的阅读,我需要实现一个自定义渲染器,以便在列表中显示我想要的字段。

我希望我的JComboBox具有如下格式的条目:

+----------------------------------------------+
|  Customer Name - Contact - City, State    V  |
+==============================================+
|  Customer #2 Name - Contact - City, State    |
|  Customer #3 Name - Contact - City, State    |
|  Customer #4 Name - Contact - City, State    |
|  Customer #5 Name - Contact - City, State    |
+----------------------------------------------+

我用过这段代码:

公共类CustomerListCellRenderer扩展DefaultListCellRenderer {

@Override
public Component getListCellRendererComponent(
        JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    if (value instanceof Customer) {
        Customer c = (Customer) value;

        StringBuffer sb = new StringBuffer();
        if (c.getCompany() != null && c.getCompany().length() > 0) {
            sb.append(c.getCompany());
        }
        sb.append(" - ");
        if (c.getCompany() != null && c.getCompany().length() > 0) {
            sb.append(c.getContact());
        }
        sb.append(" - ");
        if (c.getCompany() != null && c.getCompany().length() > 0) {
            sb.append(c.getCity());
            sb.append(", ");
        }            
        if (c.getCompany() != null && c.getCompany().length() > 0) {
            sb.append(c.getState());
        }

        setText(sb.toString());
    }
    return this;
  }
}

这在使用系统GTKLookAndFeel的Solaris / Unix / Linux下无法正常工作。未绘制组合框输入区域的背景,并且不会在其周围绘制边框。 (见下面的截图)。还有另一种方法可以在3个主要平台(Win / Mac / GTK)上正常工作吗?我可以做一个转换器来做这个,只操纵数据而不是GUI吗?

我目前的解决方法是覆盖我的Customer对象上的toString(),以我想要的格式显示每条记录,但寻找其他想法。

alt text

缺口

java linux swing gtk jcombobox
3个回答
2
投票

同样的问题,我这样做是为了自定义它来显示图标:

private static class CustomComboBoxRenderer extends DefaultListCellRenderer
{
    private final ListCellRenderer backend;

    public CustomComboBoxRenderer(ListCellRenderer backend)
    {
        this.backend = backend;
    }

    @Override
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
    {
        Component component = backend.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        if(component instanceof JLabel == false)
            component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        JLabel label = (JLabel)component;
        label.setIcon(Icons.COMPONENT);
        return label;
    }
}

然后像这样分配渲染器:

comboBox.setRenderer(new CustomComboBoxRenderer(comboBox.getRenderer()));

到目前为止,这对我来说很好。


1
投票

试试这个:

public Component getListCellRendererComponent(
        JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    if (value instanceof Customer) {
        Customer c = (Customer) value;

        StringBuffer sb = new StringBuffer();
        if (c.getCompany() != null && c.getCompany().length() > 0) {
            sb.append(c.getCompany());
        }
        sb.append(" - ");
        if (c.getCompany() != null && c.getCompany().length() > 0) {
            sb.append(c.getContact());
        }
        sb.append(" - ");
        if (c.getCompany() != null && c.getCompany().length() > 0) {
            sb.append(c.getCity());
            sb.append(", ");
        }            
        if (c.getCompany() != null && c.getCompany().length() > 0) {
            sb.append(c.getState());
        }

        value = sb.toString();
    } 
    return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
  }
}

还使用StringBuilder而不是StringBuffer(这是单线程情况)。

此外,您还可以在代码中剪切和粘贴错误,例如:

        if (c.getCompany() != null && c.getCompany().length() > 0) {
            sb.append(c.getState());
        }

正在检查公司成员并使用州成员。


0
投票

DefaultListCellRenderer扩展了JLabel,看起来像JLabel。如果您有不可编辑的ComboBox,则通过getRenderer返回的Renderer用于绘制下拉列表区域以及“输入”区域。尝试使用ComboBox和渲染器的边框/前景/背景设置。

© www.soinside.com 2019 - 2024. All rights reserved.