컨테이너와 배치
u 컨테이너의 이해
Ø 컨테이너는 자신의 영역 안에 다른 컴포넌트를 포함할 수 있는 컴포넌트를 의미한다.
Ø 컨테이너는 그 자신만으로는 특별한 동작을 할 수 없고, 다른 컴포넌트를 포함할 때만 의미가 있다. 컨테이너 그 자체도 컴포넌트로 취급되며 다른 컨테이너에 부탁될 수 있다.
Ø Panel : 다른 컨테이너에 부착되어 일부 영역을 컨트롤 하는데 많이 사용된다.
Ø Dialog : 대화창에서 주로 사용되는 컨테이너이다.
Ø Applet 과 Frame 은 대표적인 최상위 컨테이너로써 다른 컨테이너를 포함한 맨 바깥쪽 컨테이너를 의미한다.
u 컨테이너의 사용
컨테이너 |
설명 |
Window
컨테이너 |
최상위 윈도우를 제공하는 컨테이너, Frame Dialog 컨테이너가 주로 대신 사용됨
메소드 이름 |
기능 |
void pack() |
배치 관리자를 실행시켜서 포함된 컴포넌트의 배치를 시작하고, 윈도우의 크기를 조절함 |
void show() |
윈도우를 화면에 나타나게 하며 윈도우 중에 가장 맨 상단에 나타나게 한다. |
void dispose() |
다 사용한 윈도우 리소스를 해제시킨다. |
|
Frame
컨테이너 |
다른 컨테이너와 마찬가지로 add() 메소드를 사용. 배치 요구.
Frame 클래스 생성 후 setSize() 또는 setBounds() 메소드를 이용해서 크기를 꼭 정해줘야 하며 하부 컴포넌트 배치를 위해 pack() 메소드를 호출하고 마지막으로 setVisible(true) 메소드를 통해 화면에 표시해야 한다.
코드 및 예는 표 하부를 참조할 것 |
Panel
컨테이너 |
Applet과 Frame 클래스가 가장 바깥쪽의 컨테이너 역할을 하는데 반해, Panel 클래스는 컴포넌트들을 그룹별로 모을 때 주로 사용한다. 보통 GUI를 설계할 때 컴포넌트를 독립적으로 Applet과 Frame에 바로 붙이기 보다는 Panel 클래스에 그룹별로 붙이고 패널 클래스들을 배치하는 경우가 대부분이다.
코드 및 예는 표 하부를 참조할 것 |
Applet
컨테이너 |
Applet 클래스는 16장에서 살펴본다.
setSize(), setBounds() 메소드를 해 주어도 원하는 크기대로 웹 브라우저에서 나타나지 않는 경우가 있다. 왜냐면 브라우저의 종류에 따라서 조금씩 차이가 있기 때문에 직접적인 메소드보다는 HTML 태그의 사이즈 부분에 값을 주는 것이 바람직하다. |
Dialog
컨테이너 |
팝업 윈도우의 형태로 메인 윈도우 외에 따로 메시지를 출력하거나, 사용자의 입력을 받을 때 주로 사용되는 컨테이너다.
생성자를 알아보자
형태 |
기능 |
Dialog(Frame owner)
Dialog(Dialog owner) |
기본 생성자. |
Dialog(Dialog owner, String title)
Dialog(Frame owner, String title) |
Dialog에 타이틀에 추가 |
Dialog(Dialog owner, String title, boolean modal)
Dialog(Frame owner, String title, boolean modal) |
해당 Dialog를 모달(Modal)로 할 것인지의 여부를 지정함, 모달이란 Dialog가 활성화되어 있을 때는 다른 윈도우를 선택할 수 없는 기능임 |
Dialog(Frame owner, boolean modal) |
상위 컨테이너가 Frame인 경우의 생성자 |
생성과정
① Dialog 클래스 상속 : 상속을 통해서 개발자가 새로운 대화창을 만든다.
② super() 를 이용하여 생성자 호출
③ setVisible() 메소드 호출
코드 및 사용 예는 표 하부를 참조할 것 |
Ø Frame 컨테이너 사용 예
import java.awt.*;
public class FrameTest {
public static void main(String args[]){
Frame f = new Frame("테스트 프레임"); // 프레임 생성
Label l = new Label("5초 후에 없어지는 프레임");
f.add(l);
f.setBounds(10, 10, 300, 200); //크기 위치 셋팅
f.setVisible(true); // 화면에 나타낸다.
try{
Thread.sleep(5*1000);
}catch(InterruptedException e){}
f.setVisible(false);
f.dispose(); // 자원을 해제한다.
}
} |
<실행결과>

|
Ø Panel 컨테이너 사용 예
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class PanelTest extends Applet implements ActionListener{
Panel panel1, panel2;
Button button1, button2, button3, button4;
public void init(){
panel1 = new Panel();
panel2 = new Panel();
panel1.setBackground(Color.red);
panel2.setBackground(Color.yellow);
add(panel1);
add(panel2);
button1 = new Button("패널 2 보이기");
button2 = new Button("패널 2 안보이기");
button3 = new Button("패널 1 보이기");
button4 = new Button("패널 1 안보이기");
button1.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);
button4.addActionListener(this);
panel1.add(button1);
panel1.add(button2);
panel2.add(button3);
panel2.add(button4);
}
// 버튼이 눌리면 actionPerformed() 메소드가 호출된다.
public void actionPerformed(ActionEvent ae){
Button b = (Button)ae.getSource();
String label = b.getLabel();
if(label.equals("패널 1 보이기"))
panel1.setVisible(true);
else if(label.equals("패널 1 안보이기"))
panel1.setVisible(false);
else if(label.equals("패널 2 보이기"))
panel2.setVisible(true);
else
panel2.setVisible(false);
}
} |
<실행결과>

|
Ø Dialog 컨테이너 사용 예
<Notification.java>
import java.awt.*;
import java.awt.event.*;
class Notification extends Dialog implements ActionListener{
String msg;
public Notification(Frame f, String s){
super(f,"주목",true);
msg = s;
}
public void disp(){
Button b;
add("North", new Label(msg,Label.CENTER));
b = new Button("OK");
b.addActionListener(this);
Panel p = new Panel();
p.add(b);
add("South", p);
setBackground(Color.gray);
setSize(160,100);
setVisible(true);
}
public void actionPerformed(ActionEvent e){
dispose();
}
}
<TestDialog.java>
import java.awt.*;
import java.awt.event.*;
class TestDialog extends Frame implements ActionListener{
Notification n;
public TestDialog(){
super("다이얼로그를 테스트합니다.");
n = new Notification(this,"다이얼로그가 보입니다");
Panel p = new Panel();
Button b1 = new Button("다이얼로그 열기");
b1.addActionListener(this);
p.add(b1);
add(p);
setSize(300,150);
setVisible(true);
}
public void actionPerformed(ActionEvent e){
n.disp();
}
public static void main(String args[]){
TestDialog t = new TestDialog();
}
} |
<실행결과>

|
u 배치에 대한 이해
Ø 문제 분석 : GUI에서 화면을 구성하기 위해서는 컴포넌트의 위치를 좌표로 지정해 주었다. 다른 운용체제에서 절대 좌표를 입력하면 다르게 표시되어 원하는 모습이 나오지 않는다. 또한 컨테이너의 사이즈를 재조정하면 그 안에 들어 있는 컴포넌트의 위치가 제각각 변하기 때문에 배치 개념이 나옴
Ø 문제 해결 : 플랫폼 독립성의 특징을 이용해 컴포넌트의 배치를 배치 관리자(Layout Manager)라는 것을 이용하여 처리하도록 한다. 배치 관리자는 LayoutManager 인터페이스를 반드시 구현하도록 되어 있는데 이 배치 관리자를 통해 컴포넌트를 영역에 배치한다.
Ø 컨테이너가 배치 관리자에게 컴포넌트를 배치하는 것을 요청하면 컴포넌트 간의 간격이나 컴포넌트의 크기 등의 윈도우 시스템에 종속적인 값을 배치 관리자가 하위 윈도우 시스템에 가장 적합한 값으로 매핑해서 화면에 보여준다.
Ø 디폴트 배치 관리자
컨테이너 |
배치 관리자 |
Applet, Panel |
FlowLayout |
Window, Frame, Dialog |
BorderLayout |
Ø 자바의 컨테이너가 배치 관리자를 사용하기 위한 절차
① 필요한 배치를 지원하는 배치 관리자 클래스 객체를 생성
② 배치 관리자 클래스를 컴포넌트의 setLayout() 메소드를 이용하여 컨테이너에 설정
③ 이후 add() 메소드로 추가되는 컴포넌트는 설정된 배치 관리자 클래스에 |
u Flow 레이아웃
Ø 컨테이너에 주어진 컴포넌트를 왼쪽에서 오른쪽으로, 위에서 아래쪽으로 순차적으로 쭉 배열한다.
Ø 배치시 주의점은 컴포넌트가 지정한 크기를 무시하고 각 컴포넌트에 필요한 최소한의 높이와 위치, 간격이 자동적으로 지정되어 배치된다.
Ø 코드는 생략하고 실행결과와 특징변화의 예시를 보자.
<실행결과>
(기본모습) (옆으로 윈도우를 늘렸을 때)

|
u Border 레이아웃
Ø 각 배치에는 “North”, “East”, “South”, “West”, “Center”의 이름이 붙어 있다.
Ø 각 이름은 컴포넌트를 컨테이너에 포함시킬 때, 같이 주어지며 이에 의해서 컴포넌트가 포함되는 위치가 정해진다.
Ø 소스 코드 및 실행 결과
import java.awt.*;
public class BorderTest extends Frame{
public static void main(String args[]){
BorderTest f = new BorderTest();
f.setLayout(new BorderLayout());
f.add("North", new Button("첫번째"));
f.add("East", new Button("두번째"));
f.add("West", new Button("세번째"));
f.add("South", new Button("네번째"));
f.add("Center", new Button("다섯번째"));
f.setSize(300,300);
f.setVisible(true);
}
} |
<실행결과>

|
u Grid 레이아웃
Ø 그리드 레이아웃은 생성할 때 컬럼수와 라인수를 지정한다.
Ø 레이아웃에서는 배치되는 컴포넌트의 크기와 상관없이 각 셀의 크기와 고정적이기 때문에 컴포넌트의 사이즈가 완전히 무시된다. 컴포넌트를 추가하면 좌측에서 우측으로, 상단에서 하단의 순서대로 컴포넌트가 추가된다.
Ø 소스 코드 및 실행 결과
import java.awt.*;
public class GridTest extends Frame{
public static void main(String args[]){
GridTest f = new GridTest();
f.setLayout(new GridLayout(3,2));
f.add("North", new Button("첫번째"));
f.add("East", new Button("두번째"));
f.add("West", new Button("세번째"));
f.add("South", new Button("네번째"));
f.add("Center", new Button("다섯번째"));
f.setSize(300,300);
f.setVisible(true);
}
} |
<실행결과>

|
u Card 레이아웃
Ø 카드를 포개어 놓은 듯한 레이아웃 형태로서 포개 놓으면 맨 위의 카드밖에는 볼 수 없듯이 이 배치 관리자를 쓰면 한번에 하나의 컴포넌트밖에는 볼 수 없다.
Ø 소스 코드 및 실행결과
import java.awt.*;
import java.awt.event.*;
public class CardTest extends Frame implements ActionListener{
CardLayout cl;
public static void main(String args[]){
CardTest f = new CardTest();
Button b;
f.cl = new CardLayout();
f.setLayout(f.cl);
b = new Button("첫번째");
b.addActionListener(f);
f.add("1,", b);
b = new Button("두번째");
b.addActionListener(f);
f.add("2,", b);
b = new Button("세번째");
b.addActionListener(f);
f.add("3,", b);
b = new Button("네번째");
b.addActionListener(f);
f.add("4,", b);
b = new Button("다섯번째");
b.addActionListener(f);
f.add("5,", b);
f.setSize(300,300);
f.setVisible(true);
}
public void actionPerformed(ActionEvent e){
cl.next(this);
}
} |
<실행결과>
(첫 화면) (첫 화면 클릭 후 두번째 화면)

|
u GridBag 레이아웃
Ø 지정된 사이즈를 좌표를 이용해 영역 구분을 해준다.
Ø 소스 코드 및 실행 결과
import java.awt.*;
import java.util.*;
public class GridBagTest extends Panel{
GridBagConstraints c;
public GridBagTest(){
GridBagLayout gridbag = new GridBagLayout();
setLayout(gridbag);
setBackground(Color.red);
c = new GridBagConstraints();
c.weightx = 1.0;
c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
layout(new Button("첫번째"), 0,0,1,2);
layout(new Button("두번째"), 2,0,2,1);
layout(new Button("세번째"), 1,1,1,1);
layout(new Button("네번째"), 2,1,1,1);
}
public void layout(Component obj, int x, int y, int width, int height){
c.gridx = x;
c.gridy = y;
c.gridwidth = width;
c.gridheight = height;
add(obj, c);
}
public static void main(String args[]){
Frame test = new Frame();
test.setSize(300,300);
test.add(new GridBagTest());
test.setVisible(true);
}
} |
<실행결과>

|
출처 : Tong - winshwin님의 + [JAVA/JSP]통