Joslynn의 하루

대용량 웹서비스를 위한 MSA Full-Stack 개발자 양성 과정 -16일차 노트 필기_GUI와 이벤트 처리, Inner class(이너클래스), IO Stream(입출력 API)_220811 본문

MSA Full-Stack 개발자 양성과정/Java

대용량 웹서비스를 위한 MSA Full-Stack 개발자 양성 과정 -16일차 노트 필기_GUI와 이벤트 처리, Inner class(이너클래스), IO Stream(입출력 API)_220811

Joslynn 2022. 8. 11. 18:16

GUI 화면 구성

: Java 내에서도 화면 구성을 위한 라이브러리가 있음;

: JDK에 포함

 

1) awt

: import java.awt.*;

: 그래픽이 운영체제가 갖고 있는 그래픽을 가져와 화면을 구성하기 때문에, 운영체제의 영향을 받음

: 동일한 프로그램이라 하더라도 운영체제마다 다른 느낌으로 출력

: ex) Frame, Panel, Dialog, Button, TextField, TextArea....

 

2) swing

: import javax.swing.*;

: 자체적으로 Look and Feel을 가지고 있어서 어떤 운영체제에서 실행해도 동일한 느낌으로 보여진다.

: swing의 대부분은 awt를 상속받았음 // awt의 단점을 보완

: ex) JFrame, JPanel, JDialog, JButton, JTextField, JTextArea.... (대부분 앞에 J자가 붙음)

 

3) JavaFX

: Java가 sun에서 oracle로 흡수되면서 oracle 사에서 swing을 버리고 JavaFX로 화면 구성을 할 수 있도록 새로운 라이브러리를 추가함. (멀티미디어 적으로 화려하고 좀 더 세련된 느낌으로 과거의 플래시 같은 효과도 가능하다.)

: 웹앱, 어플리케이션이 많이 쓰이지 않아 순수 JavaFX로 화면 구성을 하는 경우가 많지 않음

 

 

알아야 하는 용어

1) Container

: 창의 역할

: 화면 구성을 위해서는 반드시 한 개 이상의 Container가 필요하고, 여러 개의 Component들을 Container 위에 올려서 화면을 구성

: 예를 들어, 웹의 브라우져 같은 역할

: ex) JFrame, JPanel(예쁜 배치를 위한 서브창), JDialog(로그인, 주소 찾기와 같은 서브창)

: JPanel은 Component를 상속 받음; // Component라고 부를 수도 있음 → JFrame 위에 올릴 수 있는 이유

 

2) Component

: Container 위에 올려져서 실질적인 화면 구성을 담당해주는 요소들

: ex) JButton, JCheckBox, JTextField, JTextArea....

 

3) LayoutManager

: Container 위에 Component들이 올려질 때, 레이아웃(배치)방법

: FlowLayout 왼쪽에서 오른쪽으로

: BorderLayout 5가지 영역(동서남북, 센터)으로 배치

: GridLayout 행과 열로 이루어짐

: CardLayout 카드가 한 장씩 올라가는 형태로 배치

: GridBackLayout


실습예제

// Frame 위에 Button을 올릴 때 → Frame.add(Button 인수);

// Frame.setLayout();

1. 보통 상속을 받아 사용시 Container를 주로 상속받아 사용 (super나 this로 접근 가능) // Frame의 메소드 사용 많음;

2. 나머지 Component들은 생성해서 사용

3. 화면 구성은 주로 생성자에서 작성


 

1. Container: JFrame을 상속 받아 사용

: if, title을 생성하고 싶다면 생성자 첫 줄에서 super(title 내용);으로 JFrame(String title)을 호출

2. Button 생성은 맴버필드에서 생성해서 사용

 

3. JFrame의 기본 Layout은 BorderLayoutManager

: 특별한 지정 없을 시, Component는 무조건 센터에 배치

: 다른 layout은 

import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.BorderLayout;
import java.awt.FlowLayout;

public class JFrameExam extends JFrame { // BoderLayoutManager를 기본으로 가짐
	JButton btn1 = new JButton("클릭 1");
	JButton btn2 = new JButton("클릭 2");	
	
	
	/**화면 구성은 주로 생성자에서 작성*/
	public JFrameExam() {
		super("JFrame 실습입니다.");
		
		// JFrame의 LayoutManager를 변경
		setLayout(new FlowLayout());
		
		// JButton 추가
		add(btn1);
		add(btn2);
		
		//창의 크기
		setSize(500,400);
		
		//창의 위치 설정
		//setLocation(300,200); // 가로(x) 300, 높이(y) 200에 위치
		setLocationRelativeTo(null); // 창의 크기가 정해진 이후 정중앙에 위치
		
		//화면 보여줘
		setVisible(true);
		
		//x를 클릭하면 프로그램 종료
		setDefaultCloseOperation(JFrameExam.EXIT_ON_CLOSE);
	}

	public static void main(String[] args) {
		new JFrameExam(); 

	}

}

화면 결과:


Event 처리

: import java.awt.event.*;

: 사용자의 액션이 일어날 때, 처리해야 하는 기능

: 각 액션에 해당하는 즉 이벤트 종류마다 interface가 이미 다 정의되어 있다. - EventHandler

: 필요한 이벤트에 해당하는 interface를 implement해서 메소드 재정의로 기능을 만들어서 사용

: 이벤트 핸들러에 해당하는 interface들은 모두 XxxListener로 만들어져 있다.

: XxxListener를 직접 implements를 하게 되면 모든 메소드를 재정의 해야하는 번거로움이 있음

: 이러한 번거로움을 해결하기 위해서 이미 interface를 implemens를 해놓은 XxxAdapter클래스를 제공

  즉, XxxAdapter클래스는 Abstract 클래스로서 상속을 받아서 필요한 메소드만 재정의하면 된다.

: 보통 Listener와 Adapter가 1:1로 구성되어 있음

: 단, XxxListener 안에 메소드가 한 개만 있는 경우는 XxxAdapter는 없다!

 

**중요 포인트

: XxxListener(interface) implements 시는 모든 메소드 오버라이딩;

: XxxAdapter클래스는 상속 받아서 사용 // 주의사항: 상속은 한 클래스당 한 번만 가능

public abstract class XxxAdapter implements XxxListener{

          // 메소드가 모두 재정의 됨;

}

 

 

Event 처리 방법

ex) btn1을 클릭했을 때 "안녕"이라고 출력한다.

 

1) 이벤트를 발생시키는 주체(Component)를 찾는다. → 주체: btn1

2) 1)에서 찾은 주체에 발생할 수 있는 이벤트 종류를 찾는다.  → 많은 XxxEvent 중 어떤 이벤트인지 찾는다.

     ex) 버튼이 눌러지는 것은 주로 ActionEvent

3) 2)에서 찾은 XxxEvent에 해당하는 XxxListener 또는 XxxAdapter를 선택해서 메소드를 재정의한다.

    ex) ActionEvent → ActionListener → (ActionAdapter)  

4) 이벤트 등록: 이벤트 발생주체. addXxxListener(이벤트 처리객체);

    : 주로 화면구성 클래스의 생성자 마지막부에서 호출

 

**이벤트 등록 시 매개 변수 = 이벤트 처리 객체

  1. this: 이벤트 처리를 현재 객체가 했을 때

  2. new 객체(): 이벤트 처리를 외부의 객체가 했을 때

 

이벤트 담당 클래스들은 GUI를 담당하는 클래스와 밀접한 관련을 가짐; 

클래스들이 계속 분리가 되면, 화면 구성을 담당하는 각 요소들을 이벤트 클래스 생성자의 인수로 계속 넘겨줘야 함; 

이너클래스의 사용

class A{
	JTextField text;
    
    //이너클래스
    class B{
    
        //이너클래스: A의 입장에서는 필드와 동일하나 class이므로 상속, 구현이 가능;
        // Outer class에 있는 모든 메소드, 모든 필드를 접근할 수 있다.
        // Outer class 없이는 class B를 다시 재사용할 수 없음; (재사용성 떨어짐)
    
    }
    
}

OuterClass의 요소들 접근 시: outclass이름.this.----;

컴파일 시

A.class

A$B.class

 

 3. 익명이너클래스: 이벤트 등록과 동시에 이벤트 처리를 함께 했을 때

이너클래스가 1회성으로 사용될 때

A$1.class

A$2.class

A$3.class

// 이름이 없어서 번호가 라벨링됨

 


Inner클래스 선언 위치 3가지 

1) 인스턴스 맴버클래스

: non-static 이너클래스 안에서 static 선언은 안된다.
: 단, java version 16이상부터 가능하다. 
: static은 객체 생성 없이 접근 가능, 그러나 인스턴스 innerClass는 객체 생성 없이는 접근 불가
: static 필드, static 메소드 접근은 가능

:클래스 앞에 access modifer(접근제한자) 4가지 모두 선언 가능 (↔ outerClass에는 def, 또는 public만 올 수 있음)

class Test{
	
	int a = 10;
	static int b = 5;
	
	public void aa() {
		
	}
	
	public static void bb() {
		
	}
	
	class InstanceInner{
		int a = 7;
		//static int c =100;
		
		public void test() {
			System.out.println(a); // 7
			System.out.println(this.a); // 7
			System.out.println(Test.this.a); // 10
			
			System.out.println(b);
			System.out.println(Test.b);
			
			aa();
			bb();
			
		}
		
		/*static void test2() {
			
		}*/
		
	}

 

인스턴스 맴버클래스 호출 예시)

public class InnerAccessExam {

	public static void main(String[] args) {
		System.out.println("--1. 인스턴스 맴버클래스-----------------");
		Test t = new Test();
		Test.InstanceInner ti = t.new InstanceInner(); // Test 객체 안의 이너클래스 생성
		ti.test();
	}
}

 

2) 정적(static) 맴버클래스

: 클래스 앞에 access modifer(접근제한자) 4가지 모두 선언 가능

class A{
	static class B{
    
    }
}

: static 키워드는 원래 class에 올 수 없지만 inner 클래스에는 올 수 있다.

 

3) 로컬 이너 클래스 - 메소드 내부에 선언

: access modifier 올 수 없고, static 선언이 불가
: static 선언은 로컬에는 올 수 없었기 때문

class Test{

	public void test2() {
		
  	    	  class LocalInner { 
			int a=3;
			//static int b = 7;
			
			public void aa() {
				System.out.println("LocalInner의 aa() 메소드 호출됨...");
				
			}
					
	 	   } // LocalInnerEnd
		
        	//로컬 이너클래스는 Outer메소드 안에서만 접근 가능 
		LocalInner li = new LocalInner();
		li.aa();
	
	}
}

public class InnerAccessExam {

	public static void main(String[] args) {
		
		System.out.println("----------------Local 이너클래스-----------------");
		t.test2();

	}

}

 


IOStream 

: 입출력에 관련된 API 제공

: import java.io.*;

: 단방향 Stream이다. // 하나의 클래스가 읽고 쓰기를 동시에 하지 못함;

: 읽기(입력) 전용, 쓰기/저장(출력)전용 클래스가 따로 있음;

: 예외 처리 필수!! - 체크 예외이다.

 

1. byte 단위 처리

:1 byte 씩 읽고 쓰기 처리

: 영문, 숫자는 1 byte, 한글은 2 byte

: 즉, 한글은 두 번에 나눠 읽고 쓰기 처리

  읽기 = 입력                 : InputStram

  쓰기 = 저장 = 출력      : OutputStream

 

2. 문자 단위 처리

: 1개의 character씩 읽고 쓰기 처리

: 바이트에 관계 없이 문자 하나씩 읽고 쓰기 처리

ex) 채팅 

  읽기 = 입력                 : Reader

  쓰기 = 저장 = 출력      : Writer

 

 

*InputStram, OutputStream, Reader, Writer 클래스는 모두 abstract 클래스이다. - 직접 사용하지 않음;

: abstract 클래스를 이미 상속해놓은 수많은 서브 클래스를 제공한다!!! 

ex) FileInputStream extends InputStream - byte 단위로 파일을 읽어들임; 

 

**용어 정리

1) 노드 Stream

: 읽기, 쓰기를 위해서 반드시 필요한 Stream으로 바로 읽기, 쓰기가 가능한 것

 

2) 보조 Stream = 필터 Stream

: 보조 Stream 없이도 읽고 쓰기를 할 수 있음

: 중간에 보조 Stream을 걸쳐 성능 향상 또는 원하는 데이터 타입으로 변환하는 등 필요한 가공을 할 수 있도록 도와주는 Stream

ex) Buffered는 항상 사용을 권장한다.

**Buffer: 임시 저장소 - 읽고 쓰기를 할때 일정량의 데이터를 모아두었다가 한 번에 읽기, 쓰기 처리

               buffer 없이는 데이터를 하나하나씩 읽기, 쓰기 처리함으로써 처리 속도가 느림; 

 


File 클래스

: 파일의 크기, 속성, 이름 등의 정보를 얻어내거나 생성 및 삭제하는 등의 파일 가공 기능 등을 제공 

 

File의 입출력 참조 자료:

 

자바(JAVA) 파일 입출력(I/O)

파일 입출력 File java.io 패키지에서 제공하는 File 클래스는 파일 크기, 파일 속성, 파일 이름등의 정보를 얻어내는 기능과 파일 생성 및 삭제 기능을 제공한다. File file = new File("C:/Temp/file.txt"); OR..

loco-motive.tistory.com

 

파일을 byte 단위로 읽기

: FileInputStream

  - read() // 오버로딩이 많이 되어 있음

파일을 byte 단위로 쓰기

: FileOutputStream

  - write()

 

**중요

읽기 또는 쓰기를 할 때,

try{
    1) 필요한 객체를 생성한다
    2) 읽기 또는 쓰기를 한다.
 } catch(XxxException e){
 
 } finally{
    3) 사용한 객체는 반드시 닫는다. - close() // 중요 포인트
 }

- byte단위 읽기에 Buffered 사용

BufferedInputStream

: 반드시 노드 Stream이 있어야만 생성 가능 (생성자 인수: InputStream)

 

 

- byte단위 쓰기에 Buffered 사용

BufferedOutputStream

Comments