Results 1 to 7 of 7
- 02-17-2009, 04:59 PM #1
Member
- Join Date
- Feb 2009
- Posts
- 4
- Rep Power
- 0
TableRowSorter, explicit comparator is not working
Hi guys
I've got a problem with the TableRowSorter.
Cotext is this: I'd like to set up an explicit comparator for one of the columns of a JTable. In the customized table model I've got, I cannot override the getColumClass in my table model, so I need to specify an ad-hoc comparator. Problem's that once I click the column header the "sorting arrow" changes as to the sorting was taking place, but actually no sorting happens. Further, each entry of the table is an instance of a specific class.
I've coded a small test case base on the actual one.
Any help would be highly appreciated.
Regards
Nicola
Here's the actual(dummy) testing code:
Entry point to create the JTable:
import java.awt.*;
import java.util.*;
import javax.swing.DefaultListSelectionModel;
import javax.swing.*;
import javax.swing.table.TableRowSorter;
import com.enterprise.filmmanager.Film;
import com.enterprise.filmmanager.table.FilmTableCell;
import com.enterprise.filmmanager.table.FilmTableModelExt ended;
public class FilmTableGUITestCase {
final static List<Film> repository = new ArrayList<Film>();
final static JFrame frame = new JFrame("Film Monitor");
final static JTable table = new JTable();
static {
repository.add(new Film(10L, new Date(), "Not so1 bad", "1,000,000", false, Film.Category.FANTASY));
repository.add(new Film(13L, new Date(), "Not so bad", "1,210", false, Film.Category.ACTION));
repository.add(new Film(20L, new Date(), "Not so6 bad", "1,710", false, Film.Category.ACTION));
repository.add(new Film(21L, new Date(), "Not so bad", "1,130", false, Film.Category.EPIC));
repository.add(new Film(22L, new Date(), "Not so bad", "1,110", false, Film.Category.COMEDY));
}
private static class MyComparator1 implements Comparator<Object> {
@Override
public int compare(final Object f1, final Object f2) {
try {
final Long l1 = new Long(((FilmTableCell)f1).getData().replace(",","") );
final Long l2 = new Long(((FilmTableCell)f2).getData().replace(",", ""));
System.out.println("First: "l1", Second: "+l2);
return l1.compareTo(l2);
}
catch(Exception e) {
e.printStackTrace();
return 0;
}
}
}
private static void initGUI() {
final JPopupMenu popupMenu = new JPopupMenu();
final JPanel tablePanel = new JPanel(new BorderLayout());
table.setComponentPopupMenu(popupMenu);
final FilmTableModelExtended filmTableModel = new FilmTableModelExtended(repository);
table.setModel(filmTableModel);
final ListSelectionModel filmTableSelectionModel = new DefaultListSelectionModel();
filmTableSelectionModel.setSelectionMode(ListSelec tionModel.SINGLE_INTERVAL_SELECTION);
table.setSelectionModel(filmTableSelectionModel);
final TableRowSorter<FilmTableModelExtended> sorter = new TableRowSorter<FilmTableModelExtended>(filmTableMo del);
sorter.setComparator(1, new MyComparator1());
sorter.sort();
table.setRowSorter(sorter);
final JScrollPane tablePane = new JScrollPane(table);
tablePanel.add(tablePane, BorderLayout.NORTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS E);
frame.setLocationRelativeTo(null);
frame.setLocation(new Point(300, 300));
final Container contentPane = frame.getContentPane();
contentPane.add(tablePanel);
frame.setSize(new Dimension(500, 500));
frame.setVisible(true);
}
public static void main(String[] args) {
final Runnable runnable = new Runnable() {
public void run() {
initGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
TableModel and utility classes:
package com.enterprise.filmmanager.table;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import com.enterprise.filmmanager.Film;
public class FilmTableModelExtended extends AbstractTableModel {
private List<Film> data;
private String[] columns = new String[] {"ID", "Title", "Evaluation", "Download Data", "Watched", "Category"};
private final FilmTableCell tableCell = new FilmTableCell();
public FilmTableModelExtended(final List<Film> data) {
this.data = data;
}
@Override
public int getColumnCount() {
return columns.length;
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public Object getValueAt(int row, int column) {
tableCell.setAlert(false);
if (row > data.size()) {
tableCell.setData("");
}
else {
final Film film = data.get(row);
switch (column) {
case 0:
tableCell.setData(film.getId().toString());
break;
case 1:
tableCell.setData(film.getTitle());
break;
case 2:
tableCell.setData(film.getEvaluation());
break;
case 3:
tableCell.setData(film.getDownloadDate().toString( ));
break;
case 4:
tableCell.setData(film.isWatched().toString());
break;
case 5:
tableCell.setData(film.getCategory().toString());
break;
default:
throw new IllegalArgumentException("Unexpected Column on FilmTableModel: " + column);
}
}
return tableCell;
}
public String getColumnName(int col) {
switch (col) {
case 0:
return "ID";
case 1:
return "Title";
case 2:
return "Evaluation";
case 3:
return "Download Data";
case 4:
return "Watched";
case 5:
return "Category";
}
return "";
}
}
package com.enterprise.filmmanager.table;
public class FilmTableCell {
private String data;
private boolean alert;
public FilmTableCell(final String data, final boolean alert) {
this.data = data;
this.alert = alert;
}
public FilmTableCell() {
this.data = "";
this.alert = false;
}
public void setData(final String data) {
this.data = data;
}
public void setAlert(final boolean alert) {
this.alert = alert;
}
public final String getData() {
return data;
}
public final boolean isAlert() {
return alert;
}
}
package com.enterprise.filmmanager;
import java.util.Comparator;
import java.util.Date;
public final class Film {
public enum Category {
ALL, FANTASY, ACTION, COMEDY, EPIC
}
private final Long id;
private final String title;
private final Boolean watched;
private final Date downloadDate;
private final String evaluation;
private final Category category;
public Film(final Long id, final Date downloadDate, final String evaluation, final String title,
final Boolean watched, final Category category) {
this.id = id;
this.downloadDate = downloadDate;
this.evaluation = evaluation;
this.title = title;
this.watched = watched;
this.category = category;
}
public Category getCategory() {
return category;
}
public Long getId() {
return id;
}
public String getTitle() {
return title;
}
public Boolean isWatched() {
return watched;
}
public Date getDownloadDate() {
return downloadDate;
}
public String getEvaluation() {
return evaluation;
}
@Override
public String toString() {
return id + " " + title + " " + evaluation + " " + downloadDate + " " + category;
}
}
- 02-18-2009, 02:51 PM #2
First, you can look at Sorting and Filtering in the Sun Tutorial.
Second, the easiest way I can see to sort a column is avoid implementing any sort of custom TableRowSort and simply ensure that the column you want to sort implements the Comparator interface. You may need to extend an existing class to do that, but that is easy. You just need a compareTo() method.
I don't have time to analyze exactly what you did in your code, but I would suggest getting rid of the comparator and the sorter.
In the TableModel interface implementation, implement the getColumnClass() method. In the column you want to sort on, modify the class to implement Comparator.
Essentially, you are letting the framework do all the work by putting the specifics in TableModel.
- 02-18-2009, 03:42 PM #3
Member
- Join Date
- Feb 2009
- Posts
- 4
- Rep Power
- 0
Hi Steve
Thank you for the reply. I've already read the tutorial and I know how it works sorting table's columns overriding the getColumnClass() in the table model. Unfortunately, I cannot override it, so I was looking for setting an explicit compator. I already did it plenty of times, the problem now is that, in my JTable, each entry is an instance of an ad-hoc class which holds the current value to be set in the entry itself. This is the only difference I see with my previos trials. The tricky point is that, after setting the TableRowSorter's comporator or extending TableRowSorter itself overriding the getComparator method, is that when the user click on the column with the explicit comparator all the machinery takes life (I mean, the vertical arrow), but the actual data remains unsorted, 'couse comparator uses the same data for both the entries to compare!
Usually, you have int compare(Obj a1, Obj a2), what I see in my debug session is that the undelying infrastructure is passing the same value for both a1 and a2, where a1 and a2 are instances of my TableCell holder class.
Cheers
NicolaLast edited by Nicola; 02-18-2009 at 03:50 PM.
- 02-18-2009, 04:53 PM #4
OK, you are in over my head ;-)
- 02-19-2009, 03:57 PM #5
Member
- Join Date
- Feb 2009
- Posts
- 4
- Rep Power
- 0
No way! I had to restructure my TableModel to properly override the getColumnClass to solve the issue. It seems that wheenver you've got a proprer table cell value holder, there's no way make it working the customer comparator with the magic TableRowSorter.
- 02-19-2009, 07:20 PM #6
Why didn't I think of that... :-(
- 02-20-2009, 10:03 AM #7
Member
- Join Date
- Feb 2009
- Posts
- 4
- Rep Power
- 0
Similar Threads
-
Jtable + TableRowSorter
By Ralphw in forum AWT / SwingReplies: 8Last Post: 02-05-2009, 09:39 AM -
Use different comparator for SortedSet
By linus_k in forum New To JavaReplies: 0Last Post: 11-21-2008, 02:46 PM -
How to search with a Comparator
By Java Tip in forum java.langReplies: 0Last Post: 04-15-2008, 07:39 PM -
How to write your own Comparator
By Java Tip in forum java.langReplies: 0Last Post: 04-15-2008, 07:38 PM -
Using Comparable and Comparator interfaces
By barney in forum New To JavaReplies: 1Last Post: 08-07-2007, 07:10 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks