기존의 J2SE에서는 탑 레벨 Swing 컨테이너인 JFrame, JDialog, JWindow, JApplet, JInternalFrame에 직접적으로 컴포넌트를 추가하는 일이 불가능했었다. 예를 들어 myFrame이라는 이름의 JFrame 인스턴스가 있고, 이 JFrame에 someComponent이라는 이름의 컴포넌트를 추가하고 싶다면, 이를 위해 JFrame의 메서드인 getContentPane를 호출해야했었다.
myFrame.getContentPane().add(someComponent).
J2SE 5.0에서는 탑 레벨 Swing 컨테이너에 컴포넌트를 추가할 수 있으며, 레이아웃 매니저를 직접 설정하여 컨테이너에서 컴포넌트를 제거할 수도 있다. 이번 테크팁에서는 getContentPane()를 호출하지 않고도 add(), setLayout(), remove()를 직접 사용할 수 있게 된 탑 레벨 컨테이너들의 변화에 대해서 알아보자. 또한 이제 더 이상 컴포넌트를 추가하기 위해 ContentPane를 호출하지 않아도 되지만 이를 무시할 수는 없는 이유에 대해서도 알아보고자 한다.
J2SE 1.4와 그 이전 버전의 상황에 대해서 먼저 알아보자. JFrame 에 LayoutManager를 설치하고 다양한 컴포넌트를 추가하고 싶다고 가정하자. JFrame에 대한 문서를 보면 JFrame은 java.awt.Container의 add() 메서드를 상속받는다는 것을 알 수 있을 것이다. 이 add() 메서드는 JFrame 컨테이너에 컴포넌트를 추가하기 위해 사용된다. Container클래스에는 또한 setLayout() 메서드가 포함되어 있으며 이 메서드는 주어진 컨테이너를 위한 레이아웃 매니저를 지정한다. Java 초보자들은 보통 다음의 프로그램이 컴파일되고 완전하게 구동될 것이라고 여기기 쉽다.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.GridLayout;
import java.awt.Color;
public class FrameTest extends JFrame {
//Warning - this version is not correct for J2SE 1.4
// it works fine with J2SE 5.0
FrameTest(){
super("Test Frame");
setBackground(Color.BLACK);
setLayout(new GridLayout(7,7,2,2)); // problem 1
for ( int i=0;i<49; i++){
JPanel jPanel = new JPanel();
jPanel.setBackground(new Color (
(int)(Math.random()*16777215)));
add(jPanel); // problem 2
}
setSize(400,400);
setVisible(true);
}
public static void main(String[] args){
new FrameTest();
}
}
이 코드는 J2SE 5.0에서는 컴파일되고 구동된다. J2SE 1.4에서도 컴파일은 되지만 코드를 구동하는 데에는 문제가 생긴다. 문제점 1, 2라고 표시된 라인들이 JFrame 의 setLayout()와 add()메서드에 호출된 것이다. 이 코드를 컴파일하고 J2SE 1.4에 구동시킨다면 다음과 같은 런타임 예외상황에 부닥치게 될 것이다.
Exception in thread "main" java.lang.Error: Do not use
FrameTest.setLayout()
use FrameTest.getContentPane().setLayout() instead
at
javax.swing.JFrame.createRootPaneException(JFrame.java:465)
at javax.swing.JFrame.setLayout(JFrame.java:531)
at FrameTest.<init>(FrameTest.java:11)
at FrameTest.main(FrameTest.java:23)
예외사항에 제시된 어드바이스를 따라 위에서 "problem 1"이라고 붙여진 setLayout 라인을 다음과 같이 교체하면,
getContentPane().setLayout(new GridLayout(7,7,2,2));
또 그 후 J2SE 1.4의 FrameTest를 다시 컴파일하고 재구동 시키면, 두번째 런타임 예외상황을 얻게 될 것이다. 이 두번째 예외상황은 "problem 2"이라고 붙여진 add(jPanel) line을 다음의 라인으로 교체하면 고칠 수 있게 된다.
getContentPane().add(jPanel);
J2SE 1.4의 FrameTest을 재컴파일하고 구동시켜보자. 가로세로 7칸의 바둑판 모양으로 서로 다른 색의 JPanel들을 포함하는 JFrame이 나타난다.

앞의 예제에서와 같이 J2SE 5.0 이전 버전에서는 getContentPane() 을 명확하게 호출한 후 getContentPane() 에 의해 리턴된 Container 오브젝트의 add() 또는 setLayout()를 호출해야했다. J2SE 5.0에서는 Container 오브젝트에서 직접 add() 또는 setLayout()를 호출할 수 있다. 예를 들어 myFrame이 JFrame의 인스턴스라고 할 때 myFrame.getContentPane().add()를 좀 더 간단한 myFrame.add()로 교체할 수 있다. add()의 구현이 사실상 this.getContentPane().add()의 구현이라는 것을 기억한다면 좀 더 이해하기 쉬울 것이다. setLayout() 와 remove()의 경우에도 같은 것이 적용된다. 뿐만 아니라 모든 탑 레벨의 Swing 컴포넌트, JFrame, JDialog, JWindow, JApplet, JInternalFrame에 적용된다.
J2SE 5.0을 이용하여 FrameTest의 오리지날 버전을 컴파일하고 구동하자. 또 다시 바둑판 모양으로 된 49개의 JPanel을 볼 수 있을 것이다. JPanel의 배경 색이 랜덤으로 지정되기 때문에 이 구동에서의 JPanel들의 색은 이전에 구동했을 때와는 다를 것이다.

아마도 미묘한 문제점을 눈치챘을 것이다. FrameTest 프로그램에서의 다음 라인이 아무 효과도 갖지 않은 것처럼 보인다.
setBackground(Color.BLACK);
JFrame의 배경색이 검정색이기 때문에 각 JPanel들 사이의 선들이 회색이 아닌 검정색이 될 것이라고 생각했겠지만 보통은 그렇게 보이지 않는다. 컨텐츠의 구획이 검정색인 부분의 위에 위치하기 때문이다. JFrame를 리사이징하면 순간적으로 검정색 배경을 볼 수 있을 것이다. FrameTest 프로그램의 setBackground 라인을 다음과 같이 변경시켜보자.
getContentPane().setBackground(Color.BLACK);
이제 바둑판의 선이 검정색으로 보인다.

이 문제에 대해 주의를 기울이는 이유는 Jframe의 add(), remove(), setLayout()를 이용할 때 비록 getContentPane()의 호출이 필요하지 않는다 하더라도 이를 리사이징 할 때는 도움이 되기 때문이다. 따라서 ContentPane의 역할을 무시할 수는 없다.
"Java SE" 카테고리의 다른 글
- JSSE 이용한 안전한 커뮤니케이션 (댓글 2개 / 트랙백 0개) 2004/08/31
- 3D 화면(scene)에 빛 효과 주기 (댓글 1개 / 트랙백 0개) 2004/07/30
- Java SE & Java SE for Business 지원 로드맵 (댓글 0개 / 트랙백 0개) 2009/09/11
- 클래스에서 enhanced For-Loop 사용 (댓글 0개 / 트랙백 1개) 2007/10/09
- VARIABLE CONTENT로 메세지 포맷하기 (댓글 7개 / 트랙백 2개) 2003/08/19
- CONTENTPANE 작업의 변화 (댓글 1개 / 트랙백 0개) 2004/11/11
- 새로운 포매터로 출력물 포맷하기 (댓글 1개 / 트랙백 0개) 2004/10/27
- 스윙 유저 인터페이스에서 컴포넌트의 방향성 (댓글 2개 / 트랙백 0개) 2003/09/26
- 쓰레드의 상태정보를 저장할 때 사용되는 THREADLOCAL 변수들 (댓글 4개 / 트랙백 0개) 2003/12/12
- 2개의 스트링이 같은 경우는? (댓글 2개 / 트랙백 0개) 2004/05/27
댓글을 달아 주세요
좋은 정보 감사해요~
2007/09/19 05:37