웹개발 수업/JAVA

[Day +27]GUI / Java Swing, 컨테이너, 컴포넌트

Chole Woo 2021. 7. 29. 23:55
210729 목

 

GUI(Graphic User Interface)

<-> CLI(Command Line Interface)

 

-대부분의 소프트웨어 환경은 GUI이다.

*GUI의 중요도는 낮은 편이다. 프로젝트 구현 정도의 실력을 가지면 된다. 

 

1. GUI 특징

1) AWT

-AWT 패키지 하위에 클래스들이 많음

-윈도우의 OS컴포넌트를 그대로 사용하는 것이 특징

 

2) Swing

: AWT를 확장한 GUI프로그래밍 도구

-클래스명 앞에 J를 붙여서 AWT와 구분

예) JButton, JPannel

 

3) 컨테이너

-가장 바깥에 있는 GUI 컴포넌트

-컨테이너가 존재해야 다른 컴포넌트들을 올릴 수 있다

 

4) 컴포넌트

-컨테이너에 포함되어야 화면에 출력될 수 있는 GUI 객체

-Java.awt.Component 클래스는 모든 GUI컴포넌트의 최상위 클래스

-스윙컴포넌트의 최상위 클래스는 javax.swing.Jcomponent

 

 

<컨테이너와 컴포넌트의 포함관계>

 

2. 작업 순서

1) 컨테이너 객체 생성

-JFrame 상속 이용

2) 컨테이너에 레이아웃 설정

3) 컴포넌트 객체 생성

4) 지정된 배치 방식에 따라 컨테이너에 컴포넌트 배치

5) 컴포넌트에 마우스나 키보드 반응에 대한 이벤트 처리함

 

<컨테이너 배치 방식 지정>

1) BorderLayOut

-모두 5개 영역으로 나누고, 각 영역에 하나의 컴포넌트를 넣을 수 있음

-한 영역에 하나 이상의 컴포넌트를 넣고 싶으면 Panel을 사용

2) FlowLayout

-컴포넌트를 워드프로세서와 같은 방식, 즉 왼쪽에서 오른쪽으로 배치

-3가지 정렬 방식(왼쪽, 가운데, 오른쪽)이 가능

3) GridLayout

-컴포넌트들을 가로, 세로의 일정 수만큼 배치하고자 할 때 주로 사용

-행과 열을 지정하고, 각 컴포넌트는 동일한 사이즈를 가짐

4) CardLayout

-여러 컨테이너를 슬라이드처럼 바꿔가며 보여줄 수 있음

-앨범이나 퀴즈 또는 설치 프로그램에 주로 사용

5) NullLayout

-레이아웃 지정 없이 위치를 지정하여 배치하는 방법

-컴포넌트의 위치와 크기를 자유롭게 만들 수 있음

 

 

기본

1-1> JFrameView1

package com.kh.chap01_container.view;

import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

//JFrame생성하기1
//javax.swing.JFrame 클래스를 상속 받아 생성자에서 프레임에 대해 설정
public class JFrameView1 extends JFrame {
	
	//기본 생성자 안에 프레임 기본 세팅 설정하기
	public JFrameView1() {
		//프레임 위치 설정(x, y) => 픽셀 기준
		this.setLocation(300, 200);
		
		//프레임 크기 설정(width, height)
		this.setSize(800, 500);
		
		//프레임 위치와 크기 한번에 설정(x, y, width, height)
		this.setBounds(300, 200, 800, 500);
		
		
		//프레임 상단에 이름 설정
		this.setTitle("My Boo");
		
		//프레임 상단에 로고 이미지 변경
		try {
			this.setIconImage(ImageIO.read(new File("image/icon.png")));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		//기본 값으로 프레임 사이즈 조정이 활성화되어 있으므로 사이즈를 임의로 조정할 수 없게 설정
		this.setResizable(false);
		
		
		
		
		
		//창에서 X버튼을 눌러서 종료를 해도 프로세스는 계속 실행 중
		//닫기 버튼을 눌렀을 때 프로세스 정상 종료를 위한 구문 추가
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		//화면이 보여지게 만들기 위해서는 반드시 setVisible(true) 호출 필요
		//프레임 위에 올라간 컴포넌트들이 잘 보이려면 마지막에 호출
		this.setVisible(true);
		
		//=> 이 두 메소드는 꼭 넣는다고 생각하자! 而且 setVisible을 마지막에 넣는다고 생각하자!
	}

}

1-2> JFrameView2

package com.kh.chap01_container.view;

import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

//JFrame 생성하기2
//javax.swing.JFrame 클래스를 객체로 생성 후 
//해당 프레임 객체의 설정 값을 변경하는 방법
public class JFrameView2 {

	public void showJFrame() {
//		JFrame mainFrame = new JFrame();
//		mainFrame.setTitle("My Boo");
		
		//매개변수 생성자로 title 전달하면서 JFrame 객체 생성
		JFrame mainFrame = new JFrame("My Boo");
		
		//위치와 사이즈 설정 => 객체를 먼저 만들어주는 방법도 있음
		//Rectangle 객체를 활용(x, y, width, height)
		Rectangle r = new Rectangle(300, 200, 800, 500);
		mainFrame.setBounds(r);
		
		//사이즈 변경 불가
		mainFrame.setResizable(false);
		
		//아이콘 이미지 변경
		try {
			mainFrame.setIconImage(ImageIO.read(new File("image/icon.png")));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setVisible(true);
		
	}

}

답) 1, 2번 답 동일

package com.kh.chap01_container.run;

import com.kh.chap01_container.view.JFrameView1;
import com.kh.chap01_container.view.JFrameView2;

public class Run {

	public static void main(String[] args) {
		
		//JFrameView1 jf = new JFrameView1();
		
		JFrameView2 jf = new JFrameView2();
		jf.showJFrame();
	}

}

레이아웃

2-1> BorderLayout

package com.kh.chap02_layout.view;

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;

public class A_BorderLayout extends JFrame {

	public A_BorderLayout() {
		//부모 생성자로 JFrame title 전달
		super("BorderLayout");
		
		
		//프레임 위치 및 크기 설정
		this.setBounds(300, 200, 800, 500);
		
		
		//레이아웃 설정하기
		//LayoutManager 인터페이스의 후손 클래스로 다양한 레이아웃이 제공됨
		this.setLayout(new BorderLayout(10, 10));
		//=>주석처리를 해도 같은 값이 나옴. 		
		
		//현재 적용 된 레이아웃 알아보기
		//=> 미설정 시 JFrame의 기본 레이아웃도 BorderLayout임
		System.out.println(this.getLayout());
		//답 : java.awt.BorderLayout[hgap=0,vgap=0] 
		
		
		//JButton 객체 생성 => 객체 생성만으로 화면에 표현되는 것이 아님
		JButton north = new JButton("북");
		JButton south = new JButton("남");
		JButton east = new JButton("동");
		JButton west = new JButton("서");
		JButton center = new JButton("중간");
		
		//화면에 추가하기 위해서 add 메소드로 jframe 위에 jbutton 추가
		//위치 지정 문자열 틀렸을 경우 오류 발생 유의
		this.add(north, "North");
		this.add(south, "South");
		this.add(east, "East");
		this.add(west, "West");
		this.add(center, "Center");
		
		
		
		//반드시 필요한 코드
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		this.setVisible(true);
	}
	
}

답)

 

2-2> FlowLayout

package com.kh.chap02_layout.view;

import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;

public class B_FlowLayout extends JFrame {

	public B_FlowLayout() {
		super("FlowLayout");
		this.setBounds(300, 200, 800, 500);
		
		
		//FlowLayout 설정
		//컴포넌트들을 가로나 세로 방향의 줄 단위로 배치하는 레이아웃
		//만약 컨테이너보다 배치할 구성 요소가 더 많거나 크게 되면 자동으로 다음 줄로 넘기며 배치
		this.setLayout(new FlowLayout());	//기본 정렬 설정은 Center
		
		//정렬 기준 전달
		this.setLayout(new FlowLayout(FlowLayout.CENTER));
		this.setLayout(new FlowLayout(FlowLayout.LEFT));
		this.setLayout(new FlowLayout(FlowLayout.RIGHT));
		
		for(int i = 0 ; i < 15 ; i++) {
		this.add(new JButton(i+1+"번"));
		}
		
		
		
		
		
		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		
		
	}
	
}

답)

 

2-3> GridLayout

package com.kh.chap02_layout.view;

import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;

public class C_GridLayout extends JFrame {

	public C_GridLayout() {
	super("GridLayout");
	
	this.setBounds(300, 200, 800, 500);
	
	
	//GridLayout
	//컴포넌트들을 가로, 세로의 일정 수만큼 배치하고자 할 때 사용
	//윗 줄부터 시작해서 왼쪽에서오른쪽으로 움직이며 각 줄을 이동하며 컴포넌트 배치
	//생성자(가로칸, 세로칸, 가로갭, 세로갭)
	this.setLayout(new GridLayout(0, 5, 10, 20));
	// => 컴포넌트 개수가 맞지 않으면 rows에 설정된 값이 우선 된다.(가로값 우선)
	// => 만약 cols를 우선시 하고 싶은 경우  row는 0으로 두면 된다.
	
	for(int i = 1 ; i <= 40 ; i++) {
		this.add(new JButton(i + "번"));
	}
	
	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	this.setVisible(true);
	
	
	

	}
}

답)

 

2-4> CardLayout

package com.kh.chap02_layout.view;

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class D_CardLayout extends JFrame{

	public D_CardLayout() {
		
		super("CardLayout");
		this.setBounds(300, 200, 800, 500);
		
		
		//CardLayout
		//Panel을 이용해서 카드판을 만들어 겹쳐놓음
		//이벤트를 이용해서 다른 판이 보이게 설정해야 함
		CardLayout card = new CardLayout();
		this.setLayout(card);
		
		//패널 생성
		//패널은 컴포넌트지만 다른 컴포넌트를 포함할 수 있는 컨테이너의 성격을 지님
		JPanel card1 = new JPanel();
		JPanel card2 = new JPanel();
		JPanel card3 = new JPanel();
	
		//패널마다 배경색 지정하기
		card1.setBackground(Color.GRAY);
		card2.setBackground(Color.YELLOW);
		card3.setBackground(new Color(50,100, 100));
		
		//패널에 라벨 추가
		card1.add(new JLabel("Card1"));
		card2.add(new JLabel("Card2"));
		card3.add(new JLabel("Card3"));
		
		//메인 프레임에 패널 추가
		this.add(card1);
		this.add(card2);
		this.add(card3);
		
		//패널에 이벤트 추가
		card1.addMouseListener(new MouseAdapter() {
			
			//card1 패널에 마우스 클릭 이벤트가 일어날 때 수행할 코드 작성
			@Override
			public void mouseClicked(MouseEvent e) {
				
				//왼쪽 버튼1, 휠 2, 오른쪽 버튼3
				System.out.println(e.getButton());
				//감지 될때 1, 2, 3의 숫자가 콘솔창에 뜬다
				
				//왼쪽 버튼이 클릭 되었을 때 카드 레이아웃을 다음 카드로 변경
				if(e.getButton() == MouseEvent.BUTTON1) {
					card.next(card1.getParent());
				//오른쪽 버튼이 클릭 되었을 때 카드 레이아웃의 이전 카드로 변경
				}else if(e.getButton() == MouseEvent.BUTTON3) {
					card.previous(card1.getParent());
				}
			}
		});
		
		
		
		
		
		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		
	}
	
}

답)

 

2-5> NullLayout

package com.kh.chap02_layout.view;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class E_NullLayout extends JFrame {
	
	public E_NullLayout() {
		
	super("NullLayout");
	this.setBounds(200, 200, 500, 500);
	
	
	//Layout 지정 없이 위치 지정하면서 배치하는 방법
	this.setLayout(null);
	
	JLabel lb = new JLabel("이 름 : ");
	lb.setLocation(50, 100);
	lb.setSize(150,50);
	
	JTextField tf = new JTextField(20);
	tf.setLocation(110, 100);
	tf.setSize(200,50);
	
	JButton btn = new JButton("추 가");
	btn.setLocation(350, 100);
	btn.setSize(100,50);
	
	
	//프레임에 생성된 컴포넌트 추가
	//Layout이 null인 상태에서 컴포넌트의 위치 설정이 없으면 
	//프레임에 올라갈 수 없다
	this.add(lb);
	this.add(tf);
	this.add(btn);
	
	
	
	
	
	
	
	
	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	this.setVisible(true);
	
	
	}
	

}

답) 

 

 

package com.kh.chap02_layout.view;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class F_PanelLayout extends JFrame {
	
	public F_PanelLayout() {
	super("PanelLayout");
	this.setBounds(200, 200, 500, 500);
	
	
	//컴포넌트 생성
	JLabel lb = new JLabel("이 름 : ");
	lb.setLocation(50, 100);
	lb.setSize(150,50);
	
	JTextField tf = new JTextField(20);
	tf.setLocation(110, 100);
	tf.setSize(200,50);
	
	JButton btn = new JButton("추 가");
	btn.setLocation(350, 100);
	btn.setSize(100,50);
	
	//JPanel 생성
	JPanel panel = new JPanel();
	
	//Panel의 레이아웃 기본 값은 FlowLayout(정렬은 Center / B참조하세요)
	//패널에 위치를 정해서 컴포넌트를 올리고 싶다면 패널의 레이아웃을 null로 변경
	panel.setLayout(null);
	
	//패널에 컴포넌트 생성
	panel.add(lb);
	panel.add(tf);
	panel.add(btn);
	
	//패널을 프레임에 추가
	this.add(panel);
	
	
	
	
	
	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	this.setVisible(true);
	
	}
	
}

답)

package com.kh.chap02_layout.run;

import com.kh.chap02_layout.view.A_BorderLayout;
import com.kh.chap02_layout.view.B_FlowLayout;
import com.kh.chap02_layout.view.C_GridLayout;
import com.kh.chap02_layout.view.D_CardLayout;
import com.kh.chap02_layout.view.E_NullLayout;
import com.kh.chap02_layout.view.F_PanelLayout;

public class Run {

	public static void main(String[] args) {
		
		A_BorderLayout a = new A_BorderLayout();
		
		//B_FlowLayout b = new B_FlowLayout();

		//C_GridLayout c = new C_GridLayout();
		
		//D_CardLayout d = new D_CardLayout();

		//E_NullLayout e = new E_NullLayout();
		
		//F_PanelLayout f = new F_PanelLayout();
	}

}

Component

3-1> TextField

package com.kh.chap03_component.view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class A_TextField {

	public void testFieldTest() {
				
		JFrame frame = new JFrame("제곱 계산하기");
		
		frame.setSize(300, 140);
		
		//패널 생성
		JPanel panel = new JPanel();
		//라벨 패널에 부착
		panel.add(new JLabel("숫자 입력 : "));
		//텍스트 필드 생성
		JTextField text = new JTextField(15);
		panel.add(text);
		
		//라벨 패널에 부착
		panel.add(new JLabel("제곱한 값 : "));
		//결과 텍스트 필드 생성
		JTextField result = new JTextField(15);
		//결과 텍스트 필드 수정 불가 설정
		result.setEditable(false);
		panel.add(result);
		
		//버튼 생성
		JButton btn = new JButton("OK");
		panel.add(btn);
		
		
		
		//버튼 클릭 시 발생하는 이벤트 감지
		/*
		 * ActionEvent : 사용자가 어떤 동작을 할 때 발생하며 모든 컴포넌트에서 발생하지는 않음
		 * 1. 버튼이 눌러졌을 때 
		 * 2. 메뉴를 클릭했을 때
		 * 3. 텍스트 필드에서 엔터키를 눌렀을 때
		 */
		
		btn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				//클릭 시 text에 기록된 값 가져오기(문자열 파싱 처리)
				int value = Integer.parseInt(text.getText());
				//result에 제곱값 입력하기
				result.setText(value*value + "");
				//텍스트 상자로 다시 포커스 가져가기
				text.requestFocus();
			}});
		
		
		
		
		
		
		
		
		
		
		
		frame.add(panel);
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		
		
	}

	
	
}

답)

 

3-2> TextArea

package com.kh.chap03_component.view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class B_TextArea {
	
	public void textAreaTest() {
		
		JFrame frame = new JFrame("textarea 테스트");
		
		//입력용 텍스트 필드
		JTextField tf = new JTextField(30);
		
		//출력용 텍스트 필드
		JTextArea ta = new JTextArea(10, 30);
	
		//텍스트 필드에서 엔터키를 눌렀을 때 이벤트
		tf.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				//텍스트 필드에 입력 된 값 알아오기 
				String text = tf.getText();
				//텍스트 영역에 setText가 아닌 append로 해당 값 추가하기
				ta.append(text + "\n");
				tf.setText("");
				
			}});
		
		
		
		
		
		
		frame.add(tf, "North");
		frame.add(ta, "Center");
		
		
		//프레임 크기를 지정하지 않으면 작게 나옴
		//그래서 프레임의 크기를 컴포넌치 배치에 맞춰서 자동 설정하고 싶을 때
		frame.pack();
		
			
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		
	}

}

답)

 

3-3> RadioButton

package com.kh.chap03_component.view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

public class C_RadioButton {

	public void radioButtonTest() {
		
		JFrame frame = new JFrame("RadioButtonTest");
		frame.setSize(300,150);
		
		//상단 패널 생성
		JPanel topPanel = new JPanel();
		JLabel label = new JLabel("어떤 크기의 커피를 주문하시겠습니까?");
		topPanel.add(label);
		frame.add(topPanel, "North");
		
		//중간 패널
		JPanel sizePanel = new JPanel();
		
		JRadioButton small = new JRadioButton("Small Size");
		JRadioButton medium = new JRadioButton("Medium Size");
		JRadioButton large = new JRadioButton("Large Size");
		
		//버튼 그룹을 지정해주지 않으면 각자(모두 다) 선택 가능하게 동작한다.
		//라디오 버튼은 복수 선택이 불가능한 선택을 받기 위한 컴포넌트이므로
		//필수로 그룹으로 묶어줘야 한다
		ButtonGroup sizeGroup = new ButtonGroup();
		sizeGroup.add(small);
		sizeGroup.add(medium);
		sizeGroup.add(large);
		
		
		sizePanel.add(small);
		sizePanel.add(medium);
		sizePanel.add(large);
		
		frame.add(sizePanel, "Center");
		
		
		
		//하단 패널
		JPanel resultPanel = new JPanel();
		JLabel text = new JLabel("크기가 선택되지 않았습니다");
		resultPanel.add(text);
		frame.add(resultPanel, "South");
		
		
		//small size 버튼이 클릭되었을 때
		small.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				text.setText("Small Size가 선택되었습니다");
				
			}});
		
		//medium size 버튼이 클릭되었을 때
			medium.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
			text.setText("Medium Size가 선택되었습니다");
						
			}});
				
				
		//large size 버튼이 클릭되었을 때
			large.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
			text.setText("Large Size가 선택되었습니다");
						
			}});
				
		
		
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		
	}

}

답)

 

package com.kh.chap03_component.run;

import com.kh.chap03_component.view.A_TextField;
import com.kh.chap03_component.view.B_TextArea;
import com.kh.chap03_component.view.C_RadioButton;

public class Run {

	public static void main(String[] args) {
	
		A_TextField a = new A_TextField();
		//a.testFieldTest();
		
		B_TextArea b = new B_TextArea();
		//b.textAreaTest();
		
		C_RadioButton c = new C_RadioButton();
		c.radioButtonTest();

	}

}

 

댓글수0