Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java GridBagConstraints 클래스의 중요성과 핵심 속성 완벽 가이드

GridBagLayout은 Java AWT/Swing에서 제공하는 매우 유연한 레이아웃 관리자로, 제약 조건(constraints)을 사용하여 컴포넌트들을 서로 상대적으로 배치할 수 있게 해줍니다. 각 GridBagLayout은 동적 사각형 셀 그리드를 사용하며, 각 컴포넌트는 하나 이상의 셀을 차지하는데 이를 해당 컴포넌트의 '표시 영역(display area)'이라고 합니다. GridBagLayout이 관리하는 모든 컴포넌트는 GridBagConstraints 인스턴스와 연결되어 있으며, 이 인스턴스는 컴포넌트가 자신의 표시 영역 내에서 어떻게 배치될지를 결정합니다.

GridBagConstraints란?

GridBagConstraints 객체는 public 인스턴스 변수 중 하나 이상을 설정함으로써 자유롭게 커스터마이징할 수 있습니다. 이러한 변수들은 컴포넌트의 위치, 크기, 확장 비율(growth factor), 앵커(anchor), 여백(inset), 채우기(fill), 패딩(padding) 등을 지정합니다.

  • gridx: int 값으로, 컴포넌트가 차지하는 가장 왼쪽 셀을 지정합니다. 즉, 컴포넌트가 배치될 열(column)을 결정합니다.
  • gridy: int 값으로, 컴포넌트가 차지하는 가장 위쪽 셀을 지정합니다. 즉, 컴포넌트가 배치될 행(row)을 결정합니다.
  • gridheight: int 값으로, 컴포넌트가 세로 방향으로 차지하는 셀의 개수를 지정합니다.
  • gridwidth: int 값으로, 컴포넌트가 가로 방향으로 차지하는 셀의 개수를 지정합니다.
  • ipadx: int 값으로, 각 컴포넌트에 추가되는 내부 가로 패딩의 크기를 지정합니다.
  • ipady: int 값으로, 각 컴포넌트에 추가되는 내부 세로 패딩의 크기를 지정합니다.
  • insets: Insets 객체로, 셀의 각 변에 남겨둘 빈 공간(외부 여백)의 크기를 지정합니다.
  • weightx: double 값으로, 결과 레이아웃이 할당된 영역보다 가로 방향으로 작을 경우 남는 가로 공간을 어떻게 분배할지 지정합니다.
  • weighty: double 값으로, 결과 레이아웃이 할당된 영역보다 세로 방향으로 작을 경우 남는 세로 공간을 어떻게 분배할지 지정합니다.
  • anchor: int 값으로, 셀 안에서 컴포넌트의 정렬 방식을 지정합니다.
  • fill: int 값으로, 셀 안에 남는 여분의 공간을 어떻게 처리할지 지정합니다.
  • RELATIVE: gridx와 gridy 필드에 사용되면, 컴포넌트가 마지막으로 추가된 컴포넌트 바로 옆에 배치됨을 의미합니다. gridwidth와 gridheight 필드에 사용되면, 해당 컴포넌트가 행 또는 열에서 끝에서 두 번째 컴포넌트임을 의미합니다.
  • REMAINDER: gridwidth와 gridheight 필드에 사용되면, 해당 컴포넌트가 행 또는 열의 마지막 컴포넌트임을 의미합니다.

예제 코드

아래는 GridBagConstraints를 활용하여 로그인 형태의 입력 폼 화면을 구성하는 전체 예제입니다.

import java.awt.*;
import javax.swing.*;
public class GridBagLayoutTest {
    public static void main(String[] a) {
        JFrame frame = new JFrame("GridBagLayout Test");
        Container myPane = frame.getContentPane();
        myPane.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        setMyConstraints(c,0,0,GridBagConstraints.CENTER);
        myPane.add(getFieldPanel(),c);
        setMyConstraints(c,0,1,GridBagConstraints.CENTER);
        myPane.add(getButtonPanel(),c);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 250);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    private static JPanel getFieldPanel() {
        JPanel p = new JPanel(new GridBagLayout());
        p.setBorder(BorderFactory.createTitledBorder("Details"));
        GridBagConstraints c = new GridBagConstraints();
        setMyConstraints(c,0,0,GridBagConstraints.EAST);
        p.add(new JLabel("Name:"),c);
        setMyConstraints(c,1,0,GridBagConstraints.WEST);
        p.add(new JTextField(16),c);
        setMyConstraints(c,0,1,GridBagConstraints.EAST);
        p.add(new JLabel("System:"),c);
        setMyConstraints(c,1,1,GridBagConstraints.WEST);
        p.add(getSystemPanel(),c);
        setMyConstraints(c,0,2,GridBagConstraints.EAST);
        p.add(new JLabel("Language:"),c);
        setMyConstraints(c,1,2,GridBagConstraints.WEST);
        p.add(getLanguagePanel(),c);
        setMyConstraints(c,0,3,GridBagConstraints.EAST);
        p.add(new JLabel("Year:"),c);
        setMyConstraints(c,1,3,GridBagConstraints.WEST);
        p.add(new JComboBox(new String[] {"2019","2020","2021"}),c);
        return p;
    }
    private static JPanel getButtonPanel() {
        JPanel p = new JPanel(new GridBagLayout());
        p.add(new JButton("OK"));
        p.add(new JButton("Cancel"));
        return p;
    }
    private static JPanel getSystemPanel() {
        JRadioButton winButton = new JRadioButton("Windows",true);
        JRadioButton macButton = new JRadioButton("Mac",false);
        ButtonGroup systemGroup = new ButtonGroup();
        systemGroup.add(winButton);
        systemGroup.add(macButton);
        JPanel p = new JPanel(new GridBagLayout());
        p.add(winButton);
        p.add(macButton);
        return p;
    }
    private static JPanel getLanguagePanel() {
       JPanel p = new JPanel(new GridBagLayout());
        p.add(new JCheckBox("Java",true));
        p.add(new JCheckBox("Python",true));
        p.add(new JCheckBox("Spark",false));
        return p;
    }
    private static void setMyConstraints(GridBagConstraints c, int gridx, int gridy, int anchor) {
        c.gridx = gridx;
        c.gridy = gridy;
        c.anchor = anchor;
    }
}

실행 결과

위 코드를 실행하면 라벨과 입력 필드, 라디오 버튼, 체크박스, 콤보박스, 버튼들이 격자 형태로 깔끔하게 정렬된 GUI 창이 나타납니다. 이처럼 GridBagConstraints를 잘 활용하면 복잡한 폼 레이아웃도 정교하게 설계할 수 있습니다.