[Java] 자바 GUI
▶ 자바 GUI(Graphical User Interface)
- 이미지 혹은 그래픽을 이용하여 메뉴 등을 포함하는 화면을 구성하고,
- 키보드 외 마우스 등의 편리한 입력 도구를 이용하여 사용자가 입력하기 편하도록 만들어진 사용자 인터페이스
● 자바 GUI 특징
- 강력한 GUI 컴포넌트 제공, 쉬운 GUI 프로그래밍
● 자바 GUI 프로그래밍 방법
- GUI 컴포넌트와 그래픽 이용
- GUI 컴포넌트는 AWT 컴포넌트와 Swing 컴포넌트로 구분
- AWT 패키지와 Swing 패키지에 제공하는 메커니즘 이용
▷AWT(Abstract Windowing Toolkit)
- 자바가 처음 나왔을 때 함께 배포된 GUI 라이브러리
- java.awt 패키지
- AWT 컴포넌트는 중량 컴포넌트(Heavy weight components)
- AWT 컴포넌트는 native(peer) 운영체제의 GUI 컴포넌트의 도움을 받아 작동
- 운영체제의 자원을 많이 소모하여 운영체제에 많은 부담, 오히려 처리 속도는 빠름
▷Swing
- AWT 기술을 기반으로 순수 자바 언어로 만들어진 라이브러리
- java.swing 패키지
- 모든 AWT기능 + 추가된 풍부하고 화려한 고급 컴포넌트
- AWT 컴포넌트에 J자가 덧붙여진 이름의 클래스
- 그 외J 자로 시작하는 클래스
- Swing 컴포넌트는 경량 컴포넌트(Light weight components)
- native(peer) 운영체제에 의존하지 않음
▷Swing 컴포넌트 예시
▷Swing 으로 만든 GUI 프로그램 예시
▷GUI 라이브러리 계층 구조
▷Swing 클래스 특징
- 클래스 이름이 J자로 시작
- 다양한 컴포넌트를 쉽게 GUI 프로그래밍
● Swing 컴포넌트의 2가지 유형
1. JComponent는 상속받는 클래스 (대부분의 스윙 컴포넌트)
2. AWT의 Continer를 상속받는 클래스 (JApplet, JDialog, JFrame 등)
▷컨테이너와 컴포넌트
● 컨테이너
- 다른 GUI 컴포넌트를 포함할 수 있는 컴포넌트
- 다른 컨테이너에 포함될 수 있음(그러므로 컨테이너는 컴포넌트이면서 동시에 컨테이너)
- java.awt.Container 상속 받아야함
- AWT 컨테이너 :Panel, Frame, Applet, Dialog, Window
- Swing 컨테이너 :JPanel, JFrame, JApplet, JWindow
● 최상위 컨테이너
- 다른 컨테이너에 속하지 않고 독립적으로 출력가능한 컨테이너 ex) JFrame, JDialog, JApplet
- 이들을 제외한 나머지 컨테이너나 컴포넌트는 컨테이너에 포함되어야 화면에 출력 가능
● 컴포넌트
- 컨테이너에 포함되어야 화면에 출력될 수 있는 순수 컴포넌트
- 모든 컴포넌트는 java.awt.Component를 상속받음
- 모든 스윙 컴포넌트는 javax.swing.JComponent를 상속받음
▷컨테이너와 컴포넌트의 포함 관계
- 자바 스윙 응용프로그램은 JFrame과 같은 최상위 컨테이너 위에 컨테이너와 컴포너트들이 마치 레고 블록을 쌓는 것처럼 컨테이너와 컴포넌트의 계층 구조로 구성
- 컨테이너에 부착된 컴포넌트들을 자식 컴포넌트라고 함
▶ Swing GUI 프로그램 만들기
1) Swing 프레임 작성
2) main() 메소드 작성
3) 프레임에 Swing 컴포넌트 붙이기
● Swing 패키지 사용을 위한 import문
improt문 | 설명 |
import java.awt.*; | 그래픽 처리를 위한 클래스들의 경로명 |
import java.awt.event.*; | AWT 이벤트 사용을 위한 경로명 |
import javax.swing.*; | Swing 컴포넌트 클래스들의 경로명 |
import javax.swing.event.*; | Swing 이벤트를 위한 경로명 |
1) Swing 프레임
● 모든 Swing 컴포넌트를 담는 최상위 GUI 컨테이너
- JFrame을 상속 받아 구현
- 컴포넌트가 화면에 보이려면 Swing 프레임에 부착되어야 함
- 프레임을 닫으면 프레임 내의 모든 컴포넌트가 보이지 않게 됨
● Swing 프레임(JFrame) 기본 구성
- 프레임(Frame) :스윙 프로그램의 기본 틀
- 메뉴바(Menu Bar) :메뉴들이 부착되는 공간
- 켄텐트팬(content pane):GUI 컴포넌트들이 부착되는 공간
예제) 300x300 크기의 스윙 프레임 만들기
2) main()의 위치
- 스윙 응용 프로그램에서 main()의 기능은 최소화 하는 것이 좋음
- main()에는 스윙 응용 프로그램이 실행되는 시작점으로서 프레임을 생성하는 코드 정도만 만들고, 나머지 기능은 프레임 클래스에 작성하는 것이 좋음
- 방법1과 같이 MyFrame 클래스에 두거나, 방법2와 같이 main()메소드만을 가진 새로운 클래스를 둘 수 있음
- 두 가지 방법 모두 실행결과 동일한 프레임 생성
3) 프레임에 Swing 컴포넌트 붙이기
● 타이틀 달기
● 컨텐트팬 알아내기
● 컨텐트팬 컴포넌트 달기
● 컨텐트팬 변경
예제) 3개의 버튼 컴포넌트를 가진 스윙프레임 만들기
▷Swing 응용 프로그램의 종료
- 자바에서 프로그램을 종료하려면 어떤 상황에서나 다음 코드를 사용하면 됨 (언제 어디서나 무조건 종료)
- 프레임 윈도우의 오른쪽 상단에 있는 '프레임 종료(X)'은 프레임 윈도우를 닫는 버튼이지 프로그램을 종료시키는 버튼이 아님
- '프레임 종료(X)'은 프레임이 보이지 않게 되지만 응용 프로그램이 종료한 것 아님 (키보드나 마우스 입력을 받지 못함)
- 다시 setVisible(true)를 호출하면 보이게 되고 이전 처럼 작동함
● 프레임 종료버튼(X)이 클릭될 때 프레임을 닫고 응용 프로그램이 종료하도록 하는 방법
- 다음 코드 작성
▷main() 종료 뒤에도 프레임이 살아 있는 이유는 무엇인가?
● 큰솔 응용프로그램 경우
- 자바 응용 프로그램이 시작되면 자바 가상 기계는 main 스레드를 만들고 실행시킴
- 응용 프로그램이 스레드를 만들지 않는 경우 main()이 종료되면 main 스레드가 종료되며, 더 이상 살아있는 스레드가 없기 때문에 이 응용프로그램이 종료되는 것
● Swing 응용 프로그램 경우
- 스윙에서는 JFrame 객체가 생성되면 main 스레드 외에, 입력되는 키와 마우스의 움직임을 컴포넌트에게 전달하는 이벤트 처리(분재) 스레드가 자동으로 추가 생성됨
- 그러므로 main 스레드가 종료하더라도 이벤트 처리 스레드가 살아 있기 때문에, 응용 프로그램은 종료되지않고 사용자로부터 키와 마우스 입력을 계속 처리하게 되는 것
● main 스레드
- main()을 실행하는 스레드
- 자바 응용프로그램의 실행을 시작한 스레드
● 이벤트 분배 스레드
- 스윙 응용프로그램이 실행될 때 자동으로 실행되는 스레드
- 이벤트 분배 스레드의 역할 ex) 프레임과 버튼 등 GUI 화면 그리기, 키나 마우스 입력을 받아 이벤트를 처리할 코드 호출
▷컨테이너와 배치 개념
- 컨테이너에 부착되는 컴포넌트들의 위치와 크기는 컨테이너 내부에 있는 배치관리자(Layout Manager)에 의해 결정됨
- 그림(1)은 컨테이너와 배치관리자 사이의 관계를 보여줌
- 안내원(배치관리자)은 강의실(컨테이너)에 들어오는 각 학생들(컴포넌트)에게 위치를 지정(배치) 해주고 있음
● AWT나 Swing컨테이너 특징
1. 컨테이너 마다 하나의 배치관리자가 존재하며, 삽입되는 모든 컴포넌트의 위치와 크기를 결정하고 적절히 배치함
2. 컨테이너의 크기가 변하면 내부 컴포넌트들의 위치와 크기를 모두 재조절하고 재배치함
● 배치 관리자의 대표 유형 4가지
- java.awt 패키지에 구현되어 있음
○ FlowLayout
- 컨테이너에 부착되는 순서대로 왼쪽에서 오른쪽으로 컴포넌트를 배치
- 오른쪽에 더 이상 배치할 공간이 없으면 아래로 내려와서 다시 왼쪽에서 오른쪽으로 배치
- 컴포넌트의 크기는 화면에 출력될 수 있는 적당한 크기로 설정 함
○ BorderLayout
- 컨테이너의 공간을 동,서,남,북, 중앙의 5개 영역으로 나누고 응용프로그램에서 지정한 영역에 컴포넌트를 배치
- 응용프로그램에서는 5개의 영역 중 하나를 반드시 지정해야함
- 영역을 지정하지 않으면 중앙에 배치, 컴포넌트의 크기는 영역의 크기에 맞추어 설정 함
○ GridLayout
- 컨테이너의 공간을 응용프로그램에서 설정한 동일한 크기의 2차원 격자로 나누고
- 컴포넌트가 삽입되는 순서대로 좌에서 우로, 다시 위에서 아래로 배치
- 컴포넌트의 크기는 셀의 크기와 동일하게 설정 함
○ CardLayout
- 컨테이너의 공간에 카드를 쌓아 놓은 듯이 컴포넌트를 포개에 배치
- 컴포넌트의 크기는 컨테이너의 크기와 동일하게 설정
● 컨테이너와 배치관리자
○ 컨테이너의 디폴트 배치 관리자
- 컨테이너가 생성될 때 자동으로 디폴트 배치 관리자 생성
○ 컨테이너에 새로운 배치관리자 설정
- Container.setLayout(LayoutManager Im) :lm을 새로운 배치관리자로 설정
▷FlowLayout
- 컨테이너 공간 내에 왼쪽에서 오른쪽으로 배치
- 다시 위에서 아래로 순서대로 컴포넌트를 배치
-컨테이너의 크기가 변하면 컴포넌트 재배치
● FlowLayout 생성자와 속성
예제) FlowLayout 배치관리자 활용
▷BorderLayout
- 컨테이너 공간을 5구역으로 분할, 배치
- 동, 서, 남, 북, 중앙
● 배치 방법
- add(Component comp, int index)
- comp를 index의 공간에 배치
- 컨테이너의 크기가 변하면 재배치
● 생성자
예제) BorderLayout 배치관리자를 사용하는 예
▷GridLayout
- 컨테이너 공간을 동일한 사각형 격자(그리드)로 분할하고 각 셀에 하나의 컴포넌트 배치
- 격자 구성은 생성자에 행수와 열수 지정
- 셀에 왼쪽에서 오른쪽으로, 다시 위에서 아래로 순서대로 배치
- 컨테이너의 크기가 변하면 재배치(크기 재조정)
● 생성자
예제) GridLayout으로 입력 폼 만들기
▷배치관리자가 없는 컨테이너
- 자바 GUI의 기본은 응용프로그램에서 배치관리자가 컴포넌트의 절대 크기와 절대 위치 결정
- 배치관리자가 없는 컨테이너도 존재 가능
● 용도
- 컴포넌트의 크기나 위치를 개발자 임의로 결정하고자 하는 경우
- 게임 프로그램과 같이 시간이나 마우스/키보드의 입력에 따라 컴포넌트의 위치와 크기가 수시로 변하는 경우
- 여러 컴포넌트들이 서로 겹쳐 출력하고자 하는 경우
● 컨테이너의 배치 관리자 제거 방법
- container.setLayour(null);
● 컴포넌트의 절대 크기와 절대 위치 설정
- 프로그램 내에서 이루어져야함
- 다음 메소드 이용
메소드 | 설명 |
component.setSize(int width, int height); | 컴포넌트 크기 설정 |
component.setLocation(int x, int y) | 컴포넌트 위치 설정 |
component.setBounds(int x, int y, int width, int height); | 컴포넌트 위치와 크기 동시 설정 |