자바에서 Swing을 사용할때 별 생각없이 만들다 보면,
EDT가 아닌곳에서 Swing Component에 대한 작업을 많이 하려고 한다.

다른 Thread에서 Swing Component에 대해서 어떠한 작업을 했을때,
dead lock이 일어나기 전에는,
어느곳에서 그런것을 썼는지 일일이 알아 내기가 힘들다.

Print 관련 자료를 찾다가 TroubleshootingGuide for Java를 발견해서
살짝 보았는데 참고해 두고 담에 체크할때 먹으면 좋아 보여서 긁어 놓는다.

TroubleshootingGuide for Java SE 6DesktopTechnologies
http://java.sun.com/javase/6/webnotes/trouble/TSG-Desktop/TSG-Desktop.pdf

4.2.1 IncorrectThreading
Randomexceptions and painting problems are usually the result of incorrect threading usage of Swing. All access to Swing components, unless speciically noted in the javadoc,must be done on the event dispatch thread. This includes anymodels (TableModel, ListModel, and others) that are attached to Swing components.

The best way to check for bad usage of Swing is by way of an instrumented RepaintManager,as illustrated by the following code:

public class CheckThreadViolationRepaintManager extends RepaintManager {

    // it is recommended to pass the complete check
    private boolean completeCheck = true;

    public boolean isCompleteCheck() {
        return completeCheck;
    }

    public void setCompleteCheck(boolean completeCheck) {
        this.completeCheck = completeCheck;
    }

    public synchronized void addInvalidComponent(JComponent component) {
        checkThreadViolations(component);
        super.addInvalidComponent(component);
    }

    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())) {

            Exception exception = new Exception();
            boolean repaint = false;
            boolean fromSwing = false;
            StackTraceElement[] stackTrace = exception.getStackTrace();

            for (StackTraceElement st : stackTrace) {
                if (repaint && st.getClassName().startsWith("javax.swing.")) {
                    fromSwing = true;
                }
                if ("repaint".equals(st.getMethodName())) {
                    repaint = true;
                }
            }

            if (repaint && !fromSwing) {
                //no problems here, since repaint() is thread safe
                return;
            }

            exception.printStackTrace();
        }
    }
}
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
  1. 무적조로™ 2008.11.05 12:59 신고

    어떤 내용인지 감이 잘 안잡힌다 ㅋㅋ
    다시 자세히 설명 좀 해보삼..

    • Chan 2008.11.08 00:55 신고

      뭐.. ㅎㅎ 굳이 깊이 알 필요는 없는.. ㅎㅎ
      알아두면 좋은거고. ㅎㅎ

      1. Swing에서 무언가 작업을 할때에는 EDT에서 해야 한다.
      2. 스윙에서 무슨 작업을 하고나면 보통 repaint를 호출하거나, 혹은 호출이 되는데
      3. 이때 만약 EDT가 아닌 Thread에서 호출하게 되면, 에러를 출력하는 코드

      정도 되는것 같은데. ㅎㅎ

      아직 한번도 안써봐서 ^^;;

+ Recent posts