본문 바로가기

coding/Java

[Java] GUI 응용프로그램(1) - Layout, Panel, Component

자바의 GUI(Graphical User Interface) 기반으로 응용프로그램을 작성해보자.

자바가 지원하는 GUI 컴포넌트에는 AWT 컴포넌트와 Swing 컴포넌트가 있다.

  • AWT(Abstract Windowing Toolkit) : 자바가 처음 나왔을 때 함께 배포된 패키지로, AWT 컴포넌트들은 중량 컴포넌트이다. 실행되는 운영체제에 따라 컴포넌트들이 각기 다른 모양으로 구현됨.
  • Swing : 경량 컴포넌트. 운영체제의 도움을 받지 않기 때문에 운영체제와 관계없이 항상 동일한 모양을 갖고 있다. JFrame, JPanel, JButton, JLabel 등 앞에 J가 들어가면 대부분 Swing 컴포넌트임. (아닌 것도 있지만...)

 

따라서 java.awt.*;와 javax.swing.*;을 꼭 import 해주고 시작할 것!

 

자바의 GUI 응용프로그램은 GUI 컴포넌트들로 구성되며, 다른 컴포넌트를 포함할 수 있는지의 여부에 따라 기본 컴포넌트와 컨테이너로 분류된다.

 

 

이 포스트에서 만드는 어플리케이션은 동작하지 않는다. 이유는 이벤트 처리를 하지 않고 틀을 구성하는 방법만 쓰기 때문. 클릭이나 입력에 의해 프로그램의 실행 흐름이 결정되는 '이벤트 처리'는 다음 포스트를 참고해주길 바람!!

 

1) 기본 프레임 만들기

프론트앤드가 제일 재밌어.. 화면 출력이 관건이기 때문에 setVisible(true)를 빼먹지 않는게 중요하다. 이거 없으면 화면에 아무것도 뜨지 않음

import javax.swing.*;
import java.awt.*;

class MyFrame extends JFrame {
	public MyFrame() {
		setSize(300, 150); //가로 300, 세로 150
		setLocation(200, 300); //모니터 왼쪽 상단을 기준으로 오른쪽으로 200, 아래로 300
		setTitle("MyFrame");
		setLayout(new FlowLayout());
		getContentPane().setBackground(Color.yellow);
		
		JButton b1 = new JButton("확인"); //버튼 객체 만들기
		JButton b2 = new JButton("취소"); //버튼 객체 만들기
		add(b1);
		add(b2);
		
		setVisible(true);
	}
}

public class FinalTermTest {
	public static void main(String[] args) {
		MyFrame frame = new MyFrame();
	}
}

 

 

2) 배치관리자

컨테이너에 부착되는 컴포넌트들의 위치와 크기는 컨테이너 내부에 있는 배치관리자(Layout Manager)에 의해 결정된다. 즉, 배치(Layout)란 컨테이너 안의 각 컴포넌트의 위치와 크기를 결정하는 작업이다.

대표적인 배치관리자는 다음과 같다.

 

1. FlowLayout

컨테이너에 부착하는 순서는 왼쪽에서 오른쪽. 오른쪽에 더 배치할 공간이 없으면 아래로 내려와서 다시 왼쪽 -> 오른쪽으로 컴포넌트를 배치한다. 드래그를 이용해서 창의 크기를 늘렸다 줄였다 해보면 바로 이해할 수 있음. FlowLayout 배치관리자는 위에서 썼으니까 예시 패스

 

2. BorderLayout

동서남북중앙 5개의 영역을 나눠서 컴포넌트들이 배치된다. 이건 응용프로그램이 지정해줌 (사용자가 지정하지 않으면 중앙에 배치됨)

import javax.swing.*;
import java.awt.*;

class MyFrame extends JFrame {
	public MyFrame() {
		setSize(300, 150);
		setLocation(200, 300);
		setTitle("MyFrame");
		setLayout(new BorderLayout()); //BorderLayout 배치관리자
		
		JButton b1 = new JButton("NORTH");
		JButton b2 = new JButton("SOUTH");
		JButton b3 = new JButton("EAST");
		JButton b4 = new JButton("WEST");
		JButton b5 = new JButton("CENTER");
		add(b1, BorderLayout.NORTH);
		add(b2, BorderLayout.SOUTH);
		add(b3, BorderLayout.EAST);
		add(b4, BorderLayout.WEST);
		add(b5, BorderLayout.CENTER);
		
		setVisible(true);
	}
}

public class FinalTermTest {
	public static void main(String[] args) {
		MyFrame frame = new MyFrame();
	}
}

 

3. GridLayout

2차원 격자로 공간을 나눈다. 컴포넌트 삽입 순서는 FlowLayout과 마찬가지로 왼쪽 -> 오른쪽, 위 -> 아래.

참고로 GridLayout() 안에 인자를 예시처럼 숫자로 남겨주면 알아서 컴포넌트 위치를 배정해주는데, 비워두면 행 수를 우선적으로 고려해서 0행에 열수를 버튼 수만큼 늘린다 (일렬로 5칸 나온다는 얘기).

import javax.swing.*;
import java.awt.*;

class MyFrame extends JFrame {
	public MyFrame() {
		setSize(300, 150);
		setLocation(200, 300);
		setTitle("MyFrame");
		setLayout(new GridLayout(2, 3)); //GridLayout 배치관리자 (행 수, 열 수)
		
		JButton b1 = new JButton("Button1");
		JButton b2 = new JButton("Button2");
		JButton b3 = new JButton("Button3");
		JButton b4 = new JButton("Button4");
		JButton b5 = new JButton("Button5");
		add(b1);
		add(b2);
		add(b3);
		add(b4);
		add(b5);
		
		setVisible(true);
	}
}

public class FinalTermTest {
	public static void main(String[] args) {
		MyFrame frame = new MyFrame();
	}
}

 

4. 절대위치로 배치

이건 배치관리자의 종류가 아닌가..? 암튼 지금까지는 버튼이 크기도 위치도 좀 자기마음대로인 느낌이 있는데, 사용자가 고정해버릴 수도 있다. 일단 setLayout(null)임을 기억해두자.

import javax.swing.*;
import java.awt.*;

class MyFrame extends JFrame {
	public MyFrame() {
		setSize(300, 150);
		setLocation(200, 300);
		setTitle("MyFrame");
		setLayout(null); //절대 크기의 설정
	
		JButton b1 = new JButton("Button1");
		add(b1);
		b1.setLocation(10, 30); //위치 설정 - 프레임 기준 오른쪽(x축)으로 10, 밑으로(y축)으로 30
		b1.setSize(90, 20); //크기 설정
		
		JButton b2 = new JButton("Button2");
		add(b2);
		b2.setLocation(150, 30); //프레임 기준 오른쪽(x축)으로 150, 밑으로(y축)으로 30
		b2.setSize(90, 20); //크기 설정

		setVisible(true);
	}
}

public class FinalTermTest {
	public static void main(String[] args) {
		MyFrame frame = new MyFrame();
	}
}

 

 

3) 패널과 기초 컴포넌트

패널(Panel)은 컴포넌트들을 포함하고 있도록 설계된 컨테이너 중 하나이다.

패널없이 그냥 프레임만 쓰는 경우는 드문 모양. 패널을 쓰면 화면을 분할해서 안에 컴포넌트(예를 들면 버튼)들을 집어넣고 싶을 때 편하다.

 

기초 컴포넌트들은 다음과 같은 종류가 있음

  • 레이블: JLabel - 텍스트를 표시할 수 있는 공간(편집이 불가능한 텍스트)
  • 텍스트필드: JTextField - 사용자가 한 줄의 텍스트를 입력할 수 있는 공간
  • 버튼: JButton - 클릭되면 어떤 동작을 실행하는 버튼

텍스트필드에는 JTextField 외에도 JFormattedTextField(사용자가 입력할 수 있는 문자를 제한), JPasswordField(주민등록번호 입력할 때 처럼 입력하는 내용 가려줌) 등이 있고 버튼도 JCheckBox(여러개 선택 가능한 네모 체크박스), JRadioButton(그룹 중 하나의 버튼만 선택 체크 가능) 등이 있다.

 

예시를 만들어볼 것인데, 화면 복붙이 귀찮으니 궁금하시면 코드 직접 돌려주세여~~

 

 

Q1. 화씨온도를 섭씨 온도로 변환해주는 어플리케이션을 작성해 보자.

import javax.swing.*;
import java.awt.*;

class MyFrame extends JFrame {
	public MyFrame() {
		setSize(250, 150);
		setLocation(500, 100);
		setTitle("온도변환기");
		
		setLayout(new FlowLayout()); 
		
		JLabel l1 = new JLabel("화씨 온도");
		JLabel l2 = new JLabel("섭씨 온도");
		JTextField f1 = new JTextField(15); //15글자를 입력할 수 있는 텍스트필드
		JTextField f2 = new JTextField(15);
		JButton b1 = new JButton("변환"); //가운데 정렬이 디폴트인 FlowLayout
		
		//여기서부터 순서 중요함!! FlowLayout이니깐
		add(l1);
		add(f1);
		add(l2);
		add(f2);
		add(b1);
		
		setVisible(true);
	}
}

public class FinalTermTest {
	public static void main(String[] args) {
		MyFrame frame = new MyFrame();
	}
}

 

 

Q2. 피자의 종류를 버튼으로 만들고, 개수를 입력받는 어플리케이션을 작성해 보자. 패널 안에 다른 패널이 포함될 수 있다는 것을 이용해 화면 디자인하기!

import javax.swing.*;
import java.awt.*;

class MyFrame extends JFrame {
	public MyFrame() {
		setSize(600, 150);
		setLocation(200, 300);
		setTitle("MyFrame");
		
		//setLayout을 아무것도 하지 않으면 기본적으로 FlowLayout이 된다
		
		JPanel p = new JPanel();
		JPanel p1 = new JPanel();
		JPanel p2 = new JPanel();
		
		JLabel l1 = new JLabel("자바 피자에 오신 것을 환영합니다. 피자의 종류를 선택하시오.");
		p1.add(l1);
		
		JButton b1 = new JButton("콤보피자");
		JButton b2 = new JButton("포테이토피자");
		JButton b3 = new JButton("불고기피자");
		
		JLabel l2 = new JLabel("개수");
		JTextField t1 = new JTextField("3", 10); //앞에 문자열 넣으면 화면에 미리 보여짐
		p2.add(b1);
		p2.add(b2);
		p2.add(b3);
		p2.add(l2);
		p2.add(t1);
		
		//패널들 사이의 관계 설정
		p.add(p1);
		p.add(p2);
		add(p);
		
		setVisible(true);
	}
}

public class FinalTermTest {
	public static void main(String[] args) {
		MyFrame frame = new MyFrame();
	}
}