KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > debug > CheckThreadViolationRepaintManager


1 package debug;
2
3 import java.util.*;
4 import javax.swing.*;
5
6 //from the Troubleshooting Guide for JavaTM SE 6 DesktopTechnologies
7
// December 2006 64
8

9 /** checks that the calls to the swing methods are in the EDT.
10 *
11 * Usage: call
12 * RepaintManager.setCurrentManager(new debug.CheckThreadViolationRepaintManager());
13 * a summary print will appear at the end
14 */

15 public class CheckThreadViolationRepaintManager extends RepaintManager
16 {
17
18     // it is recommended to pass the complete check
19
private boolean completeCheck = true;
20
21     Map<String JavaDoc, Integer JavaDoc> alreadyShown = new HashMap<String JavaDoc, Integer JavaDoc>();
22     private int badCallsOutsideProject = 0;
23     private int repaintsFromSwing = 0;
24
25     HashSet<String JavaDoc> projectPackagesStartWith = new HashSet<String JavaDoc>(
26        Arrays.asList("SnowMailClient.", "snow.", "DNS.", "khunpangame."));
27
28     // exact match...
29
HashSet<String JavaDoc> allowedMethodNamesCallingRepaint = new HashSet<String JavaDoc>(Arrays.asList(
30       "imageUpdate", "insertString", "setCharacterAttributes", "setText"));
31
32
33     public CheckThreadViolationRepaintManager() {
34
35         Runtime.getRuntime().addShutdownHook(new Thread JavaDoc()
36         {
37            public void run()
38            {
39               System.out.println("\n=====RepaintManager EDT Check:\n badCallsOutsideProject="+badCallsOutsideProject);
40               System.out.println(" repaintsFromSwing: "+repaintsFromSwing);
41
42               System.out.println(" "+alreadyShown.size()+" distinct bad calls from project:");
43               for(String JavaDoc bc : alreadyShown.keySet())
44               {
45                 System.out.println("\tat "+bc+": "+alreadyShown.get(bc));
46               }
47            }
48         });
49     }
50
51
52     public synchronized void addInvalidComponent(JComponent component) {
53         checkThreadViolations(component);
54         // use delegatee instead of super for *all* methods
55
super.addInvalidComponent(component);
56     }
57
58     public boolean isCompleteCheck() {
59         return completeCheck;
60     }
61
62     public void setCompleteCheck(boolean completeCheck) {
63         this.completeCheck = completeCheck;
64     }
65
66
67     public void addDirtyRegion(JComponent component, int x, int y, int w, int h) {
68         checkThreadViolations(component);
69         super.addDirtyRegion(component, x, y, w, h);
70     }
71
72
73     private void checkThreadViolations(JComponent c)
74     {
75         if (!SwingUtilities.isEventDispatchThread() && (completeCheck || c.isShowing())) {
76             Throwable JavaDoc exception = new Throwable JavaDoc();
77             boolean repaint = false;
78             boolean fromSwing = false;
79             StackTraceElement JavaDoc[] stackTrace = exception.getStackTrace();
80             StackTraceElement JavaDoc firstInProject = null;
81             for (StackTraceElement JavaDoc st : stackTrace)
82             {
83                 if (repaint && st.getClassName().startsWith("javax.swing.")) {
84                     fromSwing = true;
85                 }
86                 if ("repaint".equals(st.getMethodName())) {
87                     repaint = true;
88                 }
89
90                 if(repaint && allowedMethodNamesCallingRepaint.contains(st.getMethodName())) return;
91
92                 if(firstInProject==null)
93                 {
94                   for(String JavaDoc sw : projectPackagesStartWith)
95                   {
96                     if( st.getClassName().startsWith(sw))
97                     {
98                        firstInProject = st;
99                        break;
100                     }
101                   }
102                 }
103             }
104             if (repaint && !fromSwing)
105             {
106                 //no problems here, since repaint() is thread safe
107
repaintsFromSwing++;
108                 return;
109             }
110
111
112             if(firstInProject==null)
113             {
114                badCallsOutsideProject++;
115                // don't print them !
116
return;
117             }
118             else if( alreadyShown.containsKey(""+firstInProject))
119             {
120                // show only once but count
121
alreadyShown.put(""+firstInProject, alreadyShown.get(""+firstInProject)+1);
122                return;
123             }
124             else
125             {
126                alreadyShown.put(""+firstInProject, 1);
127                // show the first immediately:
128
exception.printStackTrace();
129             }
130
131         }
132     }
133 }
Popular Tags