[JAVA] GUI 프로그래밍 - AWT 컴포넌트, Swing(스윙)컴포넌트
자바의 GUI
- 그래픽 이용, 사용자가 이해하기 쉬운 모양으로 정보제공
- 마우스나 키보드를 이용하여 입력
GUI 프로그래밍
- GUI 컴포넌트와 그래픽 이용
AWT – java.awt 패키지
Swing – javax.swing 패키지
AWT |
Swing |
자바가 처음 나왔을 때 함께 배포된 GUI 라이브러리 |
AWT 기술을 기반으로 순수 자바언어로 만든 라이브러리 |
java.awt 패키지 |
javax.swing 패키지 |
Heavy weight (중량) 컴포넌트 |
Light weight (경량) 컴포넌트 |
Native(peer) OS의 GUI 컴포넌트의 도움을 받아 작동 |
Native(peer) OS에 의존 X |
빠른 속도, OS 많은 부담 |
화려한 고급 컴포넌트+AWT |
|
유형 1) JComponet 상속받는 클래스 : 대부분 유형 2) AWT의 Container를 상속받는 클래스 : JApplet, JDialog,JFrame,등 |
Swing(스윙)
- JComponet : 스윙 컴포넌트의 공통 속성을 구현한 추상 클래스, AWT의 Component를 상속받음
new JComponent() 인스턴스 생성 X
스윙 GUI 프로그램 만드는 방법
1. 스윙 프레임 작성
2. main() 메소드 작성
3. 프레임에 스윙 컴포넌트 붙이기
스윙 패키지 사용 import문
import java.awt.*; //그래픽 처리 클래스의 경로명
import java.awt.event.* //AWT 이벤트 사용을 위한 경로명
import javax.swing.*; // 스윙 컴포넌트 클래스들의 경로명
import javax.swing.event.*; //스윙 이벤트를 위한 경로명
컨테이너와 컴포넌트
컨테이너 |
컴포넌트 |
다른 GUI 컴포넌트를 포함할 수 있는 컴포넌트 |
컨테이너에 포함되어야 화면에 출력될 수 있는 순수 컴포넌트 |
java.awt.Container 상속, 다른 컨테이너에 포함될 수 O |
모든 컴포넌트는 java.awt.Componet 상속받음 모든 스윙 컴포넌트는 javax.swing.JComponent 상속받음 |
AWT 컨테이너 : Panel, Frame, Applet, Dialog, Window |
|
Swing 컨테이너 : 앞에 J 붙인거 |
최상위 컨테이너
- 독립적 출력 O
- JFrame, JDialog, JApplet
- 모든 컴포넌트는 컨테이너에 포함되어야 화면 출력 O
컨테이너와 컴포넌트의 포함관계
스윙 프레임
- 모든 스윙 컴포넌트를 담는 최상위 GUI 컨테이너
- JFrame을 상속받아 구현
- 스윙 프레임에 의존
프레임 : 스윙 프로그램의 기본 틀
메뉴바 – 메뉴 부착
Content Pane : GUI 컴포넌트 부착
300*300 크기의 스윙 프레임 만들기
import javax.swing.*;
public class swing1 extends JFrame{
public swing1(){
setTitle("300 * 300 swing frame 만들기");
setSize(300,300);
setVisible(true);
}
public static void main(String[] args) {
swing1 frame = new swing1();
}
}
위의 코드를 실행하면 아래와 같은 창이 뜬다
cf) main()을 프레임 클래스 내의 멤버로 작성
프레임에 컴포넌트 붙이기
- 3개의 버튼 컴포넌트를 가진 스윙프레임
import javax.swing.*;
import java.awt.*;
public class swing2 extends JFrame{
public swing2() {
setTitle("ContentPane과 JFrame"); //메소드를 호출하여 타이틀달기
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = getContentPane(); //컨텐트팬 알아내기
contentPane.setBackground(Color.ORANGE);
contentPane.setLayout(new FlowLayout());
//컨텐트팬에 컴포넌트 달기
contentPane.add(new JButton("OK"));
contentPane.add(new JButton("Cancel"));
contentPane.add(new JButton("Ignore"));
setSize(300,150);
setVisible(true);
}
public static void main(String[] args) {
new swing2();
}
}
위의 코드를 실행하면 아래와 같은 창이 뜬다
스윙 응용프로그램의 종료
- 응용프로그램 내에서 스스로 종료
System.exit(0); -언제 어디서나 종료
- 프레임 종료 버튼(x) 클릭되면?
프레임은 닫히지만, 응용프로그램은 작동함
setVisible(true) 호출 시 프레임 보이고 다시 작동
- 프레임 종료 버튼 클릭시 프레임 닫고 응용프로그램 종료하려면?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main() 종료 뒤에도 프레임이 살아 있는 이유?
- 스윙 프로그램이 실행되는 동안 메인스레드, 이벤트분배스레드 생성
메인스레드 : main() 실행, 자바 응용 프로그램의 실행 시작
이벤트 분배 스레드 : 자동실행, 프레임과 버튼, 등 GUI 화면 그리기, 키와 마우스 입력받아 호출
실행중인 사용자 스레드가 하나도 없을 때 자바 응용프로그램 종료
-> 메인 스레드가 종료되어도 이벤트 분배 스레드가 살아있어 프레임 화면, 마우스나 키 입력을 받기 때문
컨테이너와 배치 개념
1. 컨테이너마다 하나의 배치 관리자가 존재
- 삽입되는 모든 컴포넌트의 위치와 크기 결정, 적절히 배치
2. 컨테이너의 크기가 변하면 내부 컴포넌트들의 위치와 크기를 모두 재조절/재배치
배치관리자
- java.awt 패키지에 구현되어 있음
(FlowLayout, BorderLayout, GridLayout, CardLayout) 4가지 유형이 있다
"이쪽으로 가세요" 하는 사람을 배치관리자(Layout Manager)
자리를 컨테이너(Container)
자리를 배정받는 사람을 컴포넌트(Component)
배치관리자
- java.awt 패키지에 구현되어 있음
(FlowLayout, BorderLayout, GridLayout, CardLayout)
컨테이너와 디폴트 배치관리자
AWT와 스윙 컨테이너 |
디폴트 배치관리자 |
Window, JWindow |
BorderLayout |
Frame, JFrame |
|
Dialog, JDialog |
|
Panel, JPanel |
FlowLayout |
Applet, JApplet |
컨테이너에 새로운 배치 관리자 설정
- Container.setLayout(LayoutManager Im) : Im을 새로운 배치관리자로 설정
//JPanel 패널에 BorderLayout 배치 관리자 설정
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
//컨텐트팬의 배치 관리자를 FlowLayout으로 변경
Container c = frame.getConentPane(); //컨텐트팬
c.setLayout(new FlowLayout());
FlowLayout
- 컨테이너 크기가 변하면 컴포넌트 재배치
- FLowLayout(int align, int hGap, vGap)
align : 컴포넌트 정렬방법( FlowLayout.LEFT)
hGap : 좌우 컴포넌트 사이 수평간격, 픽셀단위, 디폴트는 5
vGap : 상하 컴포넌트 사이 수직간격, 픽셀단위, 디폴트는 5
FlowLayout 배치 관리자 활용
import javax.swing.*;
import java.awt.*;
public class swing3 extends JFrame{
public swing3() {
setTitle("FlowLayout Sample");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
//FlowLayout(int align, int hGap, int vGap)
c.setLayout(new FlowLayout(FlowLayout.LEFT,30,40)); //왼쪽으로 정렬
//align : 컴포넌트 정렬방법
//(FlowLayout.LEFT) (FlowLayout.RIGHT) (FlowLayout.CENTER(디폴트))
//hGap : 좌우 컴포넌트 사이 수평간격, 픽셀단위, 디폴트는 5
//vGap : 상하 컴포넌트 사이 수직간격, 픽셀단위, 디폴트는 5
c.add(new JButton("add"));
c.add(new JButton("sub"));
c.add(new JButton("mul"));
c.add(new JButton("div"));
c.add(new JButton("Calculate"));
setSize(300,200);
setVisible(true);
}
public static void main(String[] args) {
new swing3();
}
}
위의 코드를 실행하면 아래와 같은 창이 뜬다
창의 크기를 바꿨더니 아래와 같은 화면이 되었다.
BorderLayout
- 배치방법 : 컨테이너 공간 5구역으로 분할 배치
(East,West,South,North,Center)
- 컨테이너 크기가 변하면 재배치
- void add(Component comp, int index)
: comp 컴포넌트를 index 위치에 삽입
(BorderLayout.EAST)
BorderLayout 배치관리자를 사용하는 코드
import javax.swing.*;
import java.awt.*;
public class swing4 extends JFrame{
public swing4() {
setTitle("BorderLayout Sample");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new BorderLayout(30,20));
c.add(new JButton("Calculate"),BorderLayout.CENTER);
c.add(new JButton("add"),BorderLayout.NORTH);
c.add(new JButton("sub"),BorderLayout.SOUTH);
c.add(new JButton("mul"),BorderLayout.EAST);
c.add(new JButton("div"),BorderLayout.WEST);
setSize(300,200);
setVisible(true);
}
public static void main(String[] args) {
new swing4();
}
}
위의 코드를 실행하면 아래와 같은 창이 뜬다
창의 크기를 바꿨더니 아래와 같은 화면이 되었다.
GridLayout
- 컨테이너 공간을 동일한 사각형 격자(그리드)로 분할하고 각 셀에 하나의 컴포넌트 배치
- 생성자에 행수와 열수 지정(vGap,hGap)
- 컨테이너 크기가 변하면 재배치
- GridLayout(int rows, int cols, int hGap, int vGap)
rows: 그리드 행수, 디폴트는 1
cols : 열수, 디폴트는 1
hGap 좌우 vGap 수직 디폴트는 0
GridLayout으로 입력 폼 만들기
import javax.swing.*;
import java.awt.*;
public class swing5 extends JFrame{
public swing5() {
setTitle("GridLayout Sample");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout grid = new GridLayout(4,2);
grid.setVgap(5);
Container c = getContentPane();
c.setLayout(grid);
c.add(new JLabel("이름")); c.add(new JTextField(""));
c.add(new JLabel("학번")); c.add(new JTextField(""));
c.add(new JLabel("학과")); c.add(new JTextField(""));
c.add(new JLabel("과목")); c.add(new JTextField(""));
setSize(300,200);
setVisible(true);
}
public static void main(String[] args) {
new swing5();
}
}
위의 코드를 실행하면 아래와 같은 창이 뜬다
배치관리자 없는 컨테이너
- 응용프로그램에서 컴포넌트의 절대크기와 절대위치 결정
(용도)
- 컴포넌트의 크기나 위치 임의 지정
- 시간이나 마우스/키보드의 입력에 따라 컴포넌트들의 위치와 크기가 수시로 변하는 경우
- 여러 컴포넌트들이 서로 겹쳐 출력하고자 하는경우
컨테이너의 배치 관리자 제거 방법 : container.setLayout(null)
- 크기설정 setSize (width, height) 위치설정 setLocating(x,y)
- 위치와 크기 동시 설정 setBounds(x,y,width,height)
컴포넌트를 절대위치와 크기로 지정
import javax.swing.*;
import java.awt.*;
public class swing6 extends JFrame{
public swing6() {
setTitle("Null Container Sample");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(null);
JLabel la = new JLabel("Hello, Press Buttons!");
la.setLocation(130,50);
la.setSize(200,20);
c.add(la);
for(int i=1;i<=9;i++) {
JButton b = new JButton(Integer.toString(i)); //버튼 생성
b.setLocation(i*15,i*15);
b.setSize(50,20);
c.add(b); //버튼을 컨텐트팬에 부착
}
setSize(300,200);
setVisible(true);
}
public static void main(String[] args) {
new swing6();
}
}
위의 코드를 실행하면 아래와 같은 창이 뜬다