2009-04-11 15 views
8

Ho un'applicazione Swing e anche se ho tutto in un try/block, l'eccezione non viene rilevata.Come posso rilevare questa eccezione in Swing?

public static void main(String[] args) { 

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

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

tutto quello che ottiene è questo stack trace:

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

Sto per indovinare che hai una griglia da qualche parte a destra – geowa4

+0

È una JTable :) – feiroox

risposta

10

Come accennato da un altro poster, il problema è che l'eccezione viene generata in un altro thread, il thread di invio dell'evento. Un paio di soluzioni:

  • mettere un tentativo/aggirare il codice effettivo in cui si verifica l'eccezione: ad es. se è in risposta a un clic del pulsante gestito da un ActionListener, inserisci try/catch nel metodo actionPerformed();
  • oppure, lasciare l'eccezione come eccezione non rilevata e aggiungere uncaught exception handler. Per esempio:

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

Su un lato nota, si dovrebbe in linea di principio, ma il vostro codice di avvio interfaccia utente in un SwingUtilities.invokeLater().

+0

grazie per la nota a margine :) – feiroox

+1

Qualcuno ha mai veramente scoperto qualche eccezione generata nell'EDT usando Thread.setDefaultUncaughtExceptionHandler()? Dubito seriamente (almeno su JDK5, non ho controllato su JDK6) perché EDT cattura TUTTE le eccezioni da solo e rilascia semplicemente un printStackTrace() su System.err. – jfpoilpret

+1

Almeno in JDK 6, sembra "correttamente" passare attraverso il gestore di eccezioni non rilevate. Confesso che non mi ero reso conto che era qualcosa che era cambiato tra il 5 e il 6, ma forse. –

2

swing gestisce le cose nel thread dispacciamento evento. Stai provando a prenderlo nel thread principale.

E si noti che lo swing non è thread-safe, anche voi dovreste fare le cose nel thread di dispatch dell'evento.

Per rilevare l'eccezione, è possibile sovrascrivere un metodo da quella traccia di stack, come il metodo paint dal componente.

E per me quell'eccezione sembra un bug da correggere, non qualcosa che dovresti nascondere catturando.

+0

E come si cattura è possibile? – feiroox

+0

può essere d'aiuto, non sono un esperto Java: http://ruben42.wordpress.com/2009/03/30/catching-all-runtime-exceptions-in-swing/ – boj

0

Come accennato in precedenza, il problema è dove viene generata l'eccezione - sul thread di invio dell'evento.

Se si desidera impostare un blocco try/catch per catturare questo particolare problema, ne inserirò uno nel metodo paint della classe App. Esegui l'override e metti una chiamata a super.paint in un blocco catch try lì.

Se si desidera un metodo generico per rilevare le eccezioni non rilevate, dare un'occhiata a Thread.setUncaughtExceptionHandler. Chiami quel metodo con un gestore di eccezioni e puoi gestire tutte le eccezioni che non vengono scoperte nella tua applicazione.

2

Le eccezioni di runtime come ArrayIndexOutOfBoundsException mostrano un errore del programmatore. Quindi potrebbe essere meglio sistemarli piuttosto catturandoli e masticandoli silenziosamente.

Solo un'ipotesi per la causa dell'eccezione. Qualcosa rimuove contemporaneamente le righe dal datavector del modello di tabella una volta che JTable inizia a disegnare i dati sullo schermo.

+0

Hai ragione, ma sto usando una libreria che mastica l'eccezione per me. Quindi quando viene disegnata la tabella ottengo l'eccezione. Ma comunque volevo sapere cosa potevo fare. Potrei sistemare la libreria non so per certo. Il collegamento – feiroox

1

Gli unici modi idonei che sono a conoscenza di, al fine di intercettare le eccezioni lanciate dall'interno del EDT sono:

  • Scrivi la tua EventQueue (I woudln't consigliarlo in generale)
  • usa la proprietà interna di Swing "sun.awt.exception.handler" (Io uso e funziona su tutti i Sun JDK 1.4, 1.5 e 1.6 almeno, più su IBM JDK 1.4 e 1.5 almeno; I didn; T di verificarlo su altri JDK però)

si dovrebbe dare un'occhiata a this thread di avere una visione più completa delle soluzioni con i loro pro e contro.

+0

è morto ... –

Problemi correlati