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

问题描述

与我的(可能),我发现了另一种异常类型,我无法从 SwingWorker 线程中捕获并打印出来。

In connection with my question (may be), I found another exception type that I not able to catch and print-out from SwingWorker thread.

如何生成 RepaintManager 例外?

我读了这个和由 Alexander Potochkin ,但似乎没有解决我的问题。

I read this CheckThreadViolationRepaintManager and this approach by Alexander Potochkin, but nothing seems to solve my issues.

推荐答案

如果有帮助,下面的示例会打印多个变体o f以下异常,主要用于帧的UI委托初始化的每个阶段。我使用了,但 也很有趣。

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