일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Java Programming
- ssafy
- 모두를 위한 컴퓨터 과학(CS50)
- exception
- 알고리즘
- WebProgramming
- CS 기초지식
- CS기초지식
- til
- 부스트코스
- 이진법
- ERD
- 예외처리
- Compute Science
- 면접을 위한 CS 전공지식 노트
- 데이터베이스 모델링
- edwith
- 모두를 위한 컴퓨터 과학
- 상속
- CS 기초
- Computer Science
- SW
- SSAFY 9기
- CS50
- 삼성청년SW아카데미
- 기초프로그래밍
- w3schools
- 관계형 데이터베이스
- java
- 객체지향
- Today
- Total
Joslynn의 하루
대용량 웹서비스를 위한 MSA Full-Stack 개발자 양성 과정 -16일차 노트 필기_GUI와 이벤트 처리, Inner class(이너클래스), IO Stream(입출력 API)_220811 본문
대용량 웹서비스를 위한 MSA Full-Stack 개발자 양성 과정 -16일차 노트 필기_GUI와 이벤트 처리, Inner class(이너클래스), IO Stream(입출력 API)_220811
Joslynn 2022. 8. 11. 18:16GUI 화면 구성
: 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의 입출력 참조 자료:
파일을 byte 단위로 읽기
: FileInputStream
- read() // 오버로딩이 많이 되어 있음
파일을 byte 단위로 쓰기
: FileOutputStream
- write()
**중요
읽기 또는 쓰기를 할 때,
try{
1) 필요한 객체를 생성한다
2) 읽기 또는 쓰기를 한다.
} catch(XxxException e){
} finally{
3) 사용한 객체는 반드시 닫는다. - close() // 중요 포인트
}
- byte단위 읽기에 Buffered 사용
BufferedInputStream
: 반드시 노드 Stream이 있어야만 생성 가능 (생성자 인수: InputStream)
- byte단위 쓰기에 Buffered 사용
BufferedOutputStream