Liste sectionnée en Java / swing?
Question
J'ai une liste d'éléments dans un JList
pour l'utilisateur de sélectionner. Comme il y a beaucoup d'articles (par exemple, les villes dans les Etats), je veux diviser la liste en sections. Les titres de section ne doivent pas être sélectionnées, cependant. Donc, pour mes villes / états exemple, cela pourrait ressembler à ceci:
- État 1
- Ville 1
- Ville 2
- Ville 3
- État 2
- Ville 4
- Ville 5
- Ville 6
Il ne serait pas si difficile de me écrire ce en intégrant JList
s dans un ListCellRenderer
personnalisé, mais je me demande s'il y a déjà une classe comme ça là-bas.
La solution
Je vois cette question est déjà répondu, mais je remarque que Robert a fait remarquer qu'il espérait une solution open source. Je vous recommande d'utiliser la liste de séparation des listes givrés, l'API pour lequel vous pouvez trouver ici:
http://publicobject.com /glazedlists/glazedlists-1.8.0/api/ca/odell/glazedlists/SeparatorList.html
Voici quelques exemples de code qui produira une liste d'articles regroupés par leur première lettre:
texte alt 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);
}
}
Autres conseils
Il y a un élément disponible avec JIDE qui vous permet de faire exactement cela. Il est appelé groupList:
Peut-être en utilisant DTree ? Ce que vous décrivez est un arbre avec deux niveaux.
Vous pouvez utiliser ce que Apple appelle un SourceList. Vous les voyez en action dans iTunes et le Finder de Mac OS X. Il est une solution élégante au problème que vous décrivez.
Un multi-plateforme, open source Java composant Swing pour ce faire est ici: http://explodingpixels.wordpress.com/2008/09 / 08 / mac-widgets-for-java /