[chap 10] 자바의 이벤트 처리
🔮 이벤트 기반 프로그래밍
이벤트 기반 프로그래밍이랑 이벤트의 발생에 의해 프로그램 실행 흐름이 결정되는 방식의 프로그래밍 패러다임이다. 이벤트란 키 입력, 마우스 클랙, 드래그 등 사용자의 액션이나 센서 등 외부 장치로부터의 입력, 네트워크를 통한 데이터 수신 등에 의해서 발생한다.
📍 실행 과정
- 버튼 클릭 -> new 이벤트 발생
- 이벤트는 마우스 드라이버를 거쳐 JVM에 전달
- JVM은 이벤트 분배 스레드 에게 마우스 클릭에 관한 정보 전송
- 이벤트 분배 스레드는 이벤트 객체(ActionEvent) 를 생성, 이벤트 객체에는 전송되는 여러 정보를 가지고 있는데, 그 중 이벤트를 발생시킨 컴포넌트 정보를 이벤트 소스 라고 부른다.
- 이벤트 분배 스레드는 해당 컴포넌트의 이벤트 리스너 를 찾아서 호출
- 이벤트 리스너로부터 리턴 후 다음 이벤트를 기다린다.
요런 느낌?
📍 용어 정리
- 이벤트 소스 : 이벤트를 발생시킨 GUI 컴포넌트
- 이벤트 객체 : 발생한 이벤트에 대한 정보를 담는 객체
- 이벤트 리스너 : 이벤트를 처리하는 코드로서 컴포넌트에 등록 되어야 작동 가능
- 이벤트 분배 스레드 : 무한 루프를 실행하는 스레드로 JVM으로부터 이벤트 발생을 통지받아 적절한 이벤트 객체를 생성하여 이에 맞는 이벤트 리스너를 찾아 호출
🔮 이벤트 객체
이벤트 객체란 현재 발생한 이벤트에 관한 정보를 가진 객체이며, 이벤트 리스너에게 전달된다.
위와 같은 계층 구조를 가지고 있다. 각 이벤트의 종류별로 사용할 수 있는 메소드가 차이가 있으므로 주의깊게 볼 것!
📍 이벤트 객체와 이벤트 소스
이벤트 객체 | 이벤트 소스 | 이벤트가 발생하는 경우 |
---|---|---|
ActionEvent | JButton | 마우스나 |
JMenuItem | 메뉴 아이템 선택 | |
JTextFiedld | 텍스트 입력 중 |
|
ItemEvent | JCheckBox | 체크 박스의 선택 혹은 해제 |
JRadioButton | 라디오 버튼의 선택 상태가 변할 때 | |
JCheckBoxMenuItem | 체크박스 메뉴 아이템의 선택 혹은 해제 | |
ListSelectionEvent | JList | 리스트에서 선택된 아이템이 변경될 때 |
KeyEvent | Component | 키가 눌러지거나 눌러진 키가 떼어질 때 |
MouseEvent | Component | 마우스 작동에 대한 핸들링 |
FocusEvent | Component | 컴포넌트가 포커스를 받거나 잃을 때 |
WindowEvent | Window | 윈도우를 상속받는 모든 컴포넌트에 대해 윈도우 활성화, 비활성화, 아이콘화, 아이콘에서 복구, 윈도우 열기, 윈도우 닫기, 윈도우 종료 |
AdjustmentEvent | JScrollBar | 스크롤바를 움직일 때 |
ComponentEvent | Component | 컴포넌트가 사라지거나, 나타나거나, 이동, 크기 변경 시 |
ContainerEvent | Container | Container에 컴포넌트의 추가 혹은 삭제 |
🔮 이벤트 리스너
이벤트 리스너란 이벤트를 처리하는 자바 프로그램 코드로서 클래스로 만든다. JDK는 이벤트 리스너 인터페이스를 제공하며, 개발자는 이 인터페이스를 상속받고 추상 메소드를 모두 구현하여 이벤트 리스너를 작성한다.
📍 이벤트 리스너 작성 과정
- 이벤트와 이벤트 리스너 선택
- 이벤트 리스너 클래스 작성 -> 독립된 클래스 or 내부 클래스 or 익명 클래스
- 이벤트 리스너 등록
📍 독립된 클래스로 이벤트 리스너 작성
//독립 클래스로 Action 이벤트 리스너 작성
package Chap10;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class IndepClassListener extends JFrame {
public IndepClassListener() {
// 컨테이너 설정
setTitle("Action Event Listener Exam");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new FlowLayout());
// 버튼 생성, 컨테이너에 붙히기
JButton btn = new JButton("Action");
btn.addActionListener(new MyActionListener()); // 버튼에 actionListener를 달기
c.add(btn);
setSize(350, 150);
setVisible(true);
}
public static void main(String[] args) {
new IndepClassListener();
}
}
// 독립된 클래스로 이벤트 리스너 작성
class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource(); // 이벤트 소스를 알아내기
if (b.getText().equals("Action")) { // 버튼의 문자열이 Action 인지를 비교
b.setText("액션"); // 버튼의 문자열을 "액션"으로 변경
} else {
b.setText("Action");
}
}
}
📍 내부 클래스로 이벤트 리스너 작성
package Chap10;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class InnerClassListener extends JFrame {
public InnerClassListener() {
// 컨테이너 설정
setTitle("Action Event Listener Exam");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new FlowLayout());
// 버튼 생성, 컨테이너에 붙히기
JButton btn = new JButton("Action");
btn.addActionListener(new MyActionListener()); // 버튼에 actionListener를 달기
c.add(btn);
setSize(350, 150);
setVisible(true);
}
// 내부 클래스로 Action 리스너 작성
public class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();
if (b.getText().equals("Action")) {
b.setText("액션");
} else {
b.setText("Action");
}
InnerClassListener.this.setTitle(b.getText()); // 프레임의 타이틀에 버튼 문자열을 출력한다.
}
}
public static void main(String[] args) {
new InnerClassListener();
}
}
📍 익명 클래스로 이벤트 리스너 작성
package Chap10;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AnonymousClassListener {
JFrame jf;
Container c;
JButton btn;
public AnonymousClassListener() {
jf = new JFrame("Write Action Event Listener");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
c = jf.getContentPane();
c.setLayout(new FlowLayout());
btn = new JButton("Action");
c.add(btn);
//익명 클래스 작성
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();
if (b.getText().equals("Action"))
b.setText("Ready");
else
b.setText("Action");
jf.setTitle(b.getText());
}
});
jf.setSize(350, 150);
jf.setVisible(true);
}
public static void main(String[] args) {
new AnonymousClassListener();
}
}
이벤트 리스너에 맞는 이벤트 객체와 이벤트 소스가 있다.
🔮 어댑터 클래스
헐,,,,,,,,,대박 !! 리스너 인터페이스를 상속받아 이벤트 리스너를 구현할 때, 리스너 인터페이스의 메소드를 모두 구현해야되는 부담이 있다. -> 책말내말,,,,ㄹㅇ,,,, 여튼 이런 부담을 줄여주기 위해서 제공하는 클래스가 어댑터 클래스 이다.
리스너 인터페이스 | 대응하는 어댑터 클래스 |
---|---|
ActionListener | 없음 |
ItemListener | 없음 |
KeyListener | KeyAdapter |
MouseListener | MouseAdapter |
MouseMotionListener | MouseMotionAdaptoer or MouseAdapter |
FocuseListener | FocusAdapter |
WindowListener | WindowAdapter |
AdjustmentListener | 없음 |
ComponentListener | ComponentAdapter |
ContainerListener | ContainerAdapter |
💡 예시
package Chap10;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MouseAdapterEx extends JFrame {
private JLabel la = new JLabel("Hello");
public MouseAdapterEx() {
setTitle("Mouse Event Ex");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.addMouseListener(new MyMouseAdapter()); // 컨테이너팬에 Mouse 이벤트 리스너 달기
c.setLayout(null);
la.setSize(50, 20);
la.setLocation(30, 30);
c.add(la);
setSize(250, 250);
setVisible(true);
}
class MyMouseAdapter extends MouseAdapter {
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
la.setLocation(x, y);
}
}
public static void main(String[] args) {
new MouseAdapterEx();
}
}
댓글남기기