Lesson 11. 이벤트
이벤트와 이벤트 처리 이벤트(Event): 프로그램에서 사용자로부터 프로그램에게 어떠한 일이 발생했다는 것을 알리는 통신 수단 객체의 이벤트: 사용자가 해당 객체에 특정 조작을 하면 컴퓨터로부터 발생되는 일종의 신호 예) 버튼을 마우스 왼쪽 버튼으로 누르는 행위, 텍스트필드 등에 키보드를 이용해 입력한 행위, 마우스 커서를 옮기는 행위, 윈도우의 크기를 조절하는 행위 등 발생한 이벤트를 처리하기 위해 필요한 자바의 메소드나 함수를 이벤트 처리기(Event Handler)라 함
이벤트란? 이벤트 소스 : 마우스, 키보드, GUI 컴포넌트 이벤트 클래스 이벤트 핸들러: 이벤트 발생 시 처리하는 프로그램 AWTEvent의 서브클래스 가상머신에 미리 정해져 있음 이벤트 핸들러: 이벤트 발생 시 처리하는 프로그램 프로그렘 해서 이벤트소스와 연결해야 함 * 343페이지 참조
이벤트 처리 과정과 위임형 이벤트 모델 아래 그림처럼 윈도우 메시지 창에 포함된 버튼 컴포넌트를 클릭해 이벤트를 발생시키면, 마우스 클릭 이벤트가 처리되어 오른쪽 그림처럼 파일 대화상자가 열린다. 이벤트를 발생시키는 버튼이라는 소스 객체로부터 이벤트를 기다리는 리스너 객체로 전달. 버튼 컴포넌트를에서 마우스를 클릭, 이벤트 발생
이벤트 소스와 이벤트 리스너 방식 이벤트를 받고 싶은 이벤트 소스에 이벤트 리스너로 객체가 등록하면 이벤트발생 시 등록된 객체에 이벤트를 전달함 리스너 등록: 컴포넌트가 가지고 있는 addXXXListener()메소드를 호출하여 등록 이벤트는 운영체제의 이벤트를 자바가상머신이 받아 처리 가상머신은 이벤트객체를 만든 후 버튼객체로 전달 버튼객체는 리스너로 등록된 모든 객체로 전달 addXXXListener()
리스너를 이용한 이벤트 처리 이벤트 소스와 이벤트 클래스 결정 이벤트 리스너를 상속받아 이벤트 핸들러 작성 이벤트 관련 패키지를 import 예) import java.awt.event.*; 이벤트 리스너를 상속받아 이벤트 핸들러 작성 - 이벤트리스너 인터페이스를 상속받아 해당 메소드를 구현함(344Page) 이벤트 소스와 이벤트 핸들러 연결
1. 이벤트 소스와 이벤트 클래스 결정 컴포넌트 이벤트 클래스 Button ActionEvent MenuItem Checkbox ItemEvent Scrollbar AdjustmentEvent CheckboxMenuItem ScrollPane Choice TextComponent TextEvent Component TextField Container ContainerEvent Window WindowEvent List ActionEvent, ItemEvent
- 컴포넌트 계층 구조
컴포넌트와 발생시키는 이벤트 클래스의 관계 이벤트 명 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ActionEvent ● TextEvent ItemEvent AdjustmentEvent MouseEvent MouseMotionEvent KeyEvent WindowEvent FocusEvent ComponentEvent ContainerEvent ( 1: Button, 2: Label, 3: Choice, 4: List, 5: Checkbox, 6: CheckboxMenuItem, 7:Scrollbar, 8:ScrollPane, 9: TextField, 10:TextArea, 11: Textcomponent, 12: Canvas, 13: MenuItem, 14: Component, 15: Container, 16: Frame, 17: Panel 18: Dialog, 19: Window )
2. 이벤트 핸들러 작성 이벤트핸들러 : 이벤트 발생시 실행되는 루틴 이벤트 리스너 인터페이스를 이용하여 Over-riding함 각 이벤트에 해당하는 리스너를 상속받아 Over-riding * 필수 : import java.awt.event.*; 각 이벤트에 해당하는 이벤트 리스너 : 344Page 이벤트 리스너는 인터페이스이므로 하위클래스에서는 반드시 구현해야 함
이벤트 핸들러 작성 import java.awt.event.*; class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent e) System.out.println("버튼이 눌러졌습니다!"); }
adjustementValueChanged() - 이벤트 리스너(344페이지) 이벤트 클래스 리스너 인터페이스 리스너 메소드 ActionEvent ActionListener actionPerformed() AdjustmentEvent AdjustmentListener adjustementValueChanged() ComponentEvent ComponentListener 4개 메소드 ContainerEvent ContainerListener 2개 메소드 FocusEvent FocusListener ItemEvent ItemListener itemStateChanged() KeyEvent KeyListener 3개 메소드 MouseEvent MouseListener 5개 메소드 MouseMotionListener TextEvent TextListener textValueChanged() WindowEvent WindowListener 6개 메소드
3. 이벤트 소스와 이벤트 핸들러 연결 하나의 이벤트소스에서 발생하는 여러 개의 이벤트 중 사용할 이벤트 만을 선택하여 이벤트 핸들러와 연결 순서 이벤트 핸들러 객체를 생성한 후 이벤트 소스의 addXXXListener() 메소드를 이용하여 이벤트 소스에 핸들러를 등록(XXX는 이벤트 이름 ) 예) ActionEvent일 경우 addActionListener()
3. 이벤트 소스와 이벤트 핸들러 연결 <MyActionListener를 myButton에 연결하는 예 > import java.applet.Applet; import java.awt.*; public class MyApplet extends Applet { Button myButton; public void init() myButton= new Button("내 버튼"); MyActionListener mal= new MyActionListener(); MyButton.addActionListener(mal); add(myButton); } 이벤트 핸들러 객체 생성 생성된 객체를 인수로 전달
마우스 이벤트 처리 리스너 인터페이스 리스너 메소드 MouseListener mouseClicked(MouseEvent e) mouseEntered(MouseEvent e) mouseExited(MouseEvent e) mousePressed(MouseEvent e) mouseReleased(MouseEvent e) MouseMotionListener mouseDragged(MouseEvent e) mouseMoved(MouseEvent e) 마우스 이벤트를 발생시키는 컴포넌트(이벤트 소스) Component Label Button Checkbox Choice List TextComponent TextField TextArea Scrollbar Canvas Container Panel ScrollPane Window Frame Dialog FileDialog
마우스 이벤트 처리 예제 리스너 상속 이벤트 핸들러 연결 이벤트 핸들러 ... 3 : import java.awt.event.*; 4 : 5 : public class DragLine extends Applet 6 : implements MouseListener, MouseMotionListener 7 : { 10 : public void init() 11 : { 12 : addMouseListener(this); 13 : addMouseMotionListener(this); 14 : } 28 : public void mousePressed(MouseEvent e) 29 : { 30 : p1= e.getPoint(); // 시작점 저장 31 : } 이벤트 핸들러 연결 이벤트 핸들러 리스너 상속
내부 클래스를 이용한 이벤트 처리 외부 클래스 내부 클래스 ... 3 : import java.awt.event.*; 4 : 5 : public class MouseTest2 extends Applet 6 : { 7 : int[] x, y; // 그려질 원의 좌표 8 : int num; // 그려질 원의 갯수 32 : class MyMouseHandler implements MouseListener 33 : { 42 : public void mouseClicked(MouseEvent e) 43 : { 44 : if(num<100){ 45 : x[num]= e.getX(); // 그려질 원의 x좌표 46 : y[num]= e.getY(); // 그려질 원의 y좌표 59 : } 60 : } 내부 클래스 외부 클래스 외부 클래스의 멤버변수/메소드를 자유롭게 사용
마우스 오른쪽 버튼 상수 설명 BUTTON1_MASK 첫번째 버튼(왼쪽 버튼) BUTTON2_MASK 두번째 버튼 ... 22 : public void mousePressed(MouseEvent e) 23 : { 24 : if((e.getModifiers() & InputEvent.BUTTON3_MASK)!=0){ 25 : msg="마우스 [오른쪽] 버튼을 눌렀습니다."; 26 : }else{ 27 : msg="마우스 [왼쪽] 버튼을 눌렀습니다."; 28 : } 29 : 30 : repaint(); 31 : } 상수 설명 BUTTON1_MASK 첫번째 버튼(왼쪽 버튼) BUTTON2_MASK 두번째 버튼 BUTTON3_MASK 세번쨰 버튼(오른쪽 버튼)
키 이벤트 처리 리스너 인터페이스 리스너 메소드 설명 KeyListener keyPressed(KeyEvent e) 키가 눌러졌을 때 실행 keyReleased(KeyEvent e) 키를 놓았을 때 실행 keyTyped(KeyEvent e) 키를 타이핑했을 때 실행 키 이벤트를 발생시키는 컴포넌트(이벤트 소스) Component Label Button Checkbox Choice List TextComponent TextField TextArea Scrollbar Canvas Container Panel ScrollPane Window Frame Dialog FileDialog
쉬프트/컨트롤/앨트 키 메소드 설명 isAltDown() 앨트키가 눌러진 상태인지 조사 isControlDown() ... 23 : class MyKeyHandler implements KeyListener 24 : { 25 : String msg; 26 : 27 : public void keyPressed(KeyEvent e) 28 : { 29 : msg= "KeyPressed: "+ e.getKeyText(e.getKeyCode()); 30 : if(e.isShiftDown()){ msg += " [Shift]"; } 31 : if(e.isControlDown()){ msg += " [Ctrl]"; } 32 : if(e.isAltDown()){ msg += " [Alt]"; } 33 : 34 : myList.add(msg); 35 : } 내부 클래스로 구현한 이벤트 핸들러 메소드 설명 isAltDown() 앨트키가 눌러진 상태인지 조사 isControlDown() 컨트롤키가 눌러진 상태인지 조사 isShiftDown() 쉬프트키가 눌러진 상태인지 조사
어댑터를 이용한 이벤트 처리 이벤트 리스너 어댑터 ActionEvent ActionListener KeyEvent KeyListener KeyAdapter AdjustmentEvent AdjustmentListener MouseEvent MouseListener MouseAdapter ComponentEvent ComponentListener ComponentAdapter MouseMotionListener MouseMotionAdapterr ContainerEvent ContainerListener ContainterAdapter TextEvent TextListener FocusEvent FocusListener FocusAdapter WindowEvent WindowListener WindowAdapter ItemEvent ItemListener * 리스너는 인터페이스이기 때문에 사용하지 않는 메소드까지 모두 구현해야 하지만 어댑터는 필요한 메소드만 구현하면 됨