Stephane Grenier
Stephane Grenier

Reputation: 15927

Java Swing - how to tell what code is calling paint on the component?

Somewhere in my code a call to paint is being called but the stacktrace gives absolutely no idea as to what and where. It's also intermittent so I know it's a threading issue, and if I put a breakpoint then the code never fails. So how do I tell where or how the event thread is called to repaint the component?

Here is the stacktrace:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 4
    at javax.swing.plaf.basic.BasicTabbedPaneUI.paintTabArea(BasicTabbedPaneUI.java:834)
    at javax.swing.plaf.basic.BasicTabbedPaneUI.paint(BasicTabbedPaneUI.java:797)
    at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
    at javax.swing.JComponent.paintComponent(JComponent.java:778)
    at javax.swing.JComponent.paint(JComponent.java:1054)
    at javax.swing.JComponent.paintChildren(JComponent.java:887)
    at javax.swing.JComponent.paint(JComponent.java:1063)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5219)
    at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1529)
    at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1452)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1249)
    at javax.swing.JComponent._paintImmediately(JComponent.java:5167)
    at javax.swing.JComponent.paintImmediately(JComponent.java:4978)
    at javax.swing.RepaintManager$3.run(RepaintManager.java:808)
    at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
    at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
    at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

Upvotes: 3

Views: 556

Answers (1)

xav
xav

Reputation: 5618

You're maybe performing actions on your GUI outside the EDT. In every piece of code you suspect, you may want to use SwingUtilities.isEventDispatchThread() to test if you are currently in EDT. If this method returns false then you should not performing any UI action.

Here is an example of how to use it for debugging:

public static void checkInEventDispatchThread(String pMethod) {
    if (!SwingUtilities.isEventDispatchThread()) {
        System.err.println("** NOT in EDT: " + pMethod + "() in " + 
                           Thread.currentThread().getName());
    }
}

And for every piece of code you suspect:

public void myMethod() {
    UtilClass.checkInEventDispatchThread("myMethod");
}

Of course, it's only for debugging purpose, you shall not keep such calls for production/releases.

Upvotes: 2

Related Questions