【问题标题】:How do I define a general "POJO" ListCellRenderer for a JComboBox如何为 JComboBox 定义一个通用的“POJO”ListCellRenderer
【发布时间】:2015-09-08 23:07:45
【问题描述】:

如果我有一个 JComboBox,根据平台,它呈现单元格的方式会有所不同。我对它呈现字符串的方式很满意。我想要实现的是定义一个从 Pojos 映射到 Strings 的 ListCellRenderer,这样我就可以用任何对象填充 JComboBox,但显示的内容不是 toString 方法的内容。

我的最佳尝试(在运行时有效,但在编译时有警告)如下

import java.awt.Component;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

@SuppressWarnings("unchecked") 
public class PojoListRenderer<T> implements ListCellRenderer<Object>
{
    public static interface Extractor<T>
    {
         public String extract(T fromThis);  
    }

    private Extractor<T> myExtractor;
    private ListCellRenderer renderer;

    public PojoListRenderer(Extractor<T> extractor, ListCellRenderer parent)
    {
        myExtractor = extractor;
        renderer = parent;
    }
    public PojoListRenderer(Extractor<T> extractor)
    {
        this(extractor, new DefaultListCellRenderer());
    }

    @Override
    public Component getListCellRendererComponent(JList<?> list,
        Object value, int index, boolean isSelected, boolean cellHasFocus)
    {
        String s = myExtractor.extract((T)value);
        return renderer.getListCellRendererComponent(list, s, index, isSelected, cellHasFocus);
    }
}

然后可以按如下方式使用:

//Assume a class called Notification with methods name() and severity()
JComboBox myNotificationBox = ...;
myNotificationBox.setRenderer
(
     new PojoListRenderer<Notification>
     (
          (notification) -> notification.name() + "/" + notifiation.severity(),
          myNotification.getRenderer()
     )
);

这种方法很好,因为它意味着我可以获得 ComboBox 的默认 ListCellRenderer 的所有突出显示/选择/等,但我可以使用 ComboBox 作为域对象的规范持有者,并且仍然可以很好地显示它们。

缺点是上面显然不是类型安全的。

所以我的问题是:

  1. 这甚至是解决这个问题的理智方法吗(在我看来是这样)
  2. 我是否遗漏了 Swing 库中一些明显的东西(因为这似乎是非常明显的功能)
  3. 谁能建议如何在保留上述功能的同时消除编译器警告(并使上述类型安全)

【问题讨论】:

  • 虽然不是我的首选解决方案,但为什么不依赖toString 方法呢?您还可以定义自己的“Stringable”接口,您要使用的所有对象都将符合该接口。是不是疯了...是也不是...不是每个对象都希望以相同的方式呈现,例如,有些对象可能需要一些图形或其他状态信息,例如;)
  • 为了类型安全,从这个解决方案中删除泛型是可行的。不要使用T,只需使用Object。让提取器的实现执行类型安全所需的任何额外类型检查。老实说,这里并没有真正获得使用泛型的价值。

标签: java swing jcombobox pojo listcellrenderer


【解决方案1】:

这样我就可以用任何对象填充 JComboBox,但显示的内容不是 toString 方法的内容。

您可以查看Combo Box With Custom Renderer。这是我处理 POJO 的方法。它确实支持类型安全。

可能不完全是您想要的,但它也解决了您的自定义渲染器存在的问题,即会破坏默认的键选择功能。

【讨论】:

    猜你喜欢
    • 2011-08-19
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多