TUTORIEL : AFFICHER ET MISE A JOUR DES Si l'une des colonnes JTable ou la fenêtre JTable
DONNEES A L'AIDE DE LA CLASSE SWING elle-même est redimensionnée, les autres
JTABLE colonnes peuvent réagir en s'élargissant ou en se
URL: réduisant pour s'adapter aux nouvelles
http://www.zdnet.fr/builder/programmation/java_c_ dimensions. Il est possible de contrôler ce
cplusplus/0,39020934,39115560,00.htm comportement à l'aide de la méthode
setAutoResizeMode():
La classe JTable de Swing automatise la
création de tableaux de données. Ces tableaux table.setAutoResizeMode(int mode);
peuvent être personnalisés à la volée.
Les valeurs possibles du champ entier mode sont:
Afficher la JTable
La figure A montre une table JTable dont le
La hauteur et la largeur de la JTable sont définies quadrillage horizontal est masqué.
comme suit:
table.setPreferredScrollableViewportSize(new
Dimension(300, 80));
1
ENI
2
ENI
3
ENI
Méthodes de AbstractTableModel
Le composant JTable est un «visualisateur» qui int findColumn(String Retourne l'indice du colonne
prend les données à afficher dans un modèle qui co) à partir de son nom.
implémente l’interface TableModel, ou qui dérive
Retourne la classe des
de la classe abstraite AbstractTableModel
objets de la colonne.
(javax.swing.table.AbstractTableModel). La classe
public Class
AbstractTableModel implémente les méthodes de
Class getColumnClass(int c){
TableModel sauf :
getColumnClass(int co) // un exemple : <
return getValueAt(0,
• public int getRowCount() : le nombre de
c).getClass();
lignes.
}
• public int getColumnCount() : le nombre
de colonnes. boolean isCellEditable( Retourne true si la cellule est
• public Object getValueAt(intligne, int int li, int co) éditable, et false sinon.
colonne) : l'objet à l'intersection de ligne et public boolean
colonne. isCellEditable(
int row, int col) {
Pour obtenir la même table que précédemment // toutes les cellules
éditables :
return true;
Définir la classe : Puis écrire :
4
ENI
5
ENI
6
ENI
Avec une méthode getTableHeaderRenderer public Ami(String nom, String prenom, Color
définie par : couleur, boolean homme, Sport sport) {
super();
public static TableCellRenderer
getTableHeaderRenderer() { this.nom = nom;
return new TableCellRenderer() { this.prenom = prenom;
public Component this.couleur = couleur;
getTableCellRendererComponent(JTable table, this.homme = homme;
Object value, boolean isSelected, boolean this.sport = sport;
hasFocus, }
int row, int column) {
JLabel lbl = new JLabel(); public String getNom() {
lbl.setBorder(new EtchedBorder()); return nom;
lbl.setHorizontalAlignment( JLabel.CENTER ); }
Font font = new java.awt.Font("Comic Sans
MS", java.awt.Font.PLAIN, 24); public void setNom(String nom) {
this.nom = nom;
8
ENI
} }
private final String[] entetes = {"Prénom", "Nom", Pour ce qui est de l'affichage, il suffit d'utiliser le
"Couleur favorite", "Homme", "Sport"}; nouveau modèle au lieu de l'ancien :
public class JTableBasiqueAvecModeleStatiqueObjet
public ModeleStatiqueObjet() { extends JFrame {
super(); public JTableBasiqueAvecModeleStatiqueObjet() {
super();
amis = new Ami[]{ setTitle("JTable avec modèle statique et des
new Ami("Johnathan", "Sykes", Color.red, objets");
true, Sport.TENNIS), setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
new Ami("Nicolas", "Van de Kampf", ;
Color.black, true, Sport.FOOTBALL),
new Ami("Damien", "Cuthbert", Color.cyan, JTable tableau = new JTable(new
true, Sport.RIEN), ModeleStatiqueObjet());
new Ami("Corinne", "Valance", Color.blue,
false, Sport.NATATION), getContentPane().add(new JScrollPane(tableau),
new Ami("Emilie", "Schrödinger", BorderLayout.CENTER);
Color.magenta, false, Sport.FOOTBALL),
new Ami("Delphine", "Duke", Color.yellow, pack();
false, Sport.TENNIS), }
new Ami("Eric", "Trump", Color.pink, true,
Sport.FOOTBALL) public static void main(String[] args) {
}; new JTableBasiqueAvecModeleStatiqueObjet().
9
ENI
setVisible(true); }
}
} public Object getValueAt(int rowIndex, int
Rien ne change au niveau du rendu. Dans le columnIndex) {
chapitre suivant, on va rendre dynamique notre switch(columnIndex){
modèle en permettant l'ajout et le retrait d'ami. case 0:
return amis.get(rowIndex).getPrenom();
case 1:
4.2. Ajouter/Supprimer des lignes return amis.get(rowIndex).getNom();
case 2:
La première chose à faire est donc de rendre return amis.get(rowIndex).getCouleur();
notre modèle dynamique. Pour cela, on va donc case 3:
ajouter des méthodes addAmi et removeAmi. return amis.get(rowIndex).isHomme();
Pour avertir le JTable qu'il y a eu des case 4:
modifications sur le modèle, il faut appeler les return amis.get(rowIndex).getSport();
méthodes fireXXX qui sont définies dans default:
AbstractTableModel. On va donc utiliser cette fois return null; //Ne devrait jamais arriver
une ArrayList, ce que pourrait donner notre }
modèle dynamique : }
public class ModeleDynamiqueObjet extends
AbstractTableModel { public void addAmi(Ami ami) {
private final List<Ami> amis = new amis.add(ami);
ArrayList<Ami>(); fireTableRowsInserted(amis.size() -1,
amis.size() -1);
private final String[] entetes = {"Prénom", }
"Nom", "Couleur favorite", "Homme", "Sport"};
public void removeAmi(int rowIndex) {
public ModeleDynamiqueObjet() { amis.remove(rowIndex);
super(); fireTableRowsDeleted(rowIndex, rowIndex);
}
amis.add(new Ami("Johnathan", "Sykes", }
Color.red, true, Sport.TENNIS));
amis.add(new Ami("Nicolas", "Van de Pour la méthode add(), on ajoute le nouvel Ami
Kampf", Color.black, true, Sport.FOOTBALL)); dans la liste ensuite de quoi on prévient la JTable
amis.add(new Ami("Damien", "Cuthbert", qu'un nouvel élément a été inséré. Pour la
Color.cyan, true, Sport.RIEN)); méthode remove() le principe est le même, on
amis.add(new Ami("Corinne", "Valance", commence par supprimer l'élément de la liste et
Color.blue, false, Sport.NATATION)); enfin on prévient le tableau qu'un élément a été
amis.add(new Ami("Emilie", "Schrödinger", supprimé. On va ajouter deux actions dans notre
Color.magenta, false, Sport.FOOTBALL)); interface graphique. La première va ajouter un
amis.add(new Ami("Delphine", "Duke", ami (pour simplifier, cela va toujours rajouter le
Color.yellow, false, Sport.TENNIS)); même objet, alors qu'en réalité, il faudrait
amis.add(new Ami("Eric", "Trump", proposer à l'utilisateur de configurer le nouvel
Color.pink, true, Sport.FOOTBALL)); ami) et la seconde va supprimer le ou les
} éléments sélectionnés. Voici ce que ça va nous
donner :
public int getRowCount() {
return amis.size(); public class
} JTableBasiqueAvecModeleDynamiqueObjet extends
JFrame {
public int getColumnCount() { private ModeleDynamiqueObjet modele = new
return entetes.length; ModeleDynamiqueObjet();
} private JTable tableau;
12
ENI
cancelCellEditing();
Autre exemple }
});
Il s'agit d'une classe permettant d'éditer une
cellule de JTable sous la forme d'un PopupMenu. private JPanel panelButtons;
Le PopupMenu contient des checkBoxMenuItem protected JXCheckBoxMenuItem[]
permettant de sélectionner plusieurs éléments en checkBoxMenuItems;
même temps, et présélectionnés selon la valeur
de la cellule. private static final MouseListener mouseListener =
new MouseAdapter() {
PopupEditor.java };
14
ENI
popupMenu.addSeparator();
popupMenu.add(panelButtons); Rectangle rect = table.getCellRect(row, column,
popupMenu.pack(); false);
popupMenu.setPackSize(popupMenu.getPreferre Dimension size = popupMenu.getPackSize();
dSize()); popupMenu.setPreferredSize(new
} Dimension(Math.max(rect.width,
size.width), size.height));
public Object getCellEditorValue() { popupMenu.show(table, rect.x, rect.y +
List list = new ArrayList(); rect.height);
for (int i = 0; i < checkBoxMenuItems.length; i++) {
JXCheckBoxMenuItem menuItem = Component comp =
checkBoxMenuItems[i]; renderer.getTableCellRendererComponent(table,
if (menuItem.isSelected()) { value,
list.add(menuItem.getItem()); isSelected, false, row, column);
} comp.removeMouseListener(mouseListener);
} comp.addMouseListener(mouseListener);
return list.toArray(); return comp;
} }
15
ENI
} package popup;
16