问题描述
关于我的问题(可能是),我发现了另一种异常类型,我无法从 SwingWorker
线程中捕获和打印出来.
如何生成 RepaintManager
异常?
我读了这个CheckThreadViolationRepaintManager
和 Alexander Potochkin 的 rel="nofollow noreferrer">这种方法,但似乎没有什么能解决我的问题.
如果有帮助,下面的示例 会打印以下 Exception
的多个变体,主要针对每个变体框架的 UI 委托初始化阶段.我使用了 CheckThreadViolationRepaintManager
,但是AspectJ
变体看起来也很有趣.
import javax.swing.JComponent;导入 javax.swing.JFrame;导入 javax.swing.RepaintManager;导入 javax.swing.SwingUtilities;/** @see https://stackoverflow.com/questions/7787998 */公共类 EDTViolation {公共静态无效主(字符串参数[]){RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());JFrame f = new JFrame();f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.pack();f.setVisible(true);}私有静态类 CheckThreadViolationRepaintManager 扩展了 RepaintManager {//http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html私有布尔值 completeCheck = true;私有 WeakReference最后一个组件;公共 CheckThreadViolationRepaintManager(boolean completeCheck) {this.completeCheck = completeCheck;}公共 CheckThreadViolationRepaintManager() {这是真的);}公共布尔 isCompleteCheck() {返回完整检查;}public void setCompleteCheck(boolean completeCheck) {this.completeCheck = completeCheck;}@覆盖公共同步无效 addInvalidComponent(JComponent 组件) {checkThreadViolations(组件);super.addInvalidComponent(component);}@覆盖public void addDirtyRegion(JComponent 组件,int x,int y,int w,int h){checkThreadViolations(组件);super.addDirtyRegion(component, x, y, w, h);}私有无效 checkThreadViolations(JComponent c) {if (!SwingUtilities.isEventDispatchThread() && (completeCheck || c.isShowing())) {布尔重绘 = 假;布尔值 fromSwing = false;布尔图像更新 = 假;StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();for (StackTraceElement st : stackTrace) {if (repaint && st.getClassName().startsWith("javax.swing.")&&//详情见//https://swinghelper.dev.java.net/issues/show_bug.cgi?id=1!st.getClassName().startsWith("javax.swing.SwingWorker")) {fromSwing = 真;}if (repaint && "imageUpdate".equals(st.getMethodName())) {图像更新 = 真;}if ("repaint".equals(st.getMethodName())) {重绘=真;fromSwing = 假;}if ("read".equals(st.getMethodName()) &&"javax.swing.JEditorPane".equals(st.getClassName())) {//Swing 从后台线程读取 html返回;}}如果(图像更新){//假设它是 java.awt.image.ImageObserver.imageUpdate(...)//图片是异步更新的,没关系返回;}如果(重绘&& !fromSwing){//这里没有问题,因为 repaint() 是线程安全的返回;}//忽略最后处理的组件if (lastComponent != null && c == lastComponent.get()) {返回;}lastComponent = new WeakReference(c);违规发现(c,堆栈跟踪);}}受保护的无效违规发现(JComponent c,StackTraceElement[] stackTrace){System.out.println();System.out.println("检测到EDT违规");System.out.println(c);for (StackTraceElement st : stackTrace) {System.out.println(" at " + st);}}}}
In connection with my question (may be), I found another exception type that I not able to catch and print-out from SwingWorker
thread.
How can I to generate RepaintManager
exceptions?
I read this CheckThreadViolationRepaintManager
and this approach by Alexander Potochkin
, but nothing seems to solve my issues.
If it helps, the example below prints multiple variations of the following Exception
, mostly for each phase of the frame's UI delegate initialization. I used CheckThreadViolationRepaintManager
, but the AspectJ
variation looks interesting, too.
java.lang.Exception at EDTViolation$CheckThreadViolationRepaintManager.checkThreadViolations(EDTViolation.java:43) at EDTViolation$CheckThreadViolationRepaintManager.addDirtyRegion(EDTViolation.java:37) at javax.swing.JComponent.repaint(JComponent.java:4734) at java.awt.Component.repaint(Component.java:3168) at javax.swing.JComponent.setFont(JComponent.java:2727) at javax.swing.LookAndFeel.installColorsAndFont(LookAndFeel.java:191) at javax.swing.plaf.basic.BasicPanelUI.installDefaults(BasicPanelUI.java:49) at javax.swing.plaf.basic.BasicPanelUI.installUI(BasicPanelUI.java:39) at javax.swing.JComponent.setUI(JComponent.java:662) at javax.swing.JPanel.setUI(JPanel.java:136) at javax.swing.JPanel.updateUI(JPanel.java:109) at javax.swing.JPanel.(JPanel.java:69) at javax.swing.JPanel.(JPanel.java:92) at javax.swing.JPanel.(JPanel.java:100) at javax.swing.JRootPane.createGlassPane(JRootPane.java:528) at javax.swing.JRootPane.(JRootPane.java:348) at javax.swing.JFrame.createRootPane(JFrame.java:255) at javax.swing.JFrame.frameInit(JFrame.java:236) at javax.swing.JFrame.(JFrame.java:159) at EDTViolation.main(EDTViolation.java:12) ...
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;
/** @see https://stackoverflow.com/questions/7787998 */
public class EDTViolation {
public static void main(String args[]) {
RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
private static class CheckThreadViolationRepaintManager extends RepaintManager {
//http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html
private boolean completeCheck = true;
private WeakReference<JComponent> lastComponent;
public CheckThreadViolationRepaintManager(boolean completeCheck) {
this.completeCheck = completeCheck;
}
public CheckThreadViolationRepaintManager() {
this(true);
}
public boolean isCompleteCheck() {
return completeCheck;
}
public void setCompleteCheck(boolean completeCheck) {
this.completeCheck = completeCheck;
}
@Override
public synchronized void addInvalidComponent(JComponent component) {
checkThreadViolations(component);
super.addInvalidComponent(component);
}
@Override
public void addDirtyRegion(JComponent component, int x, int y, int w, int h) {
checkThreadViolations(component);
super.addDirtyRegion(component, x, y, w, h);
}
private void checkThreadViolations(JComponent c) {
if (!SwingUtilities.isEventDispatchThread() && (completeCheck || c.isShowing())) {
boolean repaint = false;
boolean fromSwing = false;
boolean imageUpdate = false;
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for (StackTraceElement st : stackTrace) {
if (repaint && st.getClassName().startsWith("javax.swing.")
&& // for details see
// https://swinghelper.dev.java.net/issues/show_bug.cgi?id=1
!st.getClassName().startsWith("javax.swing.SwingWorker")) {
fromSwing = true;
}
if (repaint && "imageUpdate".equals(st.getMethodName())) {
imageUpdate = true;
}
if ("repaint".equals(st.getMethodName())) {
repaint = true;
fromSwing = false;
}
if ("read".equals(st.getMethodName()) && "javax.swing.JEditorPane".equals(st.getClassName())) {
// Swing reads html from a background thread
return;
}
}
if (imageUpdate) {
//assuming it is java.awt.image.ImageObserver.imageUpdate(...)
//image was asynchronously updated, that's ok
return;
}
if (repaint && !fromSwing) {
//no problems here, since repaint() is thread safe
return;
}
//ignore the last processed component
if (lastComponent != null && c == lastComponent.get()) {
return;
}
lastComponent = new WeakReference<JComponent>(c);
violationFound(c, stackTrace);
}
}
protected void violationFound(JComponent c, StackTraceElement[] stackTrace) {
System.out.println();
System.out.println("EDT violation detected");
System.out.println(c);
for (StackTraceElement st : stackTrace) {
System.out.println(" at " + st);
}
}
}
}
这篇关于如何从 RepaintManager 生成异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!