Solved

jtable sort by column

Posted on 2006-06-15
7
609 Views
Last Modified: 2011-10-03
Hey Guys,
I have a little situation, I'm using the TableSorter to sort my jtable which can be found at http://www.objects.com.au/java/examples/swing/SortableTable.do

package table;

import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
/**
* @version 1.0 02/25/99
*/

public class TableSorter {
  SortableTableModel model;
  public TableSorter(SortableTableModel model) {
    this.model = model;
  }

  //n2 selection
  public void sort(int column, boolean isAscent) {
    int n = model.getRowCount();
    int[] indexes = model.getIndexes();
    for (int i = 0; i < n - 1; i++) {
      int k = i;
      for (int j = i + 1; j < n; j++) {
        if (isAscent) {
          if (compare(column, j, k) < 0) {
            k = j;
          }
        }
        else {
          if (compare(column, j, k) > 0) {
            k = j;
          }
        }
      }
      int tmp = indexes[i];
      indexes[i] = indexes[k];
      indexes[k] = tmp;
    }
  }

// comparaters
  public int compare(int column, int row1, int row2) {
    Object o1 = model.getValueAt(row1, column);
    Object o2 = model.getValueAt(row2, column);
    if (o1 == null && o2 == null) {
      return 0;
    }
    else if (o1 == null) {
      return -1;
    }
    else if (o2 == null) {
      return 1;
    }
    else {
      Class type = model.getColumnClass(column);
      if (type.getSuperclass() == Number.class) {
        return compare( (Number) o1, (Number) o2);
      }
      else if (type == String.class) {
        return ( (String) o1).compareTo( (String) o2);
      }
      else if (type == Date.class) {
        return compare( (Date) o1, (Date) o2);
      }
      else if (type == Boolean.class) {
        return compare( (Boolean) o1, (Boolean) o2);
      }
      else {
        return ( (String) o1).compareTo( (String) o2);
      }
    }
  }

  public int compare(Number o1, Number o2) {
    double n1 = o1.doubleValue();
    double n2 = o2.doubleValue();
    if (n1 < n2) {
      return -1;
    }
    else if (n1 > n2) {
      return 1;
    }
    else {
      return 0;
    }
  }

  public
      int compare(Date o1, Date o2) {
    long n1 = o1.getTime();
    long n2 = o2.getTime();
    if (n1 < n2) {
      return -1;
    }
    else if (n1 > n2) {
      return 1;
    }
    else {
      return 0;
    }
  }

  public int compare(Boolean o1, Boolean o2) {
    boolean b1 = o1.booleanValue();
    boolean b2 = o2.booleanValue();
    if (b1 == b2) {
      return 0;
    }
    else if (b1) {
      return 1;
    }
    else {
      return -1;
    }
  }
}

An example of data that I get by sorting by direction is like this:

Distance     Direction    City                    Zip      Count
0                E               Escondido          92026  3
23.69          W              Oceanside         92054  1
11.84          W              Carlsbad           92008  5
6.97            W              Vista                 92084  2
22.98          W              Oceanside         92056   1

Now if you notice it's sorted by direction but since W is the same in more than one row it doesn't sort completely.
What I would want is to sort by say  Direction then City, because there is more than one row with the same direction and same city so that it would look like this:

Distance     Direction    City                    Zip      Count
0                E               Escondido          92026   3
23.69          W              Oceanside         92054   1
22.98          W              Oceanside         92056   1
11.84          W              Carlsbad           92008   5
6.97            W              Vista                 92084  2

How can i do this?

0
Comment
Question by:tbboyett
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 3

Expert Comment

by:ForceRs
ID: 16914475
Is it as easy as a recursive call to sort (at the bottom of sort) with a different column number?

You must ensire that the recursive call only happens once, or you will loop, but an instance varaibale would work for this.

Psuedo code:
public void sort(int column, boolean isAscent) {
    int n = model.getRowCount();
    ...
    ...
    ...
    int tmp = indexes[i];
    indexes[i] = indexes[k];
    indexes[k] = tmp;
    if(!alreadyCalledSortsecondTime) {
        alreadyCalledSortsecondTime = true; // instance variable
        int secondaryColumnToSort = 0;
        boolean ascending = true;
        switch(column) {
          case 0:
              secondaryColumnToSort = 1;
              ascending = false;
              break;
          default:
              break;
        } // end switch
        sort(secondaryColumnToSort, ascending);
    } // end if
             
0
 
LVL 5

Author Comment

by:tbboyett
ID: 16915513
Unfortunately it doesn't appear to change the results
0
 
LVL 3

Accepted Solution

by:
ForceRs earned 450 total points
ID: 16915890
You could modify the public int compare(int column, int row1, int row2) method to concatinate the objects (into Strings) to force the sort to work the way you require, based on the column the user clicked.

If the user clicks the direction column header, then concatinate direction and city and then call the compareTo(String) method.  If the user clicks a numeric column (say count), then you would have to get count's value, zero fill to say 15 bytes (5 would be 000000000000005) and then concatinate whatever other field(s) you desire as secondary/tertiary, etc. fileds.

It's some monkey business, but I've done this successfully before.
0
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 92

Assisted Solution

by:objects
objects earned 50 total points
ID: 16916733
you need to replace the compare() method with your specific business logic, that ones just a generic one.
eg. you would need to check the column that it is being sorted on,m and if your direction column then compare both direction and city.
0
 
LVL 5

Author Comment

by:tbboyett
ID: 16920445
>  if your direction column then compare both direction and city

I am uncertain a little confused on how I would compare both direction and city at the same time.

ForceRs I'll give that a shot and see what happens
0
 
LVL 3

Expert Comment

by:ForceRs
ID: 16920533
You're simply forcing the sort keys to be exactly what you want them to be.  Overriding the default behavior.  You must create new strings for each row of table, dynamically, in the public int compare(int column, int row1, int row2) method, then your string compareTo will work as desired.

public int compare(int column, int row1, int row2) {
    Object o1 = model.getValueAt(row1, column);
    Object o2 = model.getValueAt(row2, column);
    // FORCE o1 and o2 to be strings, zero justified for Number types.
    if (o1 == null && o2 == null) {
...
0
 
LVL 5

Author Comment

by:tbboyett
ID: 16920891
It was a lot easier than I was thinking, thanks guys
0

Featured Post

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This video teaches viewers about errors in exception handling.

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question