//
// DataFileTableModel.java
// DataFileTable
//
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.io.*;
import java.util.*;
/**
La classe DataFileTableModel
Cette classe dérivée de la classe AbstractTableModel devra implémenter
un certain nombre de méthodes déclarées abstraites.
Elle utilisera pour ce faire les données contenues dans un fichier.
Déclaration et variables
Nous utiliserons trois variables:
une chaine de caractères contenant le nom du fichier de données
un vecteur contenant les noms de colonnes
un vecteur contenant les données à afficher dans le tableau
La classe Vector permet de créer une collection d'objets qui fonctionne de
la même manière qu'un tableau, à l'exception que sa capacité peut varier en fonction des besoins.
Vector vecteur = new Vector();
Java définit quatre niveaux d'accès pour les variables
d'instances (données membres) et les méthodes :
public : un élément public est accessible de partout et sans aucune restriction.
Certaines classes (comme la classe principale main) doivent obligatoirement être
déclarées publiques (pour pouvoir exécuter l'application...)
protected : un élément protected (protégé) est accessible uniquement
aux classes d'un package et à ses classes filles
private : un élément private (privé) est accessible uniquement au sein de la
classe dans laquelle il est déclaré. Ces éléments ne peuvent être manipulés
qu'à l'aide de méthode spécifiques appelés accesseur et mutateur
*/
public class DataFileTableModel extends AbstractTableModel {
protected Vector data; //données
protected Vector columnNames ; //noms de colonnes
protected String datafile; //nom du fichier de données
public DataFileTableModel(String f){
datafile = f;
initVectors();
}
public void initVectors() {
String aLine ;
data = new Vector();
columnNames = new Vector();
//L'instruction try... catch désigne un bloc de commandes à essayer et spécifie qu'une
//réponse doit lancer une exception. Si une exception est lancée, l'instruction try... catch la saisira.
try {
//FileInputStream(File file)
//crée un objet FileInputStream en ouvrant une connexion à un fichier
// courant, soit le fichier désigné par l'objet File.
FileInputStream fin = new FileInputStream(datafile);
//La classe BufferedReader lit du texte à partir d'un flux d'entrée de caractères,
//mettant en mémoire tampon les caractères afin de fournir une plus
//grande efficacité pour la lecture de caractères, de tableaux et de lignes.
BufferedReader br = new BufferedReader(new InputStreamReader(fin));
// extract column names
//La classe StringTokenizer permet à une application de décomposer
//une chaîne de caractères en jetons.
StringTokenizer st1 = new StringTokenizer(br.readLine(), "|");
//La boucle while contient comme argument une condition d'arrêt toujours évaluée avant chaque itération.
while(st1.hasMoreTokens()) //vérifie s'il n'y a plus de jetons disponibles à partir de l'objet StringTokenizer.
columnNames.addElement(st1.nextToken());
// extract data
while ((aLine = br.readLine()) != null) {
StringTokenizer st2 =
new StringTokenizer(aLine, "|");
while(st2.hasMoreTokens())
data.addElement(st2.nextToken());
}
br.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
//Nombre de lignes :
//Le nombre de lignes est obtenu en divisant le nombre d'éléments
//du champ data par le nombre de colonnes.
public int getRowCount() {
return data.size() / getColumnCount();
}
//Nombre de colonnes :
//Le nombre de colonnes est le nombre d'éléments du champ columnNmes.
public int getColumnCount(){
return columnNames.size();
}
//Noms des colonnes :
//Les noms des colonnes sont contenus dans le champ columnNames.
public String getColumnName(int columnIndex) {
String colName = "";
if (columnIndex <= getColumnCount())
colName = (String)columnNames.elementAt(columnIndex);
return colName;
}
//Type de contenu d'une colonne
//Dans notre exemple, toutes les données sont des chaînes de caractères, donc de classe String.
public Class getColumnClass(int columnIndex){
return String.class;
}
//Possibilité d'édition des données
//On indique ici quelles cellules sont modifiables. Dans notre exemple, aucune cellule ne le sera.
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
//Contenu d'une cellule :
//On donne ici le contenu de chaque cellule sous forme d'objet. Dans notre exemple,
//ce contenu est une chaîne de caractères contenue dans le champ data. Il faut tenir compte
//du fait que les données sont placées les unes derrière les autres et donc recalculer leur position
//en fonction de la ligne et de la colonne de la cellule.
public Object getValueAt(int rowIndex, int columnIndex) {
return (String)data.elementAt( (rowIndex * getColumnCount()) + columnIndex);
}
//Changement du contenu d'une cellule :
//On indique ici comment prendre en compte les modifications du contenu des cellules effectuées
//par l'utilisateur. Dans notre exemple, aucune cellule n'est éditable, il n'y a donc rien à faire.
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
data.setElementAt( aValue, (rowIndex*getColumnCount())+columnIndex);
}
}