source: josm/trunk/src/org/jdesktop/swinghelper/debug/CheckThreadViolationRepaintManager.java@ 14149

Last change on this file since 14149 was 10863, checked in by Don-vip, 8 years ago

update CheckThreadViolationRepaintManager to r296 - fix for https://java.net/jira/browse/SWINGHELPER-4

File size: 4.4 KB
Line 
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 */
16
17package org.jdesktop.swinghelper.debug;
18
19import java.lang.ref.WeakReference;
20
21import javax.swing.JComponent;
22import javax.swing.RepaintManager;
23import javax.swing.SwingUtilities;
24
25/**
26 * <p>This class is used to detect Event Dispatch Thread rule violations<br>
27 * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How to Use Threads</a>
28 * for more info</p>
29 * <p/>
30 * <p>This is a modification of original idea of Scott Delap<br>
31 * Initial version of ThreadCheckingRepaintManager can be found here<br>
32 * <a href="http://www.clientjava.com/blog/2004/08/20/1093059428000.html">Easily Find Swing Threading Mistakes</a>
33 * </p>
34 *
35 * @author Scott Delap
36 * @author Alexander Potochkin
37 *
38 * https://swinghelper.dev.java.net/
39 */
40public class CheckThreadViolationRepaintManager extends RepaintManager {
41 // it is recommended to pass the complete check
42 private boolean completeCheck = true;
43 private WeakReference<JComponent> lastComponent;
44
45 public CheckThreadViolationRepaintManager(boolean completeCheck) {
46 this.completeCheck = completeCheck;
47 }
48
49 public CheckThreadViolationRepaintManager() {
50 this(true);
51 }
52
53 @Override
54 public synchronized void addInvalidComponent(JComponent component) {
55 checkThreadViolations(component);
56 super.addInvalidComponent(component);
57 }
58
59 @Override
60 public void addDirtyRegion(JComponent component, int x, int y, int w, int h) {
61 checkThreadViolations(component);
62 super.addDirtyRegion(component, x, y, w, h);
63 }
64
65 private void checkThreadViolations(JComponent c) {
66 if (!SwingUtilities.isEventDispatchThread() && (completeCheck || c.isShowing())) {
67 boolean repaint = false;
68 boolean fromSwing = false;
69 boolean imageUpdate = false;
70 StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
71 for (StackTraceElement st : stackTrace) {
72 if (repaint && st.getClassName().startsWith("javax.swing.") &&
73 // for details see
74 // https://swinghelper.dev.java.net/issues/show_bug.cgi?id=1
75 !st.getClassName().startsWith("javax.swing.SwingWorker")) {
76 fromSwing = true;
77 }
78 if (repaint && "imageUpdate".equals(st.getMethodName())) {
79 imageUpdate = true;
80 }
81 if ("repaint".equals(st.getMethodName())) {
82 repaint = true;
83 fromSwing = false;
84 }
85 if ("read".equals(st.getMethodName()) && "javax.swing.JEditorPane".equals(st.getClassName())) {
86 // Swing reads html from a background thread
87 return;
88 }
89 }
90 if (imageUpdate) {
91 //assuming it is java.awt.image.ImageObserver.imageUpdate(...)
92 //image was asynchronously updated, that's ok
93 return;
94 }
95 if (repaint && !fromSwing) {
96 //no problems here, since repaint() is thread safe
97 return;
98 }
99 //ignore the last processed component
100 if (lastComponent != null && c == lastComponent.get()) {
101 return;
102 }
103 lastComponent = new WeakReference<>(c);
104 violationFound(c, stackTrace);
105 }
106 }
107
108 protected void violationFound(JComponent c, StackTraceElement[] stackTrace) {
109 System.out.println();
110 System.out.println("EDT violation detected");
111 System.out.println(c);
112 for (StackTraceElement st : stackTrace) {
113 System.out.println("\tat " + st);
114 }
115 }
116}
Note: See TracBrowser for help on using the repository browser.