Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
692 views
in Technique[技术] by (71.8m points)

java - Trouble setting a column comparator to a JTable

In another thread I found this comparator (bottom of post) for sorting JTable columns that could be composed of integers, strings, or both. I cannot figure out how to apply it to my JTable. My table was using the auto created row sorter before. I set that to false and I am now using:

TableRowSorter<MyTableModel> rowSorter = new TableRowSorter<MyTableModel>();
jtable.setRowSorter(rowSorter);
rowSorter.setComparator(0, c1);

I get an index out of bounds exception saying I am providing an invalid range. My table has multiple columns though. Is this the correct way to apply the comparator? I feel like this is not the way to do it.

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);
                    }
                }
            }
        }
    }
};
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

when manually setting a RowSorter, you have to take care of keeping it in synch with the model yourself:

 TableRowSorter sorter = new TableRowSorter();
 table.setRowSorter(sorter);
 sorter.setModel(table.getModel());
 sorter.setComparator(myComparator);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...