But: obtenir un JTable trié
La copie d'écran ci-contre illustre le tableau que nous souhaitons obtenir.
Le tri se compose de 3 éléments:
- lancer le tri des données contenues dans DefaultTableModel au click sur une colonne,
- conserver et indiquer l'ordre de tri croissant ou décroissant (fleche dans l'entete de la colonne),
- afficher les données lorsque l'on clique sur une ligne.
Class JAVA de tri TableSorterFrame
Le but de la class est d'illustrer une méthode rapide d'ajout la fonction de tri sur un JTable. En fait, les 3 fonctions que l'on souhaite ajouter à notre tableau sont disponibles dans les class de base de Swing.
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
/**
* Trier un JTable lors du click sur la colonne
* @author Axel 2013
* @copyright http://www.fobec.com/java/1127/trier-colonnes-jtable.html
*/
public class TableSorterFrame extends JFrame {
/**
* Constructeur
*/
public TableSorterFrame() {
super("Trier un tableau");
//Frame
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 400);
this.setLocationRelativeTo(null);
//Tableau
final JTable jTable = new JTable();
MyTableModel tm = this.getTableRows();
jTable.setModel(tm);
//Trieur de donnée
RowSorter<MyTableModel> sorter = new TableRowSorter<>(tm);
jTable.setRowSorter(sorter);
//Evenement : click sur une ligne du tableau
jTable.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
//N° de la ligne séléctionnée
int row = jTable.getSelectedRow();
//N° de ligne du tableau trié
int sortedRow = jTable.convertRowIndexToModel(row);
Object pe = jTable.getModel().getValueAt(sortedRow, 0);
Object pr = jTable.getModel().getValueAt(sortedRow, 1);
Object px = jTable.getModel().getValueAt(sortedRow, 2);
String s=pe + " a pris un " + pr + " au prix de " + px + " Eur";
System.out.println(s);
}
});
//GUI
JScrollPane jscrollPane = new javax.swing.JScrollPane();
jscrollPane.setViewportView(jTable);
getContentPane().add(jscrollPane);
this.setVisible(true);
}
/*
* Remplir le Model du tableau
*/
private MyTableModel getTableRows() {
String[] headers = new String[]{"Client", "Produit", "Prix"};
Object rows[][] = {{"Charles", "Casse croute", 4.56},
{"Georges", "Baguette", 1.22},
{"Victor", "Eclairs au chocolat", 10.05},
{"Leon", "Mille-feuille", 8.52},
{"Isabelle", "Pain campagne", 2.12}};
MyTableModel tableModel = new MyTableModel(rows, headers);
return tableModel;
}
public static void main(String args[]) {
TableSorterFrame frame=new TableSorterFrame();
frame.setVisible(true);
}
}
/**
* Custom class, modifier la fonction getColumnClass de DefaultTableModel
*/
class MyTableModel extends DefaultTableModel {
MyTableModel(Object[][] rows, String[] headers) {
super(rows, headers);
}
@Override
public Class getColumnClass(int column) {
Class returnValue;
if ((column >= 0) && (column < getColumnCount())) {
returnValue = getValueAt(0, column).getClass();
} else {
returnValue = Object.class;
}
return returnValue;
}
}
Précisions sur 2 éléments de la class TableSorterFrame
Héritage de DefaultTableModelLe fonctionnement standard du package retourne le nom de la class. En créant une nouvelle class DefaultTableModel, la fonction getColumnClass est modifiée pour qu'elle retourne le type d'oject d'une colonne.
//AbstractTableModel du package JAVA
public Class<?> getColumnClass(int columnIndex) {
return Object.class;
}
//Heritage MyTableModel
public Class getColumnClass(int column) {
Class returnValue;
if ((column >= 0) && (column < getColumnCount())) {
returnValue = getValueAt(0, column).getClass();
} else {
returnValue = Object.class;
}
return returnValue;
}
Click sur un élément du tableau
Lorsque le tableau est trié, la sélection d'une ligne retourne la valeur du tableau non trié ! La fonction convertRowIndexToModel() permet de trouver l'indice de la ligne dans le tableau trié.