레이아웃 매니저(Layout Manager)는 컨테이너 안에 포함된 컴포넌트들의 크기와 위치를 결정하여, GUI 화면에서 시각적 요소들이 어떻게 배치될지 제어할 수 있도록 도와주는 핵심 도구입니다.
LayoutManager의 종류
자바에서는 기본적으로 6가지 레이아웃 매니저를 제공합니다.
- FlowLayout (플로우 레이아웃): 컴포넌트를 마치 페이지 위의 단어처럼 배치하는 방식입니다. 왼쪽에서 오른쪽으로, 그리고 위에서 아래로 순서대로 채워 나가며, 컴포넌트는 추가된 순서대로 배치됩니다. 즉, 첫 번째 컴포넌트가 좌측 상단에 나타나고, 컨테이너의 폭이 충분하지 않으면 다음 줄로 자동으로 넘어갑니다. 컴포넌트 사이의 수평·수직 간격을 조절할 수 있으며, 전체 배치를 왼쪽, 가운데, 오른쪽으로 정렬할 수도 있습니다.
- BorderLayout (보더 레이아웃): 모든 컴포넌트를 컨테이너의 가장자리나 중앙에 배치하는 방식입니다. 영역은 상단(North), 하단(South), 좌측(West), 우측(East), 중앙(Center)으로 나뉩니다. 상단이나 하단에 추가된 컴포넌트는 선호하는 높이를 유지하지만 폭은 컨테이너 전체 폭이 되고, 좌우에 추가된 컴포넌트는 선호하는 폭을 유지하되 높이는 컨테이너의 남은 높이만큼 차지합니다. 중앙에 추가된 컴포넌트는 선호 크기를 유지하지 못하고 컨테이너의 나머지 영역 전체를 채우게 됩니다.
- GridLayout (그리드 레이아웃): 모든 컴포넌트를 동일한 크기의 셀로 구성된 격자에 배치하는 방식입니다. 컴포넌트는 왼쪽에서 오른쪽으로, 위에서 아래로 순서대로 추가되며, 하나의 셀에는 하나의 컴포넌트만 배치할 수 있습니다. 컨테이너의 크기가 조절되면 모든 셀의 크기도 자동으로 함께 조절되며, 컴포넌트가 배치되는 순서는 추가된 순서에 따라 결정됩니다.
- GridBagLayout (그리드백 레이아웃): 가장 강력하고 유연한 레이아웃입니다. 컴포넌트를 격자 형태로 배치하면서도 컨테이너의 크기가 변할 때 객체의 가로세로 비율(aspect ratio)을 유지할 수 있습니다. 각 셀의 크기를 서로 다르게 설정할 수 있으며, 컴포넌트 사이에 일관된 수평·수직 간격을 부여하고, 열이나 행 안에서 컴포넌트의 기본 정렬 방식을 지정할 수도 있습니다.
- BoxLayout (박스 레이아웃): 여러 개의 컴포넌트를 세로 또는 가로 방향 중 한 방향으로만 배치하는 방식입니다. 컴포넌트는 왼쪽에서 오른쪽으로 또는 위에서 아래로 정렬되며, 가로 정렬일 경우 모든 컴포넌트의 높이가 가장 큰 컴포넌트의 높이와 같아지고, 세로 정렬일 경우 모든 컴포넌트의 폭이 가장 넓은 컴포넌트의 폭과 같아집니다.
- CardLayout (카드 레이아웃): 두 개 이상의 동일한 크기를 가진 컴포넌트를 관리하는 방식입니다. 컴포넌트들은 마치 카드 덱처럼 겹쳐서 배치되며, 모든 카드의 크기는 같지만 언제나 맨 위의 카드 하나만 화면에 표시됩니다. 컨테이너에 가장 먼저 추가된 컴포넌트가 덱의 맨 위에 놓이며, 좌우상하 기본 여백은 0입니다.
예제 코드
아래 예제는 JFrame에 BorderLayout을 적용하고, 그 안에 FlowLayout과 GridLayout을 조합하여 활용하는 방법을 보여줍니다.
import java.awt.*;
import javax.swing.*;
public class LayoutManagerTest extends JFrame {
JPanel flowLayoutPanel1, flowLayoutPanel2, gridLayoutPanel1, gridLayoutPanel2, gridLayoutPanel3;
JButton one, two, three, four, five, six;
JLabel bottom, lbl1, lbl2, lbl3;
public LayoutManagerTest() {
setTitle("LayoutManager Test");
setLayout(new BorderLayout()); // JFrame에 BorderLayout 설정
flowLayoutPanel1 = new JPanel();
one = new JButton("One");
two = new JButton("Two");
three = new JButton("Three");
flowLayoutPanel1.setLayout(new FlowLayout(FlowLayout.CENTER)); // FlowLayout 설정
flowLayoutPanel1.add(one);
flowLayoutPanel1.add(two);
flowLayoutPanel1.add(three);
flowLayoutPanel2 = new JPanel();
bottom = new JLabel("This is South");
flowLayoutPanel2.setLayout(new FlowLayout(FlowLayout.CENTER)); // FlowLayout 설정
flowLayoutPanel2.add(bottom);
gridLayoutPanel1 = new JPanel();
gridLayoutPanel2 = new JPanel();
gridLayoutPanel3 = new JPanel();
lbl1 = new JLabel("One");
lbl2 = new JLabel("Two");
lbl3 = new JLabel("Three");
four = new JButton("Four");
five = new JButton("Five");
six = new JButton("Six");
gridLayoutPanel2.setLayout(new GridLayout(1, 3, 5, 5)); // GridLayout 설정
gridLayoutPanel2.add(lbl1);
gridLayoutPanel2.add(lbl2);
gridLayoutPanel2.add(lbl3);
gridLayoutPanel3.setLayout(new GridLayout(3, 1, 5, 5)); // GridLayout 설정
gridLayoutPanel3.add(four);
gridLayoutPanel3.add(five);
gridLayoutPanel3.add(six);
gridLayoutPanel1.setLayout(new GridLayout(2, 1)); // GridLayout 설정
gridLayoutPanel1.add(gridLayoutPanel2);
gridLayoutPanel1.add(gridLayoutPanel3);
add(flowLayoutPanel1, BorderLayout.NORTH);
add(flowLayoutPanel2, BorderLayout.SOUTH);
add(gridLayoutPanel1, BorderLayout.CENTER);
setSize(400, 325);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String args[]) {
new LayoutManagerTest();
}
}
실행 결과
위 코드를 실행하면 상단에는 버튼 3개가 가로로 나열된 FlowLayout 패널이, 하단에는 라벨이 표시되며, 중앙에는 라벨 3개와 버튼 3개가 GridLayout으로 정렬된 결과를 확인할 수 있습니다.
