简体   繁体   English

Java JComboBox自定义渲染器和GTK

[英]Java JComboBox Custom Renderer and GTK

I have a list of Customer objects that I need to have selectable from a JComboBox. 我有一个需要从JComboBox中选择的Customer对象的列表。 From what I read I need to implement a custom renderer to have the fields I want displayed in the list. 从我阅读的内容中,我需要实现一个自定义渲染器,以使我想要的字段显示在列表中。

I want my JComboBox to have entries formatted as such: 我希望我的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    |
+----------------------------------------------+

I used this code: 我使用以下代码:

public class CustomerListCellRenderer extends DefaultListCellRenderer { 公共类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;
  }
}

This doesn't work correctly under Solaris / Unix / Linux using the system GTKLookAndFeel. 在使用系统GTKLookAndFeel的Solaris / Unix / Linux下,此方法无法正常工作。 The background of the input area of the combobox is not drawn and no border is drawn around it. 组合框的输入区域的背景未绘制,并且在其周围未绘制边框。 (See screenshot below). (请参见下面的屏幕截图)。 Is there another way to achieve this that will work correctly across the 3 major platforms (Win/Mac/GTK)? 还有另一种方法可以在3个主要平台(Win / Mac / GTK)上正常工作吗? Can I do a converter to do this and only manipulate the data not the GUI? 我可以做一个转换器来做到这一点,只操作数据而不是GUI吗?

My current workaround is to override toString() on my Customer object to display each record in the format I want, but looking for other ideas. 我当前的解决方法是重写Customer对象上的toString()以所需的格式显示每条记录,但是正在寻找其他想法。

替代文字

Nick 缺口

Same issue, I did this in order to customize it for showing icons: 同样的问题,我这样做是为了自定义它以显示图标:

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;
    }
}

Then assigned the renderer like this: 然后像这样分配渲染器:

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

This has worked out fine for me, so far. 到目前为止,这对我来说还算不错。

Try this: 尝试这个:

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);
  }
}

Also use a StringBuilder not a StringBuffer (this is a single threaded situation). 还请使用StringBuilder而不是StringBuffer(这是单线程情况)。

Also also it looks like you have cut and paste errors in the code for instance: 同样,例如,您似乎在代码中剪切并粘贴了错误:

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

Is checking the Company member and using the State member. 正在检查公司成员并使用州成员。

The DefaultListCellRenderer extends JLabel and looks like JLabel. DefaultListCellRenderer扩展了JLabel,看起来像JLabel。 If you have non-editable ComboBox then Renderer returned via getRenderer is used for painting drop down list area and also for "input" area. 如果您具有不可编辑的ComboBox,则通过getRenderer返回的Renderer将用于绘画下拉列表区域以及“输入”区域。 Try to play with border/foreground/background settings for ComboBox and renderer. 尝试使用ComboBox和渲染器的边框/前景/背景设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM