本文介绍了如何从 RepaintManager 生成异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于我的问题(可能是),我发现了另一种异常类型,我无法从 SwingWorker 线程中捕获和打印出来.

如何生成 RepaintManager 异常?

我读了这个CheckThreadViolationRepaintManagerAlexander Potochkin 的 rel="nofollow noreferrer">这种方法,但似乎没有什么能解决我的问题.

解决方案

如果有帮助,下面的示例 会打印以下 Exception 的多个变体,主要针对每个变体框架的 UI 委托初始化阶段.我使用了 CheckThreadViolationRepaintManager,但是AspectJ 变体看起来也很有趣.

java.lang.异常在 EDTViolation$CheckThreadViolationRepaintManager.checkThreadViolations(EDTViolation.java:43)在 EDTViolation$CheckThreadViolationRepaintManager.addDirtyRegion(EDTViolation.java:37)在 javax.swing.JComponent.repaint(JComponent.java:4734)在 java.awt.Component.repaint(Component.java:3168)在 javax.swing.JComponent.setFont(JComponent.java:2727)在 javax.swing.LookAndFeel.installColorsAndFont(LookAndFeel.java:191)在 javax.swing.plaf.basic.BasicPanelUI.installDefaults(BasicPanelUI.java:49)在 javax.swing.plaf.basic.BasicPanelUI.installUI(BasicPanelUI.java:39)在 javax.swing.JComponent.setUI(JComponent.java:662)在 javax.swing.JPanel.setUI(JPanel.java:136)在 javax.swing.JPanel.updateUI(JPanel.java:109)在 javax.swing.JPanel.(JPanel.java:69)在 javax.swing.JPanel.(JPanel.java:92)在 javax.swing.JPanel.(JPanel.java:100)在 javax.swing.JRootPane.createGlassPane(JRootPane.java:528)在 javax.swing.JRootPane.(JRootPane.java:348)在 javax.swing.JFrame.createRootPane(JFrame.java:255)在 javax.swing.JFrame.frameInit(JFrame.java:236)在 javax.swing.JFrame.(JFrame.java:159)在 EDTViolation.main(EDTViolation.java:12)...
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("\tat " + 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("\tat " + st);
            }
        }
    }
}

这篇关于如何从 RepaintManager 生成异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 09:52