이벤트 기반 프로그래밍은 프로그램이 사용자의 입력이나 외부의 변화에 의해 특정 이벤트가 발생할 때, 그 이벤트에 대응하는 코드를 실행하는 방식을 말합니다. 이벤트 종류로는 사용자의 마우스 클릭이나 키보드 입력, 센서 데이타의 변화, 네트워크로부터의 메시지 등이 있습니다. 이러한 이벤트들이 발생하면, 프로그램은 그에 맞는 이벤트 리스너를 실행하여 적절한 동작을 수행하게 됩니다.
이벤트 기반 프로그래밍의 특징은 프로그램의 흐름이 사용자나 외부의 입력에 따라 결정된다는 것입니다. 이벤트가 발생하면, 프로그램은 해당 이벤트를 처리하는 루틴인 이벤트 리스너를 실행합니다. 따라서 프로그램의 개발자가 프로그램의 흐름을 미리 결정하는 방식과는 대조적입니다.
일반적으로 이벤트 기반 프로그램은 다음과 같은 구조를 가집니다:
이벤트 기반 프로그래밍은 사용자와 시스템 사이의 상호작용이 필요한 응용 프로그램, 특히 GUI (그래픽 사용자 인터페이스)를 개발하는 데 매우 유용합니다. 사용자의 입력에 신속하게 반응하여 원하는 동작을 수행하는 등 인터랙티브한 프로그램 개발에 적합한 방식입니다.
이벤트 소스 (Event Source)
이벤트 객체 (Event Object)
이벤트 리스너 (Event Listener)
이벤트 분배 스레드 (Event Dispatch Thread, EDT)
이벤트 기반 프로그래밍에서는 이러한 용어들이 상호작용하여 사용자의 입력이나 외부 변화에 따라 프로그램이 동작하게 됩니다. 이벤트 소스가 이벤트를 발생시키면, 이벤트 분배 스레드가 이를 감지하고 이벤트 객체를 생성한 뒤 적절한 이벤트 리스너를 호출하여 프로그램의 동작이 결정되는 것이 기본적인 흐름입니다.
이벤트 객체는 이벤트가 발생할 때 해당 이벤트에 관한 정보를 가진 객체를 말합니다. 이벤트 리스너 코드에서 이벤트가 발생한 상황을 파악할 수 있도록 이벤트 객체에 포함된 정보를 활용합니다. 자바에서는 다양한 종류의 이벤트 객체를 제공하며, 이벤트의 종류에 따라 정보의 내용이 다르게 포함됩니다.
이벤트 객체에 포함될 수 있는 정보는 다음과 같습니다:
이벤트 종류 (Event Type): 발생한 이벤트의 종류를 나타냅니다.
이벤트 소스 (Event Source): 이벤트를 발생시킨 GUI 컴포넌트를 가리킵니다.
이벤트가 발생한 화면 좌표 (Screen Coordinates): 마우스 클릭과 같이 발생 위치에 관한 정보가 포함됩니다.
이벤트가 발생한 컴포넌트 내 좌표 (Component Coordinates): 컴포넌트 내에서의 마우스 위치와 같은 정보가 포함됩니다.
버튼이나 메뉴 아이템에 이벤트가 발생한 경우 버튼이나 메뉴 아이템의 문자열 (Button/Menu Item Text).
클릭된 마우스 버튼 번호 (Mouse Button Number): 마우스 이벤트에서 어떤 버튼이 클릭되었는지를 나타냅니다.
마우스의 클릭 횟수 (Mouse Click Count): 더블 클릭과 같이 클릭 횟수에 관한 정보가 포함됩니다.
키가 눌러졌다면 키의 코드 값과 문자 값 (Key Code and Key Char): 키보드 이벤트에서 눌린 키에 대한 정보가 포함됩니다.
체크박스, 라디오 버튼 등과 같은 컴포넌트에 이벤트가 발생하였다면 체크 상태 (Check State): 체크박스가 선택되었는지 여부 등의 정보가 포함됩니다.
이벤트에 따라 이벤트 객체가 포함하는 정보가 다를 수 있으며, 이벤트 객체를 이용하여 이벤트가 발생한 상황에 대한 자세한 정보를 추출하여 이벤트를 처리합니다. 이벤트 객체는 getSource()
메서드를 사용하여 이벤트 소스(발생한 컴포넌트)를 알아낼 수 있습니다.
이벤트 리스너는 이벤트를 처리하는 코드 또는 클래스로 작성되며, JDK(Java Development Kit)에서 이벤트 처리를 위한 인터페이스를 제공합니다. 개발자는 해당 인터페이스의 추상 메소드를 구현함으로써 이벤트 리스너를 작성합니다. 이벤트가 발생하면 자바 플랫폼은 해당 이벤트 리스너 인터페이스의 추상 메소드를 호출하여 이벤트를 처리합니다.
예를 들어, ActionListener
인터페이스는 다음과 같은 메소드를 제공합니다
interface ActionListener {
void actionPerformed(ActionEvent e);
}
여기서 actionPerformed(ActionEvent e)
메소드는 Action 이벤트가 발생했을 때 호출됩니다. 이와 같이 개발자가 ActionListener
인터페이스를 구현하고 해당 메소드를 정의하면, 버튼 클릭과 같은 Action 이벤트가 발생할 때마다 actionPerformed
메소드가 호출되어 해당 이벤트를 처리할 수 있습니다.
또 다른 예로, MouseListener
인터페이스는 마우스 이벤트 처리를 위한 메소드를 제공합니다:
interface MouseListener {
void mousePressed(MouseEvent e); // 마우스 버튼이 눌러지는 순간 호출
void mouseReleased(MouseEvent e); // 눌러진 마우스 버튼이 떼어지는 순간 호출
void mouseClicked(MouseEvent e); // 마우스가 클릭되는 순간 호출
void mouseEntered(MouseEvent e); // 마우스가 컴포넌트 위에 올라가는 순간 호출
void mouseExited(MouseEvent e); // 마우스가 컴포넌트 위에서 내려오는 순간 호출
}
MouseListener
인터페이스는 위와 같이 마우스와 관련된 다양한 이벤트에 대한 메소드를 제공합니다. 개발자는 이러한 메소드를 구현하여 마우스 이벤트를 처리할 수 있습니다. 이렇게 작성된 MouseListener
구현체를 컴포넌트에 등록하면, 해당 컴포넌트에서 마우스 이벤트가 발생할 때마다 구현한 메소드들이 자동으로 호출되어 처리됩니다. 이와 같은 방식으로 다양한 이벤트 리스너를 작성하여 GUI 애플리케이션에서 사용자의 입력 등을 처리할 수 있습니다.
이벤트 리스너를 작성하는 방법은 주로 세 가지가 있습니다. 각각의 방법은 다음과 같은 특징을 가지고 있으며, 상황에 맞게 선택하여 사용할 수 있습니다:
독립 클래스로 작성:
내부 클래스(inner class)로 작성:
익명 클래스(anonymous class)로 작성:
아래는 각 방법의 예시 코드입니다:
public class MyActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// 이벤트가 발생했을 때 수행할 동작을 작성
}
}
public class MyFrame extends JFrame {
// 멤버 변수 및 메서드들...
private class MyActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// 이벤트가 발생했을 때 수행할 동작을 작성
}
}
}
public class MyFrame extends JFrame {
// 멤버 변수 및 메서드들...
public MyFrame() {
JButton myButton = new JButton("Click Me");
myButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 이벤트가 발생했을 때 수행할 동작을 작성
}
});
}
}
각 방법은 사용하는 상황과 코드의 간결성을 고려하여 선택하면 됩니다. 익명 클래스는 특히 이벤트 리스너가 간단하고 한 번만 사용될 때 편리하며, 내부 클래스는 특정 클래스에서만 사용되는 경우에 용이합니다. 독립 클래스는 이벤트 리스너를 여러 곳에서 재사용해야 할 때 유용합니다.