[자바/GUI] LayoutManager(BorderLayout, FlowLayout, GridLayout, CardLayout)으로 Component 배치 예제
언어/JAVA 2021. 4. 6. 23:22레이아웃 메니저(LayoutManager)
자바에서 컨테이너안에 버튼이나 체크박스 같은 컴포넌트를 보기좋게 배치하는 일은 쉬운 일이 아닙니다. 그럴때 레이아웃 메니저를 사용하면 됩니다. 레이아웃 메니저는 컨테이너가 컴포넌트를 어떻게 배치할 것인지를 도와주는 클래스들입니다. 여기서 소개서는 레이아웃 4개를 소개합니다. 그 4개가 BorderLayout, FlowLayout, GridLayout, CardLayout입니다. 이번 포스팅은 이 4개의 레이아웃 메니저에 대해 무슨 특징이 있고 어떻게 사용하면 되는 것인지 알아보도록 하겠습니다.
공통적으로 컨테이너에게 레이이웃 메니저를 적용시키려면 setLayout메소드로 사용할 LayoutManager를 지정해주시면 됩니다.
1. BorderLayout
BorderLayout은 컴포넌트를 동, 서, 남, 북, 중앙으로 배치시킵니다. 아래의 코드를 통해서 화면배치가 어떻게 이루어지는 지 확인해봅시다.
public class Main {
public static void main(String[] ar){
Frame frame=new Frame("Reakwon");
frame.setSize(500,300);
frame.setLayout(new BorderLayout());
Button eastButton=new Button("East");
Button westButton=new Button("West");
Button southButton=new Button("South");
Button northButton=new Button("North");
Button centerButton=new Button("Center");
frame.add("East",eastButton);
frame.add("West",westButton);
frame.add("South",southButton);
frame.add("North",northButton);
frame.add("Center",centerButton);
frame.setVisible(true);
}
}
Frame의 add()로 위치도 같이 지정해줍니다. add("위치", Component) 또는 add(Component, "위치")로 구분없이 사용할 수 있습니다. 이때 위치의 종류에는 "East", "West", "South", "North", "Center" 가 있는데, 각각은 동, 서, 남, 북, 가운데의 위치를 나타냅니다. 앞글자는 항상 대문자여야합니다.
Panel 사용하기 - 다른 Component를 더 배치
이렇게 버튼 5개만 추가하기보다는 가운데에 더 많은 Component를 결합하여 Frame을 구성하고 싶다면 어떻게하면 좋을까요? 이때 사용할 수 있는 것이 Panel입니다. Panel은 Frame과 같이 자신의 영역이 있어서 그 안에서 다른 Component를 구성할 수 있습니다. Panel은 두 종류가 있는데, 자신의 영역에서 담고 있는 컴포넌트들이 넘친다면 스크롤되지 않는 Panel과 스크롤될수 있는 ScrollPane이 있습니다. 여기서는 단순 Panel만을 사용하는 예를 보도록 하겠습니다.
public static void main(String[] ar){
Frame frame=new Frame("Reakwon");
frame.setSize(500,300);
frame.setLayout(new BorderLayout());
Button eastButton=new Button("East");
Button westButton=new Button("West");
Button southButton=new Button("South");
Button northButton=new Button("North");
//Panel의 Component 추가
Panel panel=new Panel(new BorderLayout());
Button panelSouth=new Button("Panel_South");
Button panelNorth=new Button("Panel_North");
Button panelCenter=new Button("Panel_Center");
panel.add("South",panelSouth);
panel.add("North",panelNorth);
panel.add("Center",panelCenter);
frame.add("East",eastButton);
frame.add("West",westButton);
frame.add("South",southButton);
frame.add("North",northButton);
//Center에 panel 추가
frame.add("Center",panel);
frame.setVisible(true);
}
Frame과 별 차이가 있나요? Frame과 같이 add로 버튼을 추가할 수 있습니다. 그리고 Frame은 그런 Panel을 추가할 수 있죠. 왜냐면 Panel 역시 Component이니까요. 다음 보이는 배치가 위 코드의 결과입니다.
간격 넓히기
BorderLayout의 생성자를 주어서 상하 좌우 간격을 조절 할 수 있습니다. 아래처럼 생성자를 이용하는 방법이 있습니다. 처음 arguement는 Horizontal(좌우)의 간격, 두번째는 Vertical(상하)의 간격입니다.
frame.setLayout(new BorderLayout(10,2));
생성자를 사용하지 않고 이미 생성된 객체에서 setHgap과 setVgap을 통해서도 바꿀 수 있습니다. 위의 생성자를 통한 간격은 아래의 메소드를 통한 간격 조정과 동일하게 됩니다.
BorderLayout layout=new BorderLayout();
layout.setHgap(10);
layout.setVgap(2);
frame.setLayout(layout);
어떻게 변하는지 볼까요?
2. FlowLayout
이름부터 직관적으로 알 수 있듯이 기본적으로 물 흐르듯 먼저 더해진 Component들이 왼족에서 오른쪽으로 추가되고 모두 가운데로 정렬이 되며 자리가 모자라면 아랫줄에 Component들이 배치됩니다. 아래와 같이 FlowLayout을 사용하여 Layout 배치를 해보도록 하겠습니다.
public class Main {
public static void main(String[] ar){
Frame frame=new Frame("Reakwon");
frame.setSize(500,300);
frame.setLayout(new FlowLayout());
for(int i=1;i<=10;i++) {
frame.add(new Button("Button"+i));
}
frame.setVisible(true);
}
}
setLayout으로 frame의 레이아웃을 FlowLayout으로 정하고 난 이후에 Frame에 버튼 10개를 추가해줍니다. 이런 Frame이 결과로 보여질겁니다.
왼쪽부터 차례대로 버튼이 추가되는 것을 알 수 있습니다. 이 프레임 사이즈를 줄여보세요. 자리가 모자르면 아래처럼 밑으로 버튼들이 내려가는 것을 확인할 수 있습니다.
정렬하는 방법에는 왼쪽정렬(FlowLayout.LEFT), 가운데 정렬(FlowLayout.CENTER), 오른쪽 정렬(FlowLayout.RIGHT)이 있고 간격도 역시 조정할 수 있습니다. 이 모든것은 생성자를 통해서도 가능하고 메소드를 통해서도 가능합니다. 간격 조정은 BorderLayout과 같고, 정렬하는 메소드는 setAlignment()를 이용하면 됩니다.
위의 코드에서 생성자를 이렇게 고쳐봅시다.
frame.setLayout(new FlowLayout(FlowLayout.RIGHT,10,20)); //오른쪽 정렬, 좌우 간격, 상하 간격
그러면 정렬과 간격이 변한것을 볼 수 있습니다.
3. GridLayout
격자형태의 Component를 배치하고 싶다면 GridLayout을 사용하시면 됩니다. 기본적으로 생성자에 아무것도 없다면 한 행에 컴포넌트를 배치합니다. 그래서 행과 열의 수를 지정하여 사용합니다.
GridLayout을 이용해서 Component를 배치해봅시다.
public static void main(String[] ar){
Frame frame=new Frame("Reakwon");
frame.setSize(500,300);
frame.setLayout(new GridLayout(4, 3, 10, 3)); //행, 열 , 좌우 간격, 상하 간격
for(int i=1;i<=9;i++) {
frame.add(new Button(""+i));
}
frame.add(new Button("*"));
frame.add(new Button("0"));
frame.add(new Button("#"));
frame.setVisible(true);
}
4행 3열의 격자 형태의 레이아웃을 사용했습니다. 그리고 좌우의 간격, 상하의 간격도 주어 Component를 떨어뜨렸지요. 보통 계산기 같은 버튼의 격자형 배치를 만들때 GridLayout이 많이 사용되며 사진의 격자형 배치고 GridLayout을 사용할 수 있습니다.
4. CardLayout
CardLayout은 카드를 겹쳐놓은듯이 배치하고 이전의 카드, 다음의 카드를 보여주듯 Component 또는 Container를 보여줍니다. 사용법은 아래와 같습니다.
public static void main(String[] ar){
Frame frame=new Frame("Reakwon");
frame.setSize(500,300);
Panel card1=new Panel();
card1.setBackground(Color.DARK_GRAY);
card1.add(new Label("Card 1"));
Panel card2=new Panel();
card2.setBackground(Color.ORANGE);
card2.add(new Label("Card 2"));
CardLayout layout=new CardLayout();
frame.setLayout(layout);
//card1의 이름은 "card1"
frame.add(card1, "card1");
//card2의 이름은 "card2"
frame.add(card2, "card2");
layout.show(frame, "card1");
frame.setVisible(true);
//5초 대기
try {
Thread.sleep(5000);
}catch(InterruptedException e) {
e.printStackTrace();
}
//5초 후 frame에 추가한 다음 card를 보여줌
layout.next(frame);
}
여기에는 Panel을 두개 사용하여 card1과 card2라는 변수로 이름을 정해줍니다. 이 둘을 구분하기 위해서 배경색과 이름을 보여주는 Label을 추가했습니다. Frame은 CardLayout으로 세팅하는데, 여기서 객체를 계속사용해야하니까 객체를 생성하여 setLayout의 인자로 전달해줍니다. 그리고 차례대로 card1, card2를 Frame에 추가하죠. 이제 가장 처음 보여야할 container를 정하는데 show()메소드를 이용합니다.
그럼 현재 보이는 것은 card1입니다. 그리고 5초를 기다린 후 next() 메소드로 카드를 다음 것으로 바꿔줍니다. CardLayout은 메소드에 Container를 전달해줘야하는데, CardLayout이 설정된 Container를 전달하면 되는데 여기서는 frame이라는 개체가 그 Container입니다. 이 밖에도 처음, 마지막의 카드로 바꿔줄때는 아래와 같이 사용하면 됩니다.
layout.first(frame);
layout.last(frame);
우리가 구현한 위 코드의 결과는 아래처럼 처음 보이는 것은 card1입니다.
이후에 5초가 흐르면 card2 패널로 바뀌죠.
아직은 Event에 대해서 자세히 배우지 않았기 때문에 Thread를 잠시 sleep 시킨후 다음 카드로 변경했는데, Event를 배우면 버튼과 이것 저것을 합쳐서 Card를 바꿀 수 있습니다.
이처럼 JAVA AWT에서 사용하는 LayoutManager에 대한 기본적인 개념과 사용법을 알아보았습니다. 어려운 개념이 있었나요? 우리는 LayoutManager를 사용하여 Component를 효율적으로 그리고 쉽게 배치할 수 있습니다. 이 LayoutManager들은 Swing에서도 그대로 사용됩니다.
'언어 > JAVA' 카테고리의 다른 글
[자바] Scanner를 이용한 입력 쉽게 받는 방법 - System, 문자열, 파일에서 입력 받기 (3) | 2021.04.07 |
---|---|
[자바] 직렬화(Serialization)의 개념과 객체 파일로 저장하기 예제 - ObjectOutputStream, ObjectInputStream (4) | 2021.04.07 |
[자바/GUI] AWT(Abstract Window Toolkit)의 기초 - Frame 클래스 (0) | 2021.04.06 |
[자바] MessageFormat - DB query같은 메시지 형식 구현 (0) | 2021.04.06 |
[JAVA] 10진수 형식 클래스(DecimalFormat) - 세자리마다 쉼표, 소수점, 지수 나타내기 (0) | 2021.04.05 |