Mouhammed Soueidane
Mouhammed Soueidane

Reputation: 1066

TableSorter numeric values sorting

Since I'm using Java 1.4.2, this means that I cannot use Java's implementation of the table sorter. Instead, I've been using the TableSorter.java class from an earlier reply to my previous post: Heads up on implementing rowsorter and rowfilter java 1.4

It's working perfectly with one problem however, which is that it doesn't sort numeric values correctly. For instance, I have the following sequence of numbers in my table: 5,18,9,7,2,33

A increasing order sorting would display them like this in my JTable:

18,2,33,5,7,9

A decreasing order sorting would display them like this in my JTable: 9,7,5,33,2,18

I don't know if you have realized it, but apparently, the sorting of numeric values is only happening based on the first digit.

Do you have any quick fix for the problem? Please bare in mind that those numeric values are used as strings in my JTable as suggested by the getValue() method.

Upvotes: 0

Views: 3116

Answers (3)

Mouhammed Soueidane
Mouhammed Soueidane

Reputation: 1066

To update you guys on this, what I did was to replace the LEXICAL_COMPARATOR in the TableSorter.java from my original post with this:

public static final Comparator LEXICAL_COMPARATOR = new Comparator() { public int compare(Object o1, Object o2) { if(o1 instanceof Integer) {
Integer firstNumeric, secondNumeric;

            firstNumeric =(Integer)o1;
            secondNumeric= (Integer)o2;

                    return firstNumeric.compareTo(secondNumeric);


        }
        else
        return o1.toString().compareTo(o2.toString());
    }
};

Now, in the getValueAt, make sure that your "int" values are cast into Integer by simply doing: new Integer(intValue);

I hope this will save people some time.

Upvotes: 0

Femi
Femi

Reputation: 64700

You need to implement a Comparator that performs a numeric comparison rather than the default lexicographical one. So something like (taken from http://crossedlogic.blogspot.com/2008/11/java-custom-comparators-sorting-text.html):

Comparator c1 = new java.util.Comparator() {
        /**
         * Custom compare to sort numbers as numbers.
         * Strings as strings, with numbers ordered before strings.
         * 
         * @param o1
         * @param o2
         * @return
         */
@Override
            public int compare(Object oo1, Object oo2) {
                boolean isFirstNumeric, isSecondNumeric;
                String o1 = oo1.toString(), o2 = oo2.toString();


            isFirstNumeric = o1.matches("\\d+");
            isSecondNumeric = o2.matches("\\d+");

            if (isFirstNumeric) {
                if (isSecondNumeric) {
                    return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));
                } else {
                    return -1; // numbers always smaller than letters
                }
            } else {
                if (isSecondNumeric) {
                    return 1; // numbers always smaller than letters
                } else {
                    isFirstNumeric = o1.split("[^0-9]")[0].matches("\\d+");
                    isSecondNumeric = o2.split("[^0-9]")[0].matches("\\d+");

                    if (isFirstNumeric) {
                        if (isSecondNumeric) {
                            int intCompare = Integer.valueOf(o1.split("[^0-9]")[0]).compareTo(Integer.valueOf(o2.split("[^0-9]")[0]));
                            if (intCompare == 0) {
                                return o1.compareToIgnoreCase(o2);
                            }
                            return intCompare;
                        } else {
                            return -1; // numbers always smaller than letters
                        }
                    } else {
                        if (isSecondNumeric) {
                            return 1; // numbers always smaller than letters
                        } else {
                            return o1.compareToIgnoreCase(o2);
                        }
                    }
                }
            }
        }
    };

then pass that in as the comparator for the column:

tblSorter.setColumnComparator(String.class, c1);

Let me know how that works.

Upvotes: 1

trashgod
trashgod

Reputation: 205785

Verify that getColumnClass() returns a numeric type, such as Number.

Addendum: MyTableModel in TableSorterDemo is an example. Data for the third column is of type Integer, a subclass of Number; as a result, getColumnClass() returns Integer.class. Because Integer implements Comparable, the column is sorted numerically.

Upvotes: 2

Related Questions