그 이유는 update() 또는repaint()가 호출되는 경우 상위의 heavyweight ancestor로부터 paint()가 호출되며 하위 children의 paint()까지 호출하기 위해서였습니다.
이러한 구조가 Swing에와서는 더블버퍼링, UI delegate나 border의 지원 등을 위해서 구조가 변경되었고 swing에서의 paint() 메소드는 좀 더 세분화되게 되었습니다. 효율성과 확장성을 위해서 paint() 자체에 여러기능이 들어갔습니다.
예를 들면, java.awt.Container에서 하위 children까지 그리기 위한 부분이 paint()로 포함되었습니다. Swing에서는 paint()를 위해서는 paintComponent()를 사용하도록하고 있으며 좀더 많은 확장컴포넌트를 만들경우 paintChildren()이나 paintBorder()를 override하도록 하고 있습니다.
※ paint()와 paintComponent()가 잘정리되어 있는 사이트
http://java.sun.com/products/jfc/tsc/articles/painting/index.html#lw
※ 참고: 오역가능성 농후.. 책임못짐 ^^, 틀린내용있으면 말씀해주세요
AWT에 대한 설명이 틀리는 군.
답글삭제이보다 더 정확하게 정리해보면,
AWT heavy-weight 컴포넌트 구현의 대부분은 자바 자체의 페인팅, 이벤트 아키텍춰에 의한 것이 아니라 자바 외부의 시스템 컴포넌트 아키텍춰에 기반하여 자바가 빌붙어있는 형상이고, 각 AWT heavy-weight 컴포넌트는 시스템 컴포넌트이어서 개별 컴포넌트에 대한 paint 이벤트는 시스템에 의해 호출된다.
따라서, AWT heavy-weight 컴포넌트의 paint에서 자식 컴포넌트의 paint를 호출해줄 필요가 없다. (각자 따로따로 알아서 호출되니깐)
그러나,
스윙같은 가짜(혹은 가상)의 컴포넌트를 제공하려다 보니깐, 자체 컴포넌트/이벤트 아키텍춰를 따로 가져가야 했고, 하지만 AWT heavy-weight 컴포넌트 내부에 존재하기는 했으므로 기존 아키텍춰야 짬뽕 아키텍춰를 만들어야 했다.
그래서, 고민해서 수정한 것이 java.awt.Container의 paint 메소드에서는 자식 light-weight 컴포넌트 (스윙 컴포넌트 포함)의 paint도 호출하도록 정의한 것이다.
즉, java.awt.Comonent.paint()의 의미는 본래 자손 heavy-weight component가 아니라 바로 그 heavy-weight 컴포넌트를 완전하게 paint하는 것이고, light-weight 컴포넌트는 엄밀하게는 자손 heavy-weight 컴포넌트가 아니므로 이러한 관점에서는 그 의미가 변경된 것이 아니다.
단지, 2개의 서로 다른 개념의 아키텍춰가 짬뽕이 되다 보니 정의가 좀 헷갈려 보이는 것이다.
javax.swing.JComponent는 java.awt.Container의 하위 클래스로서 이러한 java.awt.Container의 paint forwaring semantics를 그대로 유지하기는 하지만, 더 정교하게 재정의하여, paintComponent, paintBorder, paintChildren을 호출하도록 한 것이다.
정리하자면, 이와 같이 heavy-weight, light-weight 컴포넌트의 painting 방식이 서로 달라보이는 근본적인 원인은 자바가 직접 제어권을 갖지 못해서 개별 컴포넌트가 외부의 이벤트 발생에 의존해 처리되는 방식과 외곽 AWT 컴포넌트에서 (JFrame등) 외부로부터 일단 이벤트를 받은 후에 그 이벤트를 실제로 처리해야 할 자손 스윙 컴포넌트로 스윙 아키텍춰에서 직접 forwarding시켜주어야 하는 방식의 차이에 기인하는 것이다.
말이 좀 어려운가...
그렇군요..Container가 heavy-weight component가 아니군요.
답글삭제it must translate that paint call to paint calls on all of its lightweight descendents. This is handled by java.awt.Container's paint() method , which calls paint() on any of its visible, lightweight children which intersect with the rectangle to be painted. So it's critical for all Container subclasses (lightweight or heavyweight) that override paint() to do the following