【问题标题】:Java JComboBox Custom Renderer and GTKJava JComboBox 自定义渲染器和 GTK
【发布时间】:2009-06-25 18:30:02
【问题描述】:

我有一个 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() 以我想要的格式显示每条记录,但正在寻找其他想法。

尼克

【问题讨论】:

  • 我看不出你为什么需要为该示例使用自定义渲染器。
  • @ammoQ :您需要它,因为您想将客户存储到您的 ComboBoxModel 中,而不是字符串。所以,当你这样做时:getSelectedItem(),你得到一个客户,而不是一个字符串。

标签: java linux swing gtk jcombobox


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    试试这个:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-09
        • 1970-01-01
        • 1970-01-01
        • 2017-11-24
        • 2013-09-25
        • 2011-07-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多