2010-06-16 9 views
3

J'ai rencontré un comportement étrange de JTable (JDK 1.5_22):
Après un changement de sélection dans la table et dans certaines circonstances particulières inconnues, le JTable appellera le rendu de cellule avec 'null' pour le paramètre value.
Cela conduira finalement à une belle 'Exception pointeur nul' sur un code de rendu personnalisé qui n'est pas prêt pour un tel appel grossier.JTable comportement étrange de la méthode getAccessibleChild() résultant en null pointeur dans le code client

Voici la méthode coupable (JTable.java, ligne 5319):

public Accessible getAccessibleChild(int i) { 
      if (i < 0 || i >= getAccessibleChildrenCount()) { 
       return null; 
      } else { 
       // children increase across, and then down, for tables 
       // (arbitrary decision) 
       int column = getAccessibleColumnAtIndex(i); 
       int row = getAccessibleRowAtIndex(i); 

       TableColumn aColumn = getColumnModel().getColumn(column); 
       TableCellRenderer renderer = aColumn.getCellRenderer(); 
       if (renderer == null) { 
        Class<?> columnClass = getColumnClass(column); 
        renderer = getDefaultRenderer(columnClass); 
       } 
       Component component = renderer.getTableCellRendererComponent(
            JTable.this, null, false, false, 
            row, column); 
       return new AccessibleJTableCell(JTable.this, row, column, 
         getAccessibleIndexAt(row, column)); 
      } 
     } 

et l'accent est mis ici sur la déclaration défectueuse:

Component component = renderer.getTableCellRendererComponent(
            JTable.this, null, false, false, 
            row, column); 

demandé google cinque "JTable getAccessibleChild 5334" était intéressant: je ne suis pas le seul à rencontrer ce 'trait'. Mais il n'y avait pas de réponse.

La question la mieux formulée se trouve on official sun forum.

Est-ce que quelqu'un a une idée à ce sujet?

Répondre

5

Ce n'est pas un problème de synchronisation ou d'EDT. Le code dans JTable appelle explicitement getTableCellRendererComponent avec une valeur null.

La valeur retournée n'est jamais utilisée, donc, sur la surface, elle ressemble plutôt à un ancien code de débogage. Cependant je soupçonne qu'il est là pour ne pas casser le code qui s'attend getTableCellRendererComponent à être appelé avant qu'une cellule soit accédée.

Sun a déjà été appelé sur ce problème et leur réponse a été que l'API ne garantit pas que value est non nul, donc getTableCellRendererComponent doit échouer correctement lorsqu'il est appelé avec une valeur nulle.

+0

+1 Bien repéré. – trashgod

+0

J'aime la théorie du «vieux code de débogage»: D – Guillaume

0

Chaque fois que je vois des problèmes inexplicables autrement comme ceci, je m'interroge au sujet de la synchronisation incorrecte. Par exemple,

1) Ne pas avoir construit le composant sur event dispatch thread.

2) Mutation du modèle du composant sur un autre thread.

Les violations se manifestent plus fréquemment en présence d'une initialisation complexe, d'un modèle avec une latence inattendue ou d'un matériel différent. Il peut aussi y avoir un bug, mais ces deux points méritent d'être vérifiés.