1

I have a list of items in a JList for the user to select. Since it's a lot of items (say, cities in states), I want to divide the list into sections. The section headings should not be selectable, though. So for my cities/states example, this might look like this:

  • State 1
    • City 1
    • City 2
    • City 3
  • State 2
    • City 4
    • City 5
    • City 6

It wouldn't be so difficult to write this myself by embedding JLists in a custom ListCellRenderer, but I'm wondering if there already is a class like that out there.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
Robert Kosara
  • 583
  • 4
  • 10
  • The JIDE classes suggested by banjollity are great, but if somebody could suggest a pure open source component, I'd be interested in that, too (I forgot to say that this is for use in an open source project). Also, thanks Tom for correcting the class name to `ListCellRenderer`. – Robert Kosara May 17 '09 at 19:01

4 Answers4

4

There's a component available with JIDE that let's you do exactly this. It's called GroupList:

alt text
(source: jidesoft.com)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
banjollity
  • 4,490
  • 2
  • 29
  • 32
  • That's exactly it! Thanks! I had hoped for something open source (I forgot to say that this is for use in an open source project), but it looks like they have a good policy towards use in open source projects. If somebody can suggest an open source version, I would still appreciate that, though. – Robert Kosara May 17 '09 at 18:54
3

Maybe by using JTree ? What you describe is a Tree with two levels.

Valentin Rocher
  • 11,667
  • 45
  • 59
1

I see this question is already answered, but I noticed that Robert commented that he was hoping for an open source solution. I'd recommend using Glazed Lists' Separator list, the API for which you can be found here:

http://publicobject.com/glazedlists/glazedlists-1.8.0/api/ca/odell/glazedlists/SeparatorList.html

Here's some sample code that will produce a list of items grouped by their first letter:

alt text http://img300.imageshack.us/img300/8977/separatorlist.png

public class SeparatorListTest {

private static Comparator<String> createComparator() {
    return new Comparator<String>() {
        public int compare(String stringOne, String stringTwo) {
            return stringOne.substring(0,1).compareTo(stringTwo.substring(0,1));
        }
    };
}

private static ListCellRenderer createListCellRenderer() {
    return new DefaultListCellRenderer() {
        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

            if (value instanceof SeparatorList.Separator) {
                SeparatorList.Separator separator = (SeparatorList.Separator) value;
                label.setText(separator.getGroup().get(0).toString().substring(0,1));
                label.setFont(label.getFont().deriveFont(Font.BOLD));
                label.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
            } else {
                label.setFont(label.getFont().deriveFont(Font.PLAIN));
                label.setBorder(BorderFactory.createEmptyBorder(0,15,0,0));
            }

            return label;
        }
    };
}

public static void main(String[] args) {
    EventList<String> rawList = GlazedLists.eventListOf(
            "apple", "appricot", "acorn", "blueberry", "coconut", "chesnut", "grape");
    SeparatorList<String> separatorList = 
            new SeparatorList<String>(rawList, createComparator(), 1, 1000);

    JList list = new JList(new EventListModel<String>(separatorList));
    list.setCellRenderer(createListCellRenderer());
    JScrollPane scrollPane = new JScrollPane(list);
    scrollPane.setBorder(null);

    JFrame frame = new JFrame();
    frame.add(scrollPane, BorderLayout.CENTER);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(200,200);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

}

Ken
  • 206
  • 1
  • 10
  • Thanks, that looks really interesting. I ended up hacking up my own sectioned list in the end, because I didn't feel like including a large library just to get this one component. It works, but it's not perfect. GlazedLists looks like it might fit the bill really well. – Robert Kosara Aug 23 '09 at 00:10
  • hello, http://publicobject.com/glazedlists/glazedlists-1.8.0/api/ca/odell/glazedlists/SeparatorList.html is dead, any relocations? – Scaramouche Jan 30 '19 at 15:38
0

You could use what Apple calls a SourceList. You see them in action in iTunes and in Mac OS X's Finder. It is an elegant solution to the problem you describe.

A cross-platform, open source Java Swing component for doing this is here: http://explodingpixels.wordpress.com/2008/09/08/mac-widgets-for-java/

Steve McLeod
  • 51,737
  • 47
  • 128
  • 184
  • That's not really what I was looking for with my question here - but I have been looking for this kind of thing in Java for a while. Great stuff, thank you! – Robert Kosara May 18 '09 at 11:29