Soutenez-nous

FAQ Java GUIConsultez toutes les FAQ

Nombre d'auteurs : 51, nombre de questions : 152, dernière mise à jour : 29 juin 2013 

 
OuvrirSommaireAWT et SwingTableaux et arbres (JTable et JTree)

Pour que certaines cellules d'une JTable ne soient pas éditables, il faut créer sa propre classe dérivant de javax.swing.table.DefaultTableModel et redéfinir la méthode isCellEditable(int,int) afin que cette dernière retourne faux pour ces cellules.

 
Sélectionnez
public boolean isCellEditable (int row, int column) {
        if ( celluleEstEditable ) {
                return ( true );
        } else {
                return ( false );
        } 
} 
Créé le 16 mai 2002  par Johann Heymes

Téléchargement : CustomTableModel1.java

On préférera un petit exemple à un long discours ;-)

Créé le 5 juin 2002  par Johann Heymes

Téléchargement : JTableFixedColumn.java

Les javax.swing.JTable sont prévus pour être affichés dans un JScrollPane, si ce n'est pas le cas l'en-tête n'est pas affiché. Pour l'afficher, vous pouvez récupérer l'en-tête en utilisant getTableHeader() et l'afficher séparément.

Un exemple est disponible ci-dessous.

Créé le 27 janvier 2003  par Johann Heymes

Téléchargement : Exemple d'implémentation.

Il suffit d'utiliser les méthodes columnAtPoint(java.awt.Point) et rowAtPoint(java.awt.Point) en lui passant le paramètre récupéré sur l'évènement java.awt.event.MouseEvent

 
Sélectionnez
int colonne, ligne;
Point p = e.getPoint ();
colonne = jtable.columnAtPoint (p);
ligne = jtable.rowAtPoint (p);
Créé le 27 janvier 2003  par Johann Heymes

Téléchargement : Exemple d'implémentation.

Il est parfois peu souhaitable que l'utilisateur puisse permuter les colonnes d'une javax.swing.JTable. Contre tout attente, la méthode permettant d'intervenir sur cette propriété n'est pas dans la classe JTable, mais dans la classe javax.swing.table.JTableHeader. Le code suivant permet d'annuler cette fonctionnalité.

 
Sélectionnez
maJTable.getTableHeader().setReorderingAllowed(false); 
Créé le 1er mars 2003  par Clément Cunin


Il faut utiliser le SelectionModel de la JTable pour travailler sur la séléction de la JTable. Par exemple, pour selectionner les lignes 2,4 et 5 de la JTable myJTable:

 
Sélectionnez
myJTable.getSelectionModel().addSelectionInterval(2,2); 
myJTable.getSelectionModel().addSelectionInterval(4,5);


Pour ce qui est de sélectionner des cellules ou des zones de cellules de la JTable, la méthode changeSelection est plus appropriée:

 
Sélectionnez
public void changeSelection(
  int rowIndex, 
  int columnIndex, 
  boolean toggle, 
  boolean extend)
Créé le 25 mai 2007  par JMLLB


Il faut utiliser les méthodes setHorizontalAlignment() et setVerticalAlignment() de la classe DefaultTableCellRenderer (ces méthodes sont en fait héritées de la classe JLabel).


Exemple : création d'un DefaultTableCellRenderer qui centre le contenu des colonnes :

 
Sélectionnez
public class CenterTableCellRenderer extends DefaultTableCellRenderer {
    public CenterTableCellRenderer() {
        setHorizontalAlignment(CENTER);
        setVerticalAlignment(CENTER);
    }
}


Il faut ensuite appliquer le renderer aux colonnes de la JTable :


- Soit à toutes les colonnes de la table :

 
Sélectionnez
JTable table = new JTable();
 // on applique le renderer à la table
table.setDefaultRenderer(Object.class, new CenterTableCellRenderer());


- Soit à une colonne en particulier :

 
Sélectionnez
// on applique le renderer à la colonne d'indice 0
table.getColumnModel().getColumn(0).setCellRenderer(new CenterTableCellRenderer());


On peut aussi faire de même pour les headers, cependant il vaut mieux récupérer le renderer par défaut et le modifier :


- Tous les headers :

 
Sélectionnez
// on applique le renderer sur tous les headers de la table
TableCellRenderer headerRenderer = table.getTableHeader().getDefaultRenderer());
((DefaultTableCellRenderer) headerRenderer).setHorizontalAlignment(DefaultTableCellRenderer.CENTER);


- Un header en particulier :

 
Sélectionnez
// on applique le renderer sur le header de la colonne d'indice 0
TableCellRenderer headerRenderer = table.getColumnModel().getColumn(0).getHeaderRenderer();
((DefaultTableCellRenderer) headerRenderer).setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
Créé le 26 mai 2007  par le y@m's

Lien : La classe DefaultCellRendererLa classe DefaultCellRenderer

Un JTree est un composant Swing permettant d'afficher un arbre (une structure de donnée hiérarchique). Ce composant ne contient pas de données mais plutôt une vue de données contenues dans son modèle.

Créé le 16 décembre 2006  par TheSeb

Lien : JTree

- Pour construire un JTree, il faut spécifier le modèle de l'arbre dans le constructeur.
- Il est posssible de créer son propre modèle en implémentant l'interface TreeModel ou bien en utilisant le modèle par défaut DefaultTreeModel.

 
Sélectionnez
DefaultTreeModel myModel = ...;JTree myTree = new JTree(myModel);

- Pour construire un modèle d'arbre par défaut, il est nécessaire de passer le noeud racine (root).
- Il est possible d'y passer tout objet implémentant l'interface TreeNode. Vous pouvez aussi utiliser la classe par défaut DefaultMutableTreeNode.

 
Sélectionnez
DefaultMutableTreeNode myRoot = ...;
DefaultTreeModel myModel = new DefaultTreeModel(myRoot);

- Pour créer un noeud, il faut indiquer un objet utilisateur. L'arbre utilisera le résultat de la méthode toString pour afficher une représentation de l'objet à un noeud donné. Pour un arbre représentant un système de fichiers, des objets File pourront être utilisés.

Voici un exemple simple et complet:

 
Sélectionnez
// Construction du noeud racine.
DefaultMutableTreeNode myRoot = new DefaultMutableTreeNode("Manuel");
 
// Construction des différents noeuds de l'arbre.
DefaultMutableTreeNode chap = new DefaultMutableTreeNode("Chapitre1");
myRoot.add(chap);
DefaultMutableTreeNode page = new DefaultMutableTreeNode("Page1");
chap.add(page);
page = new DefaultMutableTreeNode("Page2");
chap.add(page);
chap = new DefaultMutableTreeNode("Chapitre2");
myRoot.add(chap);
page = new DefaultMutableTreeNode("Page3");
chap.add(page);
 
// Construction du modèle de l'arbre.
DefaultTreeModel myModel = new DefaultTreeModel(myRoot);
 
// Construction de l'arbre.
JTree myTree = new JTree(myModel);
Créé le 16 décembre 2006  par TheSeb

Par défaut, la poignée du noeud racine n'existe pas. Pour l'afficher, il faut ajouter la ligne suivante :

 
Sélectionnez
myTree.setShowsRootHandles(true);
Créé le 16 décembre 2006  par TheSeb

Pour cacher le noeud racine, utile lorsque vous souhaitez afficher une forêt (un ensemble d'arbres), utilisez l'instruction suivante:

 
Sélectionnez
myTree.setRootVisible(false);
Créé le 16 décembre 2006  par TheSeb

La méthode la plus simple consiste à construire un objet DefaultTreeCellRender puis de modifier les icônes et de l'appliquer à l'arbre.

 
Sélectionnez
// Construction d'un afficheur par défaut.
DefaultTreeCellRenderer myRenderer = new DefaultTreeCellRenderer();
 
// Changement de l'icône pour les feuilles de l'arbre.
myRenderer.setLeafIcon(new ImageIcon("pageIcon.png"));
// Changement de l'icône pour les noeuds fermés.
myRenderer.setClosedIcon(new ImageIcon("closedBookIcon.png"));
// Changement de l'icône pour les noeuds ouverts.
myRenderer.setOpenIcon(new ImageIcon("openBookIcon.png"));
 
// Application de l'afficheur à l'arbre.
myTree.setCellRenderer(myRenderer);

Deux autres solutions consistent à implémenter l'interface TreeCellRenderer ou bien à étendre la classe DefaultTreeCellRenderer, permettant ainsi de modifier les icônes, la police et la couleur de fond des différents noeuds de l'arbre.

Créé le 16 décembre 2006  par TheSeb

De manière générale, le composant JTree ne s'utilise pas tout seul, un autre composant est utilisé pour afficher des informations relatives à l'objet utilisateur. Pour réaliser ce comportement, il est nécessaire de mettre en place un écouteur dit de sélection implémentant l'interface TreeSelectionListener sur l'arbre.

 
Sélectionnez
// Ajoute un événement de sélection à l'arbre.
myTree.addTreeSelectionListener(new TreeSelectionListener()
{
   // Appelé lorsque la valeur de la sélection change.
   public void valueChanged(TreeSelectionEvent event)
   {
      // Récupère le chemin dans l'arbre.
      TreePath myPath = myTree.getSelectionPath();
      if(myPath == null) return;
      // Récupère l'objet utilisateur correspondant.
      DefaultMutableTreeNode myNode = (DefaultMutableTreeNode) myPath.getLastPathComponent();
      Page myPage = (Page) myNode.getUserObject();
      myEditorPane().setPage(myPage.getUrl());
   }
});

La méthode valueChanged de l'interface TreeSelectionListener est appelée lorsque l'utilisateur sélectionne ou désélectionne un des noeuds de l'arbre.

Créé le 16 décembre 2006  par TheSeb

Il est possible de changer la méthode de sélection des noeuds de l'arbre avec la méthode setSelectionMode. Les différentes valeurs sont : SINGLE_TREE_SELECTION (sélection d'un seul noeud), CONTIGUOUS_TREE_SELECTION (sélection d'un ensemble contigus de noeuds), DISCONTIGUOUS_TREE_SELECTION (sélection d'un ensemble de noeuds). Exemple :

 
Sélectionnez
myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
Créé le 16 décembre 2006  par TheSeb

On utilise l'écouteur adapté à cet effet et on renvoie une exception au comportement qu'on ne veut pas produire :

 
Sélectionnez
jtree.addTreeWillExpandListener(new TreeWillExpandListener(){
	@Override
	public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {}
	@Override
	public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException{
		// On n'enroule pas le contenu du neoud quand on double-clique dessus
		throw new ExpandVetoException(event);
	}
});

Ici on interdit donc d'enrouler des noeuds.

Créé le 21 décembre 2009  par if_zen

En modifiant l'UI de l'arbre, il est tout à fait possible de modifier les icônes des arbres parents (aussi appelées poignées) :

 
Sélectionnez
((BasicTreeUI) ihmArbre.getUI()).setExpandedIcon(null);
((BasicTreeUI) ihmArbre.getUI()).setCollapsedIcon(null);

Ici, on les as supprimées, mais vous pouvez tout à fait les modifier.

Créé le 21 décembre 2009  par if_zen, Baptiste Wicht

Pour modifier l'indentation des éléments, on peut modifier l'UI de l'arbre :

 
Sélectionnez
((BasicTreeUI) jTree.getUI()).setRightChildIndent(0);
((BasicTreeUI) jTree.getUI()).setLeftChildIndent(0);

Ici on place les children au même niveau que les parents.

Créé le 21 décembre 2009  par if_zen

Il faut créer un nouveau BasicTreeUI et redéfinir les méthodes paintHorizontalPartOfLeg() et paintVerticalPartOfLeg pour indiquer qu'elles ne font rien :

 
Sélectionnez
jTree.setUI(new BasicTreeUI(){
	protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds,
		    TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf)  { }
	protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds, Insets insets, TreePath path)  { }
});
Créé le 21 décembre 2009  par if_zen
Les codes sources présentés sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Pour le reste, ce document constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Ce document issu de http://www.developpez.com est soumis à deux licences, en fonction des contributeurs : - Les contributions de Clément Cunin et Johann Heymes sont soumises aux termes de la la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies des contributions de Clément Cunin et Johann Heymes tant que cette note apparaît clairement : "Ce document issu de http://www.developpez.com est soumis à la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement". - Pour ce qui est des autres contributions : Copyright © 2004 - 2009 Developpez LLC : Tous droits réservés Developpez LLC. Aucune reproduction ne peut en être faite sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.