Programming Language/Java

[JAVA] GUI 프로그래밍 - AWT 컴포넌트, Swing(스윙)컴포넌트

BS Kwak 2020. 12. 12. 23:49

자바의 GUI

- 그래픽 이용, 사용자가 이해하기 쉬운 모양으로 정보제공

- 마우스나 키보드를 이용하여 입력

 

GUI 프로그래밍

- GUI 컴포넌트와 그래픽 이용

  AWT – java.awt 패키지

  Swing – javax.swing 패키지

 

AWT

Swing

자바가 처음 나왔을 때 함께 배포된 GUI 라이브러리

AWT 기술을 기반으로 순수 자바언어로 만든 라이브러리

java.awt 패키지

javax.swing 패키지

Heavy weight (중량) 컴포넌트

Light weight (경량) 컴포넌트

Native(peer) OSGUI 컴포넌트의 도움을 받아 작동

Native(peer) OS에 의존 X

빠른 속도, OS 많은 부담

화려한 고급 컴포넌트+AWT

 

유형 1) JComponet 상속받는 클래스 : 대부분

유형 2) AWTContainer를 상속받는 클래스 : JApplet, JDialog,JFrame,

 

Swing(스윙)

- JComponet : 스윙 컴포넌트의 공통 속성을 구현한 추상 클래스, AWTComponent를 상속받음

  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();

	}

}

위의 코드를 실행하면 아래와 같은 창이 뜬다