Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting JList Using Collections's Sort Method

I would like to sort my list of users in an IRC channellist, which is stored as a JList, using Collections's method sort. Code below accomplishes this, to some extent:

users is the JList that contains the users.

userList is the intermediary data structure (LinkedList) that is used for sorting the list with Collections.

// Iterate through the JList and add the users to a LinkedList of strings.
for(Object userName : users.toArray())
    userList.add(userName.toString());

// Sort
Collections.sort(userList);              

// Clear the user list (removes all users).
users.clear();                            

// Put the sorted userList in users again.
while(iterator.hasNext() && i < userList.size()) 
     users.addElement(userList(get(i++));

The problem is that an IRC channelList has three user groups: OPs, voiced users, and regular users, and they need to be organized in a hierarchy. Of course, the sort method does not take this into consideration. Also, the sort method differentiates between small and capital letters, and this is unwanted.

Questions summarized:

How to handle sorting the different users groups; can I specify it with the Collections's sorting method somehow so that it conforms to the hierarchy?

How to stop the sorting method from differentiating between lowercase and capital letters?

My proposed solutions:

  • (Inefficient!) Create three lists, and add the respective usergroups to them, sort, and then add them to a list in convenient order.
  • convert usernames to lowercase (unfortunate).

Any suggestions? Thanks.

like image 625
dueland Avatar asked Jul 13 '26 22:07

dueland


1 Answers

  • implement a Comparator which can handle the hierarchical sorting
  • use Collator.getInstance for locale-aware string sorting

Here's a code snippet for a custom Comparator

public static class UserComparator implements Comparator<User> {

    private Collator collator = Collator.getInstance(); 

    @Override
    public int compare(User o1, User o2) {
        int compare = compareString(o1.getGroup(), o2.getGroup());
        if (compare == 0) {
            return compareString(o1.getName(), o2.getName());
        }
        return compare;
    }

    private int compareString(String o1, String o2) {
        return collator.compare(o1, o2);
    }

}

The Collator uses the case-sensitive sorting as appropriate for the given/current locale, which may (as f.i. German) or may not ignore (as f.i. US, if I remember correctly) case. If you want to ignore always, simply change the compareString to use o1.compareToIgnoreCase(o2)

FYI, JXList of SwingX project supports sorting by default (same mechanism as JTable), no acrobatics needed, just provide the comparator to use

 JXList list = new JXList(userListModel);
 list.setComparator(new UserComparator());
 list.setAutoCreateRowSorter(true);
 list.setSortOrder(SortOrder.ASCENDING); 
like image 189
kleopatra Avatar answered Jul 15 '26 12:07

kleopatra



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!