프로그래밍 공부/Java

[ Java 프로그래밍 ] 공부 정리 - 9강. 자바의 이벤트 처리

호크테마 2023. 4. 30. 16:03

* 공부 정리일자 (2022년 8~12월) 
- 책 : 명품 자바 에센셜 
- 개인적으로 공부 및 복습하면서 정리한 내용입니다. (사진 제외) 


* 목차
9장. 자바의 이벤트 처리
9.1 이벤트 기반 GUI 프로그래밍
9.2 이벤트 객체
9.3 사용자 이벤트 리스너 작성
9.4 어댑터(Adapter) 클래스
9.5 Key 이벤트와 KeyListener
9.6 Mouse 이벤트와 MouseListener, MouseMotionListener 


1. 복습 (중요 키워드 위주)
9) 9강. 자바의 이벤트 처리 (책 354p)
9.1) 이벤트 기반 GUI 프로그래밍 (책 354p)

(1) 이벤트 기반 프로그래밍 (Event Driven Programming)
* 이벤트의 발생에 의해 프로그램 흐름이 결정되는 방식
- 이벤트가 발생하면 이벤트를 처리하는 루틴(이벤트 리스너) 실행
- 실행될 코드는 이벤트의 발생에 의해 전적으로 결정

* 반대되는 개념 : 배치 실행 (batch programming)
- 프로그램의 개발자가 프로그램의 흐름을 결정하는 방식

* 이벤트 종류
- 사용자의 입력 : 마우스 드래그, 마우스 클릭, 키보드 누름 등
- 센서로부터의 입력, 네트워크로부터 데이터 송수신 
- 다른 응용프로그램이나 다른 스레드로부터의 메시지

* 이벤트 기반 응용 프로그램의 구조
- 각 이벤트마다 처리하는 리스너 코드 보유

* GUI 응용프로그램은 이벤트 기반 프로그래밍으로 작성됨
GUI 라이브러리 종류
-- C++의 MFC, C# GUI, Visual Basic, X Window, Android 등
-- 자바의 AWT와 Swing

* 스윙 응용프로그램의 이벤트의 실제 예

(2) 자바 스윙 프로그램에서 이벤트 처리 과정
* 이벤트가 처리되는 과정
- 이벤트 발생
-- 예 :마우스의 움직임 혹은 키보드입력

* 이벤트 객체 생성
- 현재 발생한 이벤트에 대한 정보를 가진 객체

* 응용프로그램에 작성된 이벤트 리스너 찾기

* 이벤트 리스너 실행
- 리스너에 이벤트 객체 전달
- 리스너 코드 실행

* 자바의 이벤트 기반 스윙 응용프로그램의 구조와 이벤트 처리 과정


9.2) 이벤트 객체 (책 356p)
(1) 이벤트 객체
- 발생한 이벤트에 관한 정보를 가진 객체
- 이벤트 리스너에 전달됨
- 이벤트 리스너 코드가 
    발생한 이벤트에 대한 상황을 파악할 수 있게 함

(2) 이벤트 객체가 포함하는 정보 (이벤트 정보)
- 이벤트 종류와 이벤트 소스
- 이벤트가 발생한 화면 좌표 및 컴포넌트 내 좌표
- 이벤트가 발생한 버튼이나 메뉴 아이템의 문자열
- 클릭된 마우스 버튼 번호 및 마우스의 클릭 횟수
- 키의 코드 값과 문자 값
- 체크박스, 라디오버튼 등과 
   같은 컴포넌트에 이벤트가 발생하였다면 체크 상태

(3) 이벤트 소스를 알아 내는 메소드 (이벤트 소스)
- Object getSource()
- 발생한 이벤트의 소스 컴포넌트 리턴
- Object 타입으로 리턴하므로 캐스팅하여 사용
- 모든 이벤트 객체에 대해 적용

* 이벤트 객체와 이벤트 정보를 리턴하는 메소드
* 이벤트 객체, 이벤트 소스, 발생하는 경우


9.3) 사용자 이벤트 리스너 작성 (책 359p) 
(1) 리스너 인터페이스 
* 이벤트 리스너
- 이벤트를 처리하는 자바 프로그램 코드, 클래스로 작성

* 자바는 다양한 리스너 인터페이스 제공
예) ActionListener 인터페이스 – 버튼 클릭 이벤트를 처리하기 위한 인터페이스
예) MouseListener  인터페이스 – 마우스 조작에 따른 이벤트를 처리하기 위한 인터페이스

(2) 사용자의 이벤트 리스너 작성
- 자바의 리스너 인터페이스 (interface)를 상속받아 구현
- 리스너 인터페이스의 모든 추상 메소드 구현

* 자바에서 제공하는 이벤트 리스너 인터페이스

(2) 이벤트 리스너 작성 과정 사례
(2.1) 이벤트와 이벤트 리스너 선택
* 버튼 클릭을 처리하고자 하는 경우
- 이벤트 : Action 이벤트, 이벤트 리스너 : ActionListener

(2.2) 이벤트 리스너 클래스 작성 : ActionListener 인터페이스 구현

(2.3) 이벤트 리스너 등록
* 이벤트를 받아 처리하고자 하는 컴포넌트에 이벤트 리스너 등록
* component.addXXXListener(listener)
- xxx : 이벤트 명,  listener : 이벤트 리스너 객체

[ 이벤트 리스너 작성 방법 – 3가지 ]
* 독립 클래스로 작성
- 이벤트 리스너를 완전한 클래스로 작성
- 이벤트 리스너를 여러 곳에서 사용할 때 적합

* 내부 클래스(inner class)로 작성
- 클래스 안에 멤버처럼 클래스 작성
- 이벤트 리스너를 특정 클래스에서만 사용할 때 적합

* 익명 클래스(anonymous class)로 작성
- 클래스의 이름 없이 간단히 리스너 작성
- 클래스 조차 만들 필요 없이 리스너 코드가 간단한 경우에 적합

* 예제 9-1 : 독립 클래스로 Action 이벤트 리스너 만들기
* 예제 9-2 : 내부 클래스로 Action 이벤트 리스너 만들기

(2.4) 익명 클래스로 이벤트 리스너 작성
* 익명 클래스(anonymous class) : 이름 없는 클래스
- (클래스 선언 + 인스턴스 생성)을 한번에 달성

* 간단한 리스너의 경우 익명 클래스 사용 추천
- 메소드의 개수가 1, 2개인 리스너(ActionListener, ItemListener)에 대해 주로 사용

* ActionListener를 구현하는 익명의 이벤트 리스너 작성 예
* 예제 9-3 : 익명 클래스로 Action 이벤트 리스너 만들기
* 예제 9-4 : 마우스 이벤트 리스너 작성 연습 - 마우스로 문자열 이동시키기
- 아래 실행 화면과 같이  프레임의 임의의 위치에 마우스 버튼을 누르면 마우스 포인터가 있는 위치에"Hello" 문자열을 출력하는 프로그램을 작성하라.

- 마우스 버튼을 누르면 마우스가 있는 위치로 "Hello" 문자열을 이동시킨다.
- 이벤트와 리스너 : MouseEvent와 MouseListener
- 이벤트 소스 : 컨텐트팬 
- 컨텐트팬의 배치관리자 : 배치관리자 삭제
- 구현할 리스너의 메소드 : mousePressed()
- "Hello" 문자열 : JLabel 컴포넌트 이용

* 예제 9-4의 정답


9.4) 어댑터(Adapter) 클래스 (책 367p) 
* 이벤트 리스너 구현에 따른 부담
- 리스너의 추상 메소드를 모두 구현해야 하는 부담
예) 마우스 리스너에서 
    마우스가 눌러지는 경우(mousePressed())만 처리하고자 하는 경우에도 나머지 4 개의 메소드를 모두 구현해야 하는 부담

* 어댑터 클래스(Adapter) 
- 리스너의 모든 메소드를 단순 리턴하도록 만든 클래스(JDK에서 제공)
- MouseAdapter 예

* 추상 메소드가 하나뿐인 리스너는 어댑터 없음
- ActionAdapter, ItemAdapter 클래스는 존재하지 않음

* MouseListener대신 MouseAdapter를 사용한 예
* JDK에서 제공하는 어댑터 클래스

* 예제 9-5 : MouseAdapter로 마우스 리스너 작성
- MouseAdapter를 이용하여 예제 9-4를 수정하라.


9.5) Key 이벤트와 KeyListener (책 370p) 
(1) Key 이벤트와 포커스
* 키 입력 시, 다음 세 경우 각각 Key 이벤트 발생
- 키를 누르는 순간 
- 누른 키를 떼는 순간
- 누른 키를 떼는 순간(Unicode 키의 경우에만)

* 키 이벤트를 받을 수 있는 조건
- 모든 컴포넌트
- 현재 포커스(focus)를 가진 컴포넌트가 키 이벤트 독점

* 포커스(focus)
- 컴포넌트나 응용프로그램이 키 이벤트를 독점하는 권한
- 컴포넌트에 포커스 설정 방법 : 다음 2 라인 코드 필요

- 자바플랫폼마다 실행 환경의 초기화가 서로 다를 수 있기 때문에 다음 코드가 필요함component.setFocusable(true); 

(2) KeyListener
* 응용프로그램에서 KeyListener를 상속받아 키 리스너 구현
* KeyListener의 3 개 메소드

* 컴포넌트에 키 이벤트 리스너 달기

(3) 유니코드(Unicode) 키 ?
* 유니코드 키의 특징
- 국제 산업 표준
- 전 세계의 문자를 컴퓨터에서 일관되게 표현하기 위한 코드 체계
- 문자들에 대해서만 키 코드 값 정의
-- A~Z, a~z, 0~9, !, @, & 등
- 문자가 아닌 키 경우에는 표준화된 키 코드 값 없음
-- <Function> 키, <Home> 키, <Up> 키,<Delete> 키, 
    <Control> 키, <Shift> 키, <Alt> 등은 플랫폼에 따라 키 코드 값이 다를 수 있음

* 유니코드 키가 입력되는 경우
- keyPressed(), keyTyped(), keyReleased() 가 순서대로 호출

* 유니코드 키가 아닌 경우
- keyPressed(), keyReleased() 만 호출됨

(4) 가상 키와 입력된 키 판별
* KeyEvent 객체
- 입력된 키 정보를 가진 이벤트 객체
- KeyEvent 객체의 메소드로 입력된 키 판별

* KeyEvent 객체의 메소드로 입력된 키 판별
- char KeyEvent.getKeyChar()
-- 키의 유니코드 문자 값 리턴
-- Unicode 문자 키인 경우에만 의미 있음
-- 입력된 키를 판별하기 위해 문자 값과 비교하면 됨

- int KeyEvent.getKeyCode()
-- 유니코드 키 포함 
-- 모든 키에 대한 정수형 키 코드 리턴
-- 입력된 키를 판별하기 위해 
    가상키(Virtual Key) 값과 비교하여야 함
-- 가상 키 값은 KeyEvent 클래스에 상수로 선언

* 가상 키 (Virtual Key)
- 가상 키는 KeyEvent 클래스에 상수로 선언
- 가상 키의 일부 소개

* 예제 9-6 : KeyListener 활용 – 입력된 문자 키 판별
- 컨텐트팬에 <Enter> 키를 입력할 때마다 배경색을 랜덤하게 바꾸고, 'q' 키를 입력하면 프로그램을 종료시켜라.

- 컨텐트팬에 키 리스너를 달고, 포커스를 주어, 키 입력을 받도록 해야 한다. 
- 색은 new Color(int r, int g, int b)로 생성한다. 
     r(red), g(green), b(blue)는 색의 3요소로서 0~255 사이의 값이다.

* 예제 9-6 정답 
* 예제 9-7 : KeyListener 활용 – 상, 하, 좌, 우 키로 문자열 움직이기
- 상, 하, 좌, 우 키를 입력하면, 다음 그림과 같이 "HELLO" 문자열이 10픽셀씩 이동하는 프로그램을 작성하라.


- 상,하,좌,우 키를 움직이면 한 번에 10픽셀씩 "HELLO" 텍스트는 상,하,좌,우로 이동한다.
   이 텍스트는 프레임의 영역을 벗어나서 움직일 수 있다.

* 예제 9-7 정답


9.6) Mouse 이벤트와 MouseListener, MouseMotionListener (책 376p)  
(1) Mouse 이벤트 : 사용자의 마우스 조작에 따라 발생하는 이벤트
- mouseClicked() : 마우스가 눌러진 위치에서 그대로 떼어질 때 호출
- mouseReleased() : 마우스가 눌러진 위치에서 그대로 떼어지든 아니든 항상 호출
- mouseDragged(): 마우스가 드래그되는 동안 계속 여러번 호출

* 마우스가 눌러진 위치에서 떼어지는 경우 메소드 호출 순서
* 마우스가 드래그될 때 호출되는 메소드 호출 순서

(2) 마우스 리스너 달기와 MouseEvent 객체 활용
* 마우스 리스너 달기
- 마우스 리스너는 컴포넌트에 다음과 같이 등록

* 컴포넌트가 마우스 무브(mouseMoved())나 마우스 드래깅(mouseDraggecd())을 함께 처리하고자 하면,  
   MouseMotion 리스너 따로 등록

* MouseEvent 객체 활용
- 마우스 포인터의 위치, 컴포넌트 내 상대 위치
-- int getX(), int getY()

- 마우스 클릭 횟수
-- int getClickCount()

* 마우스 이벤트 처리 예 : MouseListener와 MouseMotionListener 
* 마우스 이벤트 처리 실행