10

I have a Swing application, and even though I have everything in a try/block, the exception isn't caught.

public static void main(String[] args) {

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

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

all I get is this 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)
George Stocker
  • 57,289
  • 29
  • 176
  • 237
feiroox
  • 3,069
  • 8
  • 31
  • 31

5 Answers5

13

As mentioned by another poster, your problem is that the exception is being thrown in another thread, the event dispatch thread. A couple of solutions:

  • put a try/catch around the actual code where the exception is occurring: e.g. if it's in response to a button click handled by an ActionListener, put the try/catch inside your actionPerformed() method;
  • or, leave the exception as an uncaught exception, and add an uncaught exception handler. For example:

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

On a side-note, you should in principle but your UI startup code in a SwingUtilities.invokeLater().

Neil Coffey
  • 21,615
  • 7
  • 62
  • 83
  • 1
    Has someone really ever caught any exception thrown in the EDT by using Thread.setDefaultUncaughtExceptionHandler()? I seriously doubt (at least on JDK5, didn't check on JDK6) because the EDT catches ALL exceptions by itself and just issue a printStackTrace() to System.err. – jfpoilpret Apr 13 '09 at 01:47
  • 1
    In JDK 6 at least, it appears to "properly" go through the uncaught exception handler. I confess I didn't realise this was something that had changed between 5 and 6, but maybe. – Neil Coffey Apr 13 '09 at 04:45
  • I'm now really able to catch the exception.(using jdk1.6.) – feiroox Apr 13 '09 at 10:13
  • 3
    On previous jdk versions, you had to use an unofficial trick - setting the "sun.awt.exception.handler" property with your handler. Something like this: System.setProperty("sun.awt.exception.handler",ExceptionHandler.class.getName()); public class ExceptionHandler { public void handle(Throwable ex) { ... } } This trick still works (up till java 6), but it may not work in future versions. – alves Jul 03 '09 at 11:52
  • The only method I know to catch unhandled exceptions on the event dispatch thread is to register a new EventQueue, as described [here](http://ruben42.wordpress.com/2009/03/30/catching-all-runtime-exceptions-in-swing/). Using `Thread.setDefaultUncaughtExceptionHandler()` will not work. – Duncan Jones Aug 21 '12 at 14:27
  • Duncan - see comments above: it looks like this is something that changed from Java 5 to Java 6. – Neil Coffey Aug 21 '12 at 18:44
2

Swing runs things in the event dispatching thread. You are trying to catch it in the main thread.

And note that swing is not thread safe, you too should be doing things in event dispatching thread.

To catch the exception, you can override some method from that stack trace, like the paint method from your component.

And for me that exception does look like a bug you should fix, not something you should hide by catching.

iny
  • 7,339
  • 3
  • 31
  • 36
2

Runtime exceptions like ArrayIndexOutOfBoundsException shows a programmer mistake. So it might be better to fix them rather catching and silently chewing it.

Just a wild guess for the cause of exception. Something concurrently remove rows from the table model's datavector once the JTable starts to draw the data on screen.

Manoj
  • 364
  • 1
  • 2
  • 8
  • You are right, but I'm using library which chew the exception for me. Therefore when the table is drawed I get the exception. But anyway I wanted to know what could I do. I might fix the library not sure know. – feiroox Apr 12 '09 at 11:17
1

The only suitable ways that I am aware of, in order to catch exceptions thrown from inside the EDT are:

  • write your own EventQueue (I woudln't advise it in general)
  • use Swing internal property "sun.awt.exception.handler" (I use it and it works on all Sun JDK 1.4, 1.5 and 1.6 at least, plus on IBM JDK 1.4 and 1.5 at least; I didn;t check it on other JDK though)

You should take a look at this thread to have a more complete overview of the solutions with their pros and cons.

jfpoilpret
  • 10,449
  • 2
  • 28
  • 32
0

As mentioned above, the problem is where the exception is being thrown - on the event dispatch thread.

If you want to set up a try/catch block to catch this particular problem, I would throw one into the App class's paint method. Override it and put a call to super.paint in a try catch block there.

If you want a generic way to catch uncaught exceptions, take a look at Thread.setUncaughtExceptionHandler. You call that method with an exception handler and you can deal with all the exceptions which don't get caught in your application.

deterb
  • 3,994
  • 1
  • 28
  • 33