【问题标题】:How to generate exceptions from RepaintManager如何从 RepaintManager 生成异常
【发布时间】:2011-10-16 23:09:52
【问题描述】:

关于我的question可能是),我发现了另一种我无法从SwingWorker 线程捕获和打印的异常类型。

如何生成RepaintManager 异常?

我阅读了Alexander PotochkinCheckThreadViolationRepaintManagerthis approach,但似乎没有任何问题可以解决我的问题。

【问题讨论】:

  • 你能澄清你的问题吗?谢谢/皮特
  • Pete _ I needed 生成总是在 EDT 上杀死 Swing GUI 的异常,这是我能够生成的异常之一,在 Window OS 中绘制速度最快,然后不再可能使用当前容器,那么为什么要生成这个异常,还有另一个异常,容器仍然存在,它的 JComponents 是可见的并且可以工作,我认为这不是 GPU 缺乏,因为我在虚拟环境和上得到了这个异常普通 PC 也是,我没有添加任何自定义容器,L&f 或 JComponents,每个都是普通的 JComponents
  • @mKorbel:Potochkin 博客页面似乎已经移动,所以我更新了answer 中的链接。很抱歉强加,但你有什么更好的吗?
  • @trashgod 谢谢,(AFAIK)没有比这更好的了

标签: java swing exception repaintmanager


【解决方案1】:

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

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 java.lang.ref.WeakReference;
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);
            }
        }
    }
}

【讨论】:

  • 我想我犯了一个类似的错误:认为it 是在抛出异常,而不是打印它们。
【解决方案2】:

创建自己的异常

class RepaintManagerException extends Exception
{
   String msg;

   RepaintManagerException()
   {
        msg = new String("type message here");
    }
}

用法

public class My_Exception
{
    public static void main (String args [ ])
    {
        try
        {
            // your code

            if (expression) throw new RepaintManagerException( );
        }
        catch (RepaintManagerException e)
        {
        System.out.println (e);
        }
    }
}

【讨论】:

  • 在查看他的另一个问题时,我认为这不是他想要的,但我可能错了,因为不是 100% 确定 mkorbel 的问题是什么。
  • @HovercraftFullOfEels:没错,但它很好地概括了approach 的工作原理。作为参考,建议问题的起源here:由于同步不正确导致的多个堆栈跟踪包括RepaintManager
  • @trashgod:谈论一个关于图书馆早已过时的爆炸
猜你喜欢
  • 2015-01-03
  • 2020-07-24
  • 1970-01-01
  • 2016-09-11
  • 2013-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多