• 검색 결과가 없습니다.

이벤트 처리

N/A
N/A
Protected

Academic year: 2022

Share "이벤트 처리 "

Copied!
29
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

자바 프로그래밍

(OCJP 국제공인자격 취득 중심 )

충북대학교 정보통신공학부 최민

(2)

이벤트 처리

지금까지 GUI를 구성하는 Component의 종류와 이

Component들을 Container 위에 적절하게 배치하기 위한 LayoutManager를 학습하였음

앞에서 만들었던 GUI 프로그램은 모양만 그럴듯할 뿐, 실제 Button을 누르거나, Frame 우측 상단의 X 표시를 클릭해도 아무런 동작을 하지 않음

이벤트 처리가 포함되어 있지 않기 때문

이벤트(Event)

프로그램과 관계 있는 외부의 사건으로서 주로 사용자에 의해서 일 어나는데, 사용자가 Button을 마우스로 누르거나, Frame 우측 상단 의 X 표시를 클릭해서 윈도우를 닫는 것, 마우스를 움직이고, 키보드 를 누르는 것 등이 이벤트의 예

(3)

이벤트 처리

위임형 이벤트 모델(Delegation Event Model)

이러한 각각의 이벤트가 발생했을 때 프로그램 안에서 적절한 처리 를 해야 하는데, jdk1.1 이후의 자바에서는 GUI를 표시하는 클래스와 는 별도로 새 클래스를 만들어서 이벤트 처리를 맡기는 방법을 사용 합니다.

위임형 이벤트 모델인 경우, 이벤트 처리를 위한 프로그램에 서는 다음과 같은 내용이 반드시 포함되어야 함

(4)

이벤트 처리

1. import java.awt.event.*;

▶ 이벤트 처리용 클래스 import

2. c.addXXXListener(new XXXClass( ));

▶ 이벤트 소스 Component와 이벤트 처리용 리스너 클래스 연결 c : 이벤트를 처리하고자 하는 Component에 대한 핸들

XXX : 처리하고자 하는 이벤트의 종류

3. class XXXClass implements XXXListener { (또는) class XXXClass extends XXXAdapter { ▶ 이벤트 처리용 리스너 클래스 정의

XXXListener : 처리하고자 하는 이벤트와 관련된 메소드 선언을 가지고 있는 인터페이스

XXXAdapter : 처리하고자 하는 이벤트와 관련된 메소드 선언을

가지고 있는 클래스

(5)

이벤트 처리

[NOTE]

이벤트 처리 클래스를 작성할 때 원칙적으로 자신이 처리하고자 하 는 이벤트에 대한 메소드가 선언되어 있는 Listener 인터페이스를 implements해야 합니다.

그런데 메소드 선언이 여러 개 있는 Listener 인터페이스를

implements하려면 자신이 오버라이드하고자 하는 메소드뿐만 아니 라, 다른 메소드도 모두 오버라이드하여야 하는 불편이 있기 때문에 두 개 이상의 메소드가 선언되어 있는 Listener 인터페이스에 대해서 는 대응하는 Adapter 클래스가 제공됩니다. Adapter 클래스를

extends하는 경우에는 모든 메소드를 오버라이드할 필요는 없기 때 문에 실제 구현하려는 메소드만 오버라이드하면 됩니다.

(6)

이벤트 처리

위에서 제시한 내용을 프로그램으로 구현하면 다음과 같은 구조가 됩니다.

import java.awt.*;

import java.awt.event.*; // 이벤트 처리를 위한 패키지 import

public class EventTest extends Frame {

Button bClear; // 표시할 Component 선언

public static void main(String[ ] args) {

/* 자기 자신 클래스에 대한 오브젝트 생성 */

/* display( ) 메소드 호출 */

}

EventTest(String title) {

/* 각 Component에 대한 오브젝트 생성, 초기화 */

}

(7)

이벤트 처리

void display( ) {

/* 각 Component 붙이기 */

bClear.addActionListener(new ActionHandle( ));

/* 이벤트 소스에 이벤트 처리 클래스 등록 */

/* 화면에 표시 */

} }

class ActionHandle implements ActionListener { // 이벤트 처리를 위한 클래스 정의 public void actionPerformed(ActionEvent e) {

/* 이벤트가 발생했을 때의 처리 내용 */

}

}

(8)

이벤트 처리

그런데 이와 같이 Component에 대한 오브젝트를 생성, 표 시하는 GUI 클래스와 이벤트를 처리하는 클래스가 분리되어 있는 경우, 처리 내용에 따라 클래스가 구성되므로 알아보기 쉬운 프로그램을 작성할 수 있다는 장점이 있는 반면에, 클래 스간에 정보 공유가 어렵다는 단점

예를 들어 Label이 윗쪽에 있고, Button이 아랫쪽에 있어서 아랫쪽의 Button을 누르면 윗쪽 Label에 Button에 지정된 내용을 출력하는 프로그램을 가정(예:전자계산기).

때, Button을 눌렀을 때 수행되는 메소드는 이벤트 처리 클래스에 있고, Label에 대한 핸들 변수는 GUI 클래스에 있 것이므로 쉽게 참조할 수 없음

(9)

이벤트 처리

내부 클래스(inner class)를

클래스를 분리함으로써 프로그램이 간결하다는 장점을 그대로 살리 면서 클래스간에 정보 공유를 쉽게 할 수 있는 방법

JAVA 1.1 이후에 내부 클래스 문법이 추가된 것은 이러한 이벤트 처리 방법과 무관하지 않음

내부 클래스를 이용해서 이벤트를 처리하는 기본 구조는 다 음과 같음

(10)

이벤트 처리 – inner class 사용

import java.awt.*;

import java.awt.event.*; // 이벤트 처리를 위한 패키지 import

public class EventTest extends Frame {

Button bClear; // 표시할 Component 선언

public static void main(String[ ] args) {

/* 자기 자신 클래스에 대한 오브젝트 생성 */

/* display( ) 메소드 호출 */

}

EventTest(String title) {

/* 각 Component에 대한 오브젝트 생성, 초기화 */

}

(11)

이벤트 처리 – inner class 사용

void display( ) {

/* 각 Component 붙이기 */

bClear.addActionListener(new ActionHandle( ));

/* 이벤트 소스에 이벤트 처리 클래스 등록 */

/* 화면에 표시 */

class ActionHandle implements ActionListener { // 이벤트 처리를 위한 클래스 정의 public void actionPerformed(ActionEvent e) {

/* 이벤트가 발생했을 때의 처리 내용 */

} } }

(12)

이벤트 처리

내부 클래스를 이용한 이벤트 처리의 기본적인 구조도 앞에 배운 이벤트 처리 구조와 거의 똑같습니다. 다만, 이벤트 처리 클래스가 GUI 클래스 안에 있다는 차이만 있지요. 따라, 이벤트 처리 클래스 안에서는 GUI 클래스에 있는 멤버 변수를 마음대로 쓸 수 있게 되었습니다.

그런데 이 방법보다 더 간단한 방법도 있습니다. 바로 ‘익명 내부 클래스(ano nymous inner class)'를 이용하는 것인, 이 경우 프로그램의 구조는 다음과 같습니다.

(13)

이벤트 처리 – anonymous class 사용

import java.awt.*;

import java.awt.event.*; // 이벤트 처리를 위한 패키지 import

public class EventTest extends Frame {

Button bClear; // 표시할 Component 선언

public static void main(String[ ] args) {

/* 자기 자신 클래스에 대한 오브젝트 생성 */

/* display( ) 메소드 호출 */

}

EventTest(String title) {

/* 각 Component에 대한 오브젝트 생성, 초기화 */

(14)

이벤트 처리 – anonymous class 사용

void display( ) {

/* 각 Component 붙이기 */

bClear.addActionListener(

new ActionListener( ) {

public void actionPerformed(ActionEvent e) { /* 이벤트가 발생했을 때의 처리 내용 */

} }

); // 이벤트 처리 클래스 작성, 등록

/* 화면에 표시 */

} }

(15)

이벤트 처리 – anonymous class 사용

경우에는 내부 클래스에 별도의 이름을 붙이지 않고, 내용 통째로 add XXXListener 메소드의 인수로 넘겼습니다.

방법은 이벤트 발생시 처리 내용이 간단하고, 중복되는 이 벤트 처리 내용이 없는 경우에만 사용하는 것이 좋습니다.

(16)

기본 예제

예제에서는 Button과 TextField로 구성된 Frame을 만 들고, Button을 누르면 TextField의 내용을 지우고,

Frame 우측 상단의 X표를 클릭하면 프로그램을 종료시키는 처리를 하고 있습니다.

import java.awt.*;

import java.awt.event.*;

public class EventTest extends Frame { Button bClear;

TextField tf;

public static void main(String[ ] args) {

EventTest et = new EventTest("Event 예제");

et.display( );

}

EventTest(String title) { super(title);

tf = new TextField( );

bClear = new Button("지워주세요");

(17)

기본 예제

void display( ) {

setLayout(new GridLayout(0, 1));

add(tf);

add(bClear);

bClear.addActionListener(new ActionHandle( ));

addWindowListener(new WindowHandle( ));

pack( );

setVisible(true);

}

class ActionHandle implements ActionListener {

public void actionPerformed(ActionEvent e) {

(18)

기본 예제

class WindowHandle implements WindowListener { public void windowClosing(WindowEvent e) {

System.exit(1);

}

public void windowOpened(WindowEvent e) { } public void windowClosed(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowActivated(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } }

}

(19)

기본 예제

예제는 ActionListener와 WindowListener를 각각 구 현한 이벤트 처리용 리스너 클래스를 내부 클래스로 작성하, 메소드를 오버라이드함으로써 이벤트 처리를 하고 있습 니다. 사실, 한 클래스에서 인터페이스는 두 개 이상 지정하 모두 구현할 수 있으므로 이벤트 처리용 리스너를 하나의 클래스로 통합하는 것도 가능합니다.

그런데 WindowListener를 구현한 WindowHandle 리스 클래스의 경우, 인터페이스에 선언되어 있는 모든 메소드 를 오버라이드해야 한다는 문법적인 이유 때문에 실제로 오 버라이드할 필요 없는 메소드까지도 모두 한 번씩 이름을 써

(20)

기본 예제

예제는 앞의 예제와 기능은 같지만, 처리 방법이 다릅니다.

, 이벤트 처리용 리스너 클래스 작성시 리스너 인터페이스 이용한 것이 아니라, 어댑터 클래스를 이용함으로써 불필 요한 코드를 줄일 수 있었습니다.

import java.awt.*;

import java.awt.event.*;

public class EventTest2 extends Frame {

Button bClear;

TextField tf;

public static void main(String[ ] args) {

EventTest2 et = new EventTest2("Event 예제2");

et.display( );

}

EventTest(String title) {

super(title);

(21)

기본 예제

void display( ) {

setLayout(new GridLayout(0, 1));

add(tf);

add(bClear);

bClear.addActionListener(new ActionHandle( ));

addWindowListener(new WindowHandle( ));

pack( );

setVisible(true);

}

class ActionHandle implements ActionListener { public void actionPerformed(ActionEvent e) { tf.setText("");

}

}

(22)

예제에서는 WindowListener 인터페이스 대신에

WindowAdapter 클래스를 이용함으로써 프로그램을 좀더 간단하게 만들 수 있었습니다. 이처럼 모든 두 개 이상의 메 소드가 정의되어 있는 리스너 인터페이스에 대해서 대응하는 어댑터 클래스를 이용하면 좀더 간결한 코드를 만들 수 있습 니다. 다만, 이런 경우에 한 클래스에서 두 개 이상의

Adapter 클래스를 상속받을 수는 없습니다.

(23)

기본 예제

예제도 앞의 예제와 기능은 같지만, 처리 방법이 다릅니다.

, 이벤트 처리용 리스너 클래스 작성시 리스너 클래스를 별 도로 작성한 것이 아니라, addWindowListener() 메소드 호출시 클래스의 내용을 직접 넘겨주었습니다.

import java.awt.*;

import java.awt.event.*;

public class EventTest3 extends Frame {

Button bClear;

TextField tf;

public static void main(String[ ] args) {

EventTest2 et = new EventTest3("Event 예제3");

et.display( );

}

EventTest(String title) {

(24)

기본 예제

void display( ) {

setLayout(new GridLayout(0, 1));

add(tf);

add(bClear);

bClear.addActionListener(new ActionHandle( ));

addWindowListener(

new WindowAdapter( ) {

public void windowClosing(WindowEvent e) { System.exit(1);

} } );

pack( );

setVisible(true);

}

class ActionHandle implements ActionListener { public void actionPerformed(ActionEvent e) { tf.setText("");

}

(25)

기본 예제

void display( ) {

setLayout(new GridLayout(0, 1));

add(tf);

add(bClear);

bClear.addActionListener(new ActionHandle( ));

addWindowListener(

new WindowAdapter( ) {

public void windowClosing(WindowEvent e) { System.exit(1);

} } );

pack( );

setVisible(true);

}

class ActionHandle implements ActionListener { public void actionPerformed(ActionEvent e) { tf.setText("");

}

(26)

예제에서는 이벤트 처리용 리스너 클래스를 별도로 작성 하지 않고, addWindowListener( ) 메소드 호출시 직접 리 스너 클래스의 내용을 넘겨주었음(31 ~ 37행).

이렇게 작성하면 코드의 길이가 짧아진다는 장점이 있지만, 이벤트 처리용 리스너 클래스를 반복해서 사용할 수 없다는 단점

(27)

이벤트의 종류

앞서 이벤트 처리를 위한 프로그램의 구조에 대해서 공부아 진행 하셔도 좋을 그렇다면 이벤트에는 어떤 종류가 있으, 어떤 방식으로 처리해야 할까요?

다음 표는 중요한 이벤트의 종류와 이벤트를 처리하는 클래 작성시 상속받아야 하는 인터페이스(또는 클래스) 이름, 그리고 그 안에 정의되어 있는 메소드의 형태를 정리한 것입 니다.

(28)

분 류 Listener interface (Adapter class)

메소드명 (파라미터)

이벤트 소스 Component

Action

ActionListener

actionPerformed

(ActionEvent)

Button List MenuItem TextField

Item

ItemListener

itemStateChanged

(ItemEvent)

CheckBox Choice List

Mouse motion

MouseMotionListener (MouseMotionAdapter)

mouseDragged(MouseEvent)

mouseMoved(MouseEvent)

Component

Mouse

MouseListener (MouseAdapter)

mousePressed(MouseEvent) mouseReleased

(MouseEvent)

mouseEntered(MouseEvent) mouseExited(MouseEvent) mouseClicked(MouseEvent)

Component

Key

KeyListener

(KeyAdapter)

keyPressed(KeyEvent) keyReleased(KeyEvent)

keyTyped(KeyEvent)

Component

Window

WindowListener (WindowAdapter)

windowClosing(WindowEvent) windowOpened(WindowEvent) windowIconified

(WindowEvent) windowDeiconified (WindowEvent)

windowClosed(WindowEvent) windowActivated

(WindowEvent) windowDeactivated (WindowEvent)

Window

(29)

이벤트의 종류

예를 들어, Frame 위에서 마우스를 클릭하는 이벤트를 처리하고자 한다 어떻게 해야 할까요? 위의 표에 있는 Mouse 관련 이벤트 중에서 관 메소드를 찾아보면 mouseClicked( ) 메소드가 있군요. 따라서, 이벤 트 처리를 위한 리스너 클래스에서는 mouseClicked( ) 메소드를 오버 라이드하면 되겠고, Mou se 관련 이벤트 중에서 다른 이벤트는 처리하 않을 것이므로 그 클래스 옆에는 implements MouseListener라고 쓰지 말고, extends MouseAdapter라고 쓰면 되겠군요. 그러면 이벤 소스 클래스인 Frame 클래스에 어떻게 이벤트 리스너 클래스를 등록 할까요? 바로 addMouseListener( ) 메소드를 이용하여 지금 만든 리 스너 클래스의 오브젝트를 인수로 넘겨주면 되겠군요.

이와 같이 이벤트를 처리하는 클래스를 작성할 때 위의 표는 자주 참조하 게 되므로 잘 기억해 두세요.

참조

관련 문서

안테나의 보호 및 방수 처리 몰딩을

– 뇌파를 이용한 인터페이스, 감성컴퓨터, 뇌파로 가전기기 작동 – 촉각을 이용한 인터페이스 (Haptic Feedback).

 Maximum Event Precision From Training Prior: 이벤트 정밀도가 최대 가 되는 임계치를 설정한다.  Event Precision Equal Recall: 이벤트 정밀도와

업무 시스템의 이벤트 로그 데이터를 분석하여 실제 프로세스를 도출하고, 프로세스 개선을 지원하는 프로세스 마이닝 기반

Temperature Hysteresis Inside / Outside Temperature event에 대한 hysteresis 폭을 설정 이벤트 종료레벨은 (threshold - hysteresis) 이다. 범위: 1 - 120

행사 및 부대 이벤트 운영 행사 및 부대 이벤트 운영 행사 관련 제작물 제작 및 진행 버스킹, 예술공연 운영 행사 운영.. 개발사와 투자사,

폼을 열어 레코드들이 표시될 때 발 생하며, 이 이벤트는 Current 이벤트 전에 발생하고 Open 이벤트 후에 발 생함.

이산화탄소 플라스틱은