Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to change the names *shown* for the items in a Java Swing jList?

I have a jList that uses DefaultListModel and I populate it with Objects I get from a list (context: the objects are a type of agent in ABM system).

Is it possible to change the name that is shown for the objects in the jList? I haven't been able to find anything on this...

like image 311
blackace Avatar asked Dec 23 '10 12:12

blackace


2 Answers

If the information you want to see (instead of whatever toString() spits out) is contained in the object itself, the most direct "Swing" way to accomplish this is through the use of a ListCellRenderer. Think of a ListCellRenderer (any CellRenderer really) as a rubber stamp used to draw each object in your list. The object is passed in, you setup the component, the component draws your object, and then moves on to the next object. The CellRenderer never has any state.

Consider this example:

// 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());
like image 113
basszero Avatar answered Nov 09 '22 00:11

basszero


I think the names are produced by the toString() methods of those objects. If you can change that, that's easiest. Otherwise, a quick solution would be to wrap some kind of holder object around each one that generates the view of the object for the JList and from which you can retrieve the contained object easily enough when you have to manipulate it for real.

To expand on the wrapper concept:

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;
    }
}
like image 41
Donal Fellows Avatar answered Nov 08 '22 23:11

Donal Fellows