프로그래밍 언어/JAVA

이벤트 리스너

· 코딩마이데이

리스너 인터페이스

이벤트 리스너란 이벤트를 처리하는 자바 프로그램 코드로서 클래스를 만듭니다. JDK는 이벤트 리스너 인터페이스(interface)를 제공하며, 개발자가 이 인터페이스를 상속받고 추상 메서드를 모두 구현하여 이벤트 리스너를 작성한다.

ActionListener 인터페이스의 경우를 예로 들어봅시다. ActrionListener 인터페이스는 자바 패키지에 다음과 같이 선언되어 있습니다.

interface ActionListener {
	public void actionPerformed(ActionEvent e); // Action 이벤트 발생 처리
}

 

버튼을 누르는 Action 이벤트가 발생하면 actionPerformed(ActionEvent e) 메소드가 호출되고, 이때 ActionEvent 객체가 인자로 전달됩니다.

또한 MouseListener 인터페이스는 다음과 같이 5개의 메소드를 가지고 있으며, 각 메서드는 마우스의 조작에 따라 발생하는 이벤트를 처리합니다. 메서드에는 MouseEvent 객체가 인자로 전달됩니다.

interface MouseListener {
	public void mousePressed(MouseEvent e); // 마우스 버튼이 눌러지는 순간
	public void mouseReleased(MouseEvent e); // 눌러진 마우스 버튼이 떼어지는 순간
	public void mouseClicked(MouseEvent e); // 마우스가 클릭되는 순간
	public void mouseEntered(MouseEvent e); // 마우스가 컴포넌트 위에 올라가는 순간
	public void mouseExited(MouseEvent e); // 마우스가 컴포넌트 위에서 내려오는 순간
}

 

리스너 인터페이스들은 java.awt.event 패키지에 구현되어 있으므로 이벤트 리스너를 작성하기 위해서는 import java.awt.event.*; 문이 필요합니다.

이벤트 리스너 인터페이스

 

이벤트 리스너 작성 과정

이벤트 리스너는 전형적으로 다음 3단계로 작성합니다.

1. 이벤트와 이벤트 리스너 선택 - 목적에 적합한 이벤트와 리스너 인터페이스 선택

2. 이벤트 리스너 클래스 작성 - 리스너 인터페이스를 상속받는 클래스를 작성하고 추상 메서드 모두 구현

3. 이벤트 리스너 등록 - 이벤트를 받을 스윙 컴포넌트에 이멘트 리스너 등록

 

이벤트와 이벤트 리스너 선택

이벤트: Action 이벤트

이벤트 리스너: ActionListener

이벤트 객체: ActionEvent

 

이벤트 리스너 클래스 작성

ActionListener 인터페이스를 상속받은 MyActionListener 클래스를 선언하고, 한 개 뿐인 추상 메서드 actionPerformed(ActionEvent e)를 다음과 같이 작성합니다.

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"); // 버튼의 문자열을 "Action"으로 변경
    }
}

 

이 코드에서 사용자가 클릭한 버튼 컴포넌트(이벤트 소스)는 다음과 같이 알아냅니다.

JButton b = (JButton)e.getSource(); // 이벤트 소스를 알아낸다.

 

그러고 나서 다음 코드를 이용하여 클릭된 버튼의 문자열을 "액션"으로 변경합니다.

 b.setText("액션");

 

이벤트 리스너 등록

이벤트 리스너가 작동하기 위해서는 MyActionListener의 객체를 사용하여 이벤트를 처리할 버튼 컴포넌트에 등록해야 합니다.

MyActionListener listener = new MyActionListener(); // 리스너 객체 생성
btn.addActionListener(listener); // 리스너 등록

 

일반적으로 컴포넌트 component에 이벤트 리스너를 등록하기 위해서는 다음 메소드를 사용합니다.

component.addXXXListener(listener);

 

여기서 XXX는 이벤트 이름에 해당합니다. 예를 들면, addActionListener(), addFocusListener(), addMouseListener() 등입니다.

JButton b = new JButton("test");
b.addItemListener(listener); // 오류. JButton 클래스에 addItemListener() 없음

 

또한, JScrollBar 컴포넌트에도 Action 이벤트가 발생하지 않으므로 JScrollBar 클래스 역시 addActionListener() 메서드를 가지지 않습니다.

JScrollBar s = new JScrollBar();
s.addActionListener(listener); // 오류. JScrollBar 클래스에 addActionListener() 없음

 

반면에 JList는 Mouse 이벤트를 받을 수 있기 때문에, 다음과 같이 addMouseListener() 메서드를 가집니다.

JList = list = new JList();
list.addMouseListener(listener); // 정상

 

이벤트 리스너 작성 방법

독립 클래스로 이벤트 리스너 작성

이벤트 리스너 클래스를 독립적으로 작성하는 방법으로서, 가장 전형적인 방법입니다.

독립 클래스로 Action 이벤트의 리스너 작성

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class IndepClassListener extends JFrame {
    public IndepClassListener() {
        setTitle("Action 이벤트 리스너 예제");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container c = getContentPane();
        c.setLayout(new FlowLayout());
        JButton btn = new JButton("Action");
        btn.addActionListener(new MyActionListener()); // Action 이벤트 리스너 열기
        c.add(btn);

        setSize(300, 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"); // 버튼의 문자열을 "Action"으로 변경
    }
}

[실행결과]

내부 클래스(inner class)로 이벤트 리스너 작성

이벤트 리스너를 내부 클래스(inner class)로 작성하는 방법입니다.

내부 클래스로 Action 이벤트 리스너 만들기

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class InnerClassListener extends JFrame {
    public InnerClassListener() {
        setTitle("Action 이벤트 리스너 예제");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container c = getContentPane();
        c.setLayout(new FlowLayout());
        JButton btn = new JButton("Action");
        btn.addActionListener(new MyActionListener());
        c.add(btn);

        setSize(350, 150);
        setVisible(true);
    }

    // 내부 클래스로 Action 리스너를 작성합니다.
    private 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의 멤버나 JFrame의 멤버를 호출할 수 있음
            InnerClassListener.this.setTitle(b.getText()); // 프레임의 테이블에 버튼 문자열을 출력한다.
        }
    }

    public static void main(String[] args) {
        new InnerClassListener();
    }
}

[실행결과]

 

 

InnerClassListener.this.setTitle(b.getText()); // JFrame의 setTitle() 호출. 그냥 setTitle(b.getText())로 해도 됨

 

이 코드는 JFrame의 멤버 setTitle()을 호출하는 것으로 MyActionListener가 내부 클래스이기 때문에 가능합니다.

 

익명 클래스(anonymous class)로 이벤트 리스너 작성

익명 클래스는 이름 없이 만들어진 클래스입니다. 익명 클래스는 다음과 같이 new와 함께 사용되어 바로 객체를 생성하는 데 사용됩니다.

new 익명클래스의슈퍼클래스(생성자인자들) {
	// 멤버 구현
}

 

MyActionListener 클래스를 익명 클래스로 작성

 

익명 클래스로 Action 이벤트 리스너 만들기

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class AnnonymousClassListener extends JFrame {
    public AnnonymousClassListener() {
        setTitle("Action 이벤트 리스너 예제");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container c = getContentPane();
        c.setLayout(new FlowLayout());
        JButton 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("액션");
                else
                    b.setText("Action");

                // AnnonymousClassListener의 맴버나 JFrame의 멤버를 호출할 수 있음
                setTitle(b.getText());
            }
        });

        setSize(350, 150);
        setVisible(true);
    }

    public static void main(String[] args) {
        new AnnonymousClassListener();
    }
}

 

마우스로 문자열 이동시키기 - 마우스 이벤트 연습

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class MouseListenerEx extends JFrame {
    private JLabel la = new JLabel("Hello"); // "Hello"를 출력하기 위한 테이블

    public MouseListenerEx() {
        setTitle("Mouse 이벤트 예제");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container c = getContentPane();
        c.addMouseListener(new MyMouseListener()); // 컨텐트팬에 이벤트 리스너 달기

        c.setLayout(null); // 컨텐트팬의 배치관리자 삭제
        la.setSize(50, 20); // 레이블의 크기 50x20 설정
        la.setLocation(30, 30); // 레이블의 위치 (30, 30)으로 설정
        c.add(la); // 레이블 컴폰너트 삽입

        setSize(250, 250);
        setVisible(true);
    }

    // Mouse 리스너 구현
    class MyMouseListener implements MouseListener {
        public void mousePressed(MouseEvent e) {
            int x = e.getX(); // 마우스 클릭 좌표 x
            int y = e.getY(); // 마우스 클릭 좌표  y
            la.setLocation(x, y); // 레이블의 위치를 (x, y)로 이동
        }
        public void mouseReleased(MouseEvent e) { }
        public void mouseEntered(MouseEvent e) { }
        public void mouseExited(MouseEvent e) { }
        public void mouseClicked(MouseEvent e) { }
    }

    public static void main(String[] args) {
        new MouseListenerEx();
    }
}

 

[실행 결과]

초기화면
마우스를 다른 곳에 클릭한 경우
마우스를 다른 곳애 클릭한 경우

 

'프로그래밍 언어 > JAVA' 카테고리의 다른 글

KeyEvent와 KeyListener  (1) 2025.06.14
어댑터(Adapter) 클래스  (1) 2025.06.11
이벤트 객체  (0) 2025.06.05
이벤트 기반 프로그래밍  (1) 2025.06.05
여러 컴포넌트를 가진 복잡한 GUI 만들기  (5) 2025.06.02