Salut,
@nodogeid, un "formatteur" est un composant qui permet de "formatter", c'est à dire d'indiquer comment on veut afficher une valeur. Par exemple, si on une date, on peut vouloir l'afficher "21/05/2014", ou "le mercredi 21 mai de l'année 2014", 2 formats différents pour la même valeur.
@jean_Carlo, un TableCellEditor, c'est fait pour éditer. Pour afficher, on utilise un TableCellRenderer.
DateFormat permet d'obtenir des formats de date standard, genre long, court, complet... Avec SimpleDateFormat, on peut formatter la date selon un format précis, défini par un motif.
Ensuite, il faut "configurer" la JTable pour qu'elle l'utilise.
Soit, par exemple, en l'affectant à une colonne particulière :
table.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);
Soit, en l'associant à une classe :
table.setDefaultRenderer(Date.class, renderer);
Mais dans ce cas, il faut aussi que la JTable puisse connaitre la classe d'une colonne, ce qui se fait par le modèle. Par défaut, le modèle d'une JTable est un DefaultTableModel, qui hérite d'un AbstractTableModel qui définit toutes les classes de toutes les colonnes comme Object.
On peut définit un modèle spécifique, par exemple, comme ça :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class MyTableModel extends DefaultTableModel {
public MyTableModel() {
}
public MyTableModel(int rowCount, int columnCount) {
super(rowCount, columnCount);
}
public MyTableModel(Vector columnNames, int rowCount) {
super(columnNames, rowCount);
}
public MyTableModel(Object[] columnNames, int rowCount) {
super(columnNames, rowCount);
}
public MyTableModel(Vector data, Vector columnNames) {
super(data, columnNames);
}
public MyTableModel(Object[][] data, Object[] columnNames) {
super(data, columnNames);
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch(columnIndex) {
case 3:// si la 4ième colonne est de type Date
return Date.class;
default:
return super.getColumnClass(columnIndex);
}
}
} |
Le cas d'erreur que tu indiques @nodogeid est dû au fait que l'instance qui est rendue n'est pas du type Date, et, donc ne peut pas être formatté par un DateFormat.
Il suffit que tu modifies ton renderer comme ça, et, si la valeur n'est pas une Date, il n'y aura plus d'erreur (aucune valeur ne sera affichée, si ce n'est pas une Date) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| static class DateRenderer extends DefaultTableCellRenderer {
DateFormat formatter;
public DateRenderer() {
super();
}
public void setValue(Object value) {
if ( value instanceof Date) {
if (formatter == null)
formatter = DateFormat.getDateInstance();
setText(formatter.format(value));
}
else {
setText("");
}
}
} |
ou avec un format spécifique :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| static class DateRenderer extends DefaultTableCellRenderer {
final DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
public DateRenderer() {
super();
}
public void setValue(Object value) {
if ( value instanceof Date) {
setText(formatter.format(value));
}
else {
setText("");
}
}
} |
Si tu préfères que si le type n'est pas Date, ça affiche quand même la valeur, tout simplement :
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public void setValue(Object value) {
if ( value instanceof Date) {
if (formatter == null)
formatter = DateFormat.getDateInstance();
setText(formatter.format(value));
}
else if ( value!=null ) {
setText(String.valueOf(value));
}
else {
setText("");
}
} |
Tu vois qu'on pourrait ajouter même d'autre test de classe (Double, Boolean, etc...) pour gérer d'autre formattage (pour Double, voir DecimalFormat).
Partager