如何在Swing中捕获此异常?

时间:2009-04-11 16:57:06

标签: java swing exception

我有一个Swing应用程序,即使我拥有try / block中的所有内容,也不会捕获该异常。

public static void main(String[] args) {

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

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

我得到的就是这个堆栈跟踪:

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)

5 个答案:

答案 0 :(得分:10)

正如另一张海报所提到的,你的问题是异常被抛入另一个线程,即事件派发线程。几个解决方案:

  • 对发生异常的实际代码进行try / catch:例如如果它是对ActionListener处理的按钮单击的响应,则将try / catch放在actionPerformed()方法中;
  • 或者,将异常保留为未捕获的异常,并添加uncaught exception handler。例如:

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

另一方面,您原则上应该使用SwingUtilities.invokeLater()中的UI启动代码。

答案 1 :(得分:2)

Swing在事件调度线程中运行事物。你试图在主线程中捕获它。

请注意,swing不是线程安全的,你也应该在事件调度线程中做事。

要捕获异常,您可以覆盖该堆栈跟踪中的某些方法,例如组件中的paint方法。

对我而言,异常确实看起来像你应该修复的错误,而不是你应该通过捕捉隐藏的东西。

答案 2 :(得分:2)

运行时异常(如ArrayIndexOutOfBoundsException)显示程序员错误。因此,最好是修理它们而不是悄悄地咀嚼它。

只是对异常原因的猜测。一旦JTable开始在屏幕上绘制数据,某些东西会同时从表模型的数据向量中删除行。

答案 3 :(得分:1)

为了捕捉从EDT内部抛出的异常,我所知道的唯一合适方式是:

  • 编写自己的EventQueue(我没有 一般建议)
  • 使用Swing内部属性“sun.awt.exception.handler”(我用 它适用于所有Sun JDK 1.4, 至少1.5和1.6,至少在IBM JDK 1.4和1.5上;我没有在其他JDK上查看它)

您应该查看this thread,以便更全面地了解这些解决方案的优缺点。

答案 4 :(得分:0)

如上所述,问题在于抛出异常 - 在事件派发线程上。

如果你想设置一个try / catch块来捕获这个特定的问题,我会把一个扔进App类的paint方法。覆盖它并在那里的try catch块中调用super.paint。

如果您想要一种通用方法来捕获未捕获的异常,请查看Thread.setUncaughtExceptionHandler。您可以使用异常处理程序调用该方法,并且可以处理未在应用程序中捕获的所有异常。