2014-01-25 4 views
2

Где-то в моем коде вызывается призыв к рисованию, но stacktrace не дает абсолютно никакой идеи о том, что и где. Это также прерывисто, поэтому я знаю, что это проблема с потоками, и если я поставлю точку останова, то код никогда не сработает. Итак, как мне определить, где и как вызван поток событий, чтобы перекрасить компонент?Java Swing - как узнать, какой код вызывает краску на компоненте?

Вот 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) 
+2

По существу, вы не можете. Краски назначаются в очередь событий и в будущем будут обрабатываться потоком диспетчеризации событий. Вам нужно попытаться выяснить, кто неправильно изменил состояние пользовательского интерфейса и убедиться, что они сделаны из контекста EDT. – MadProgrammer

+0

Есть ли способ сообщить, какой компонент был нарисован? –

+0

Экземпляр, на самом деле, но я могу сказать, что это был JTabbedPane – MadProgrammer

ответ

2

Вы, возможно, выполняя действия на вашем GUI вне EDT. В каждом фрагменте кода, который вы подозреваете, вы можете использовать SwingUtilities.isEventDispatchThread(), чтобы проверить, находитесь ли вы в настоящий момент в EDT. Если этот метод возвращает false, вы не должны выполнять какое-либо действие пользовательского интерфейса.

Вот пример того, как использовать его для отладки:

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

И за каждый кусок кода, который вы подозреваете:

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

Конечно, это только для отладки цели, вы должны не оставляйте такие звонки для производства/выпуска.

Смежные вопросы