2009-04-11 1 views
8

J'ai une application Swing, et même si j'ai tout dans un try/block, l'exception n'est pas interceptée.Comment puis-je attraper cette exception dans Swing?

public static void main(String[] args) { 

    try { 
     App app = new App(); 
     app.setVisible(true); 

    } catch (Throwable e) { 
     System.err.println("never printed"); 
    } 
} 

tout ce que je reçois est cette trace de la pile:

Exception in thread "AWT-EventQueue-0" 
java.lang.ArrayIndexOutOfBoundsException: 
9 >= 9 
at java.util.Vector.elementAt(Vector.java:427) 
at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:633) 
at javax.swing.JTable.getValueAt(JTable.java:2695) 
at javax.swing.JTable.prepareRenderer(JTable.java:5712) 
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2075) 
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:1977) 
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1773) 
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:143) 
at javax.swing.JComponent.paintComponent(JComponent.java:763) 
at javax.swing.JComponent.paint(JComponent.java:1027) 
at javax.swing.JComponent.paintChildren(JComponent.java:864) 
at javax.swing.JComponent.paint(JComponent.java:1036) 
at javax.swing.JViewport.paint(JViewport.java:747) 
at javax.swing.JComponent.paintChildren(JComponent.java:864) 
at javax.swing.JComponent.paint(JComponent.java:1036) 
at javax.swing.JComponent.paintChildren(JComponent.java:864) 
at javax.swing.JComponent.paint(JComponent.java:1036) 
at javax.swing.JComponent.paintChildren(JComponent.java:864) 
at javax.swing.JComponent.paint(JComponent.java:1036) 
at javax.swing.JLayeredPane.paint(JLayeredPane.java:564) 
at javax.swing.JComponent.paintChildren(JComponent.java:864) 
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5129) 
at javax.swing.BufferStrategyPaintManager.paint 
(BufferStrategyPaintManager.java:277) 
at javax.swing.RepaintManager.paint(RepaintManager.java:1217) 
at javax.swing.JComponent.paint(JComponent.java:1013) 
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21) 
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60) 
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97) 
at java.awt.Container.paint(Container.java:1780) 
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814) 
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:714) 
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:694) 
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run 
(SystemEventQueueUtilities.java:128) 
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) 
at java.awt.EventDispatchThread.pumpOneEventForFilters 
(EventDispatchThread.java:269) 
at java.awt.EventDispatchThread.pumpEventsForFilter 
(EventDispatchThread.java:184) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy 
(EventDispatchThread.java:174) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 
+0

Je vais deviner que vous avez une grille quelque part à droite – geowa4

+0

C'est un JTable :) – feiroox

Répondre

10

Comme mentionné par une autre affiche, votre problème est que l'exception est lancée dans un autre thread, le thread de distribution d'événements. Un couple de solutions:

  • mettre un try/catch autour du code réel où l'exception se produit: par ex. si c'est en réponse à un clic de bouton géré par un ActionListener, placez le try/catch dans votre méthode actionPerformed();
  • ou, laissez l'exception comme exception non interceptée et ajoutez un uncaught exception handler. Par exemple:

    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 
     public void uncaughtException(Thread t, Throwable e) { 
     // ... do something with exception here ... 
     } 
    }); 

D'un côté note, vous devriez en principe, mais votre code de démarrage de l'interface utilisateur dans un SwingUtilities.invokeLater().

+0

merci pour la note de côté :) – feiroox

+1

Quelqu'un a-t-il vraiment détecté une exception dans l'EDT en utilisant Thread.setDefaultUncaughtExceptionHandler()? Je doute sérieusement (au moins sur JDK5, n'a pas vérifié sur JDK6) parce que l'EDT attrape TOUTES les exceptions par lui-même et juste émettre un printStackTrace() à System.err. – jfpoilpret

+1

Dans JDK 6 au moins, il semble "correctement" passer par le gestionnaire d'exception uncaught. J'avoue que je n'avais pas réalisé que c'était quelque chose qui avait changé entre 5 et 6, mais peut-être. –

2

swing dirige les choses dans le fil de répartition des événements. Vous essayez de l'attraper dans le fil principal.

Et notez que swing n'est pas thread-safe, vous devriez aussi faire des choses dans l'envoi de thread.

Pour intercepter l'exception, vous pouvez remplacer certaines méthodes de cette trace de pile, comme la méthode de peinture de votre composant.

Et pour moi, cette exception ressemble à un bogue que vous devez corriger, pas à quelque chose que vous devriez cacher en attrapant.

+0

Et comment attraper est-ce possible? – feiroox

+0

peut aider, je ne suis pas un expert Java: http://ruben42.wordpress.com/2009/03/30/catching-all-runtime-exceptions-in-swing/ – boj

0

Comme mentionné ci-dessus, le problème est l'endroit où l'exception est levée - sur le thread de distribution d'événements.

Si vous voulez configurer un bloc try/catch pour attraper ce problème particulier, j'en ajouterais un dans la méthode de peinture de la classe App. Remplacez-le et appelez super.paint dans un bloc try catch.

Si vous voulez un moyen générique d'intercepter les exceptions non interceptées, jetez un oeil à Thread.setUncaughtExceptionHandler. Vous appelez cette méthode avec un gestionnaire d'exceptions et vous pouvez gérer toutes les exceptions qui ne sont pas interceptées dans votre application.

2

Des exceptions d'exécution telles que ArrayIndexOutOfBoundsException indiquent une erreur de programmation. Donc, il pourrait être préférable de les fixer plutôt attraper et de le mâcher silencieusement.

Juste une supposition sauvage pour la cause de l'exception. Quelque chose supprime simultanément les lignes du datavector du modèle de table une fois que le JTable commence à dessiner les données à l'écran.

+0

Vous avez raison, mais j'utilise la bibliothèque qui mâchent l'exception pour moi. Par conséquent, lorsque la table est dessinée, j'obtiens l'exception. Mais de toute façon je voulais savoir ce que je pouvais faire. Je pourrais corriger la bibliothèque pas sûr de savoir. – feiroox

1

Les seuls moyens appropriés que je suis au courant, afin d'intercepter les exceptions lancées à l'intérieur de l'EDT sont:

  • écrire votre propre EventQueue (je woudln't conseille en général)
  • utilisez Swing propriété interne "sun.awt.exception.handler" (je l'utilise et il fonctionne sur tous les Sun JDK 1.4, 1.5 et 1.6 au moins, plus sur IBM JDK 1.4 et 1.5 au moins; Je n; t vérifier sur d'autres que JDK)

Vous devriez jeter un oeil à this thread d'avoir une vue d'ensemble plus complète des solutions avec leurs avantages et inconvénients.

+0

lien est mort ... –