问题 是否可以更改Java Swing jList中项目的名称* *?


我有一个使用DefaultListModel的jList,我使用从列表中获取的对象填充它(上下文:对象是ABM系统中的一种代理)。

是否可以更改名称 显示 对于jList中的对象?我一直无法找到任何东西......


8884
2017-12-23 12:08


起源



答案:


如果要查看的信息(而不是toString()spits out)包含在对象本身中,那么实现这一目标的最直接的“Swing”方式是通过使用 ListCellRenderer。可以将ListCellRenderer(任何CellRenderer)视为用于绘制列表中每个对象的橡皮图章。传入对象,设置组件,组件绘制对象,然后移动到下一个对象。 CellRenderer永远不会有任何状态。

考虑这个例子:

// Extend DefaultListCellRenderer, takes care of most of the work for you
public class ExampleListCellRenderer extends DefaultListCellRenderer
{
    public Component getListCellRendererComponent(
        JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
    {
        // I know DefaultListCellRenderer always returns a JLabel
        // super setups up all the defaults
        JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelect, cellHasFocus);

        // "value" is whatever object you put into the list, you can use it however you want here

        // I'm going to prefix the label text to demonstrate the point

       label.setText("PRE:" + label.getText());

       return label;

    }
}

// Some time later...

JList list = new JList();
list.setCellRenderer(new ExampleListCellRenderer());

10
2017-12-23 12:34



basszero感谢您对listcellrenderers的详细和翔实的解释以及您提供的示例。我学到了很多 :) - blackace
@blackace - 选中答案旁边的框以接受它并给@basszero他/她应得的分数。 - I82Much
@ i82我收到的这两个答案都是正确的。我不能以任何方式表明这一点? - blackace
不幸的是,除了赞成两者之外。一个upvote给出了回答者的分数,但没有你接受答案的那么多。 - I82Much


答案:


如果要查看的信息(而不是toString()spits out)包含在对象本身中,那么实现这一目标的最直接的“Swing”方式是通过使用 ListCellRenderer。可以将ListCellRenderer(任何CellRenderer)视为用于绘制列表中每个对象的橡皮图章。传入对象,设置组件,组件绘制对象,然后移动到下一个对象。 CellRenderer永远不会有任何状态。

考虑这个例子:

// Extend DefaultListCellRenderer, takes care of most of the work for you
public class ExampleListCellRenderer extends DefaultListCellRenderer
{
    public Component getListCellRendererComponent(
        JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
    {
        // I know DefaultListCellRenderer always returns a JLabel
        // super setups up all the defaults
        JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelect, cellHasFocus);

        // "value" is whatever object you put into the list, you can use it however you want here

        // I'm going to prefix the label text to demonstrate the point

       label.setText("PRE:" + label.getText());

       return label;

    }
}

// Some time later...

JList list = new JList();
list.setCellRenderer(new ExampleListCellRenderer());

10
2017-12-23 12:34



basszero感谢您对listcellrenderers的详细和翔实的解释以及您提供的示例。我学到了很多 :) - blackace
@blackace - 选中答案旁边的框以接受它并给@basszero他/她应得的分数。 - I82Much
@ i82我收到的这两个答案都是正确的。我不能以任何方式表明这一点? - blackace
不幸的是,除了赞成两者之外。一个upvote给出了回答者的分数,但没有你接受答案的那么多。 - I82Much


我认为名字是由 toString() 这些对象的方法。如果你可以改变它,那是最简单的。否则,一个快速的解决方案是在每个生成JList的对象视图周围包装某种持有者对象,并且当您必须真实地操作它时,您可以从中轻松地检索所包含的对象。

要扩展包装概念:

class FooBarAgentHolder {
    // Simple javabean stuff
    private FooBarAgent agent;
    public FooBarAgentHolder(FooBarAgent agent) { this.agent = agent; }
    public FooBarAgent getAgent() { return agent; }

    // Produce the name for human consumption
    public String toString() {
        return agent.getDescriptiveName(); // Or whatever...
    }

    // Convenience conversion function
    public static DefaultListModel makeListModel(List<FooBarAgent> list) {
        DefaultListModel result = new DefaultListModel();
        for (FooBarAgent agent: list)
            result.addElement(new FooBarAgentHolder(agent));
        return result;
    }
}

4
2017-12-23 12:11



感谢你的及时回复。我不想更改原始对象名称,所以我想这个选项是不可能的,除非有一些我不知道的技巧。关于你的第二个建议。你能不能扩展它?我对此完全天真。一个例子非常有用...... - blackace
@blackace:试试吧。它应该是足够简单的代码,你可以看到它显然是正确的。适应您的实际代码(例如,更改 FooBarAgent 并做正确的事 toString)。 - Donal Fellows
非常感谢!现在很清楚:-) - blackace