하나의 리스너로 여러 컴포넌트의 이벤트를 처리하는 방법

heeezni·2025년 5월 20일

Java GUI 프로젝트

목록 보기
3/20
post-thumbnail

체크포인트

1️⃣ ActionEvent.getSource()를 이용한 이벤트 발생 주체 식별

2️⃣ 생성자 주입(Injection) 방식으로 외부 버튼 참조

3️⃣ 중복 리스너 객체 생성 없이 하나의 ActionListener가 두 개의 버튼 이벤트를 모두 처리


Java의 이벤트 처리 흐름

사용자가 액션 이벤트를 발생
(예: 버튼 클릭)

운영체제(OS)가 사용자 입력을 감지하고 JVM에 전달

JVM은 해당 이벤트 정보를 기반으로
→ 적절한 이벤트 객체(ActionEvent)를 인스턴스화(객체 생성)

생성된 이벤트 객체는
→ 등록된 리스너의 actionPerformed(ActionEvent e) 메서드로 전달됨

개발자는 이 e 객체(ActionEvent)를 통해
→ 어떤 컴포넌트가, 어떤 상황에서 이벤트를 발생시켰는지 모든 정보를 얻을 수 있음

윈도우가 있는 DoubleButton 클래스

package gui.event;
import java.awt.Frame;
import java.awt.Button;
import java.awt.FlowLayout;
import gui.event.day0520.MyActionListener;

public class DoubleButton {
	public static void main(String[] args) {
		Frame frame = new Frame();
		Button bt_1=null, bt_2=null;
		
		bt_1=new Button("A");
		bt_2=new Button("B");
	
		frame.setLayout(new FlowLayout());//플로우 배치 적용⭐
		frame.setSize(300,400);

		frame.add(bt_1);
		frame.add(bt_2);
		
		MyActionListener my=new MyActionListener(bt_1,bt_2);
		//버튼 1,2의 주소값을 생성자로 넘김 
		
		bt_1.addActionListener(my);//버튼1과 리스너 연결
		bt_2.addActionListener(my);//버튼2와 리스너 연결
			
		frame.setVisible(true);
	}
}

MyActionListener 클래스

package gui.event.day0520;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Button;

public class MyActionListener implements ActionListener{
	Button bt_1;
	Button bt_2; //기존 윈도우의 버튼 원함
	
	//생성자를 통해 다른 클래스에 존재하던 버튼들을 전달받음(injection)
	public MyActionListener (Button bt_1, Button bt_2){
		this.bt_1=bt_1; //this는 MyActionListener
		this.bt_2=bt_2;
		//메서드 인젝션 / 생성자 인젝션
	}
	//이벤트를 일으킨 주체를 이벤트 소스(Event Source)라고 함
    public void actionPerformed(ActionEvent e){
		Object obj=e.getSource(); 
        //obj는 자료형은 Object지만, 실제 객체는 Button
		
		if(obj==bt_1){
			System.out.println("A를 눌렀어?");
		}else if(obj==bt_2){
			System.out.println("B를 눌렀어?");
		}
	}
}

1️⃣ getSource( )로 이벤트 발생 주체 식별

Java의 ActionEvent e는
JavaScript의 addEventListener("click", (e) => {...})의 e와 같은 역할이다.
즉, 이벤트에 대한 모든 정보를 담고 있는 객체

항목설명
e.getSource()이벤트를 발생시킨 컴포넌트(=주체, 이벤트 소스)를 리턴
리턴 타입항상 Object
실제 객체Button, TextField
이유여러 컴포넌트가 하나의 리스너를 공유할 수 있게 하려면,
어떤 컴포넌트가 이벤트를 일으켰는지 확인할 수 있어야 하기 때문에
getSource()로 이벤트 발생 주체를 식별해야 함

Object obj=e.getSource();
자료형은 Object이지만, 실제 안에 들어있는 인스턴스는 Button
➡ 이벤트를 발생시킨 주체가 바로 Button이기 때문!

e.getSource( )는 이벤트를 발생시킨 컴포넌트를 돌려주는데,
그 컴포넌트가 바로 버튼(Button)이기 때문에,
→ 결과도 버튼(Button) 객체가 되는 거야.


2️⃣ 메서드/생성자 인젝션 (Injection)💉

⭐주소값(참조값) 전달하면 해당 객체를 제어할 수 있다!

Java는 원래 Call by Value라는데...

Call by Value of Reference
참조값(주소)을 값으로 전달 → 내부 수정 가능
편의상 콜바이레퍼런스라 부르자

생성자 인젝션

public class MyActionListener implements ActionListener {
	// ✅ 1. 받을 객체 정의
    Button bt_1;
    Button bt_2;

    // ✅ 2. 생성자에 매개변수 준비
    public MyActionListener(Button bt_1, Button bt_2){
   		// ✅ 3. 바인딩
        this.bt_1 = bt_1;
        this.bt_2 = bt_2;
    }

    public void actionPerformed(ActionEvent e){
        // 이벤트 처리 로직
    }
}
// 사용하는 쪽
Button bt_1 = new Button("A");
Button bt_2 = new Button("B");

// ✅ 4. 객체를 생성해서 주입
MyActionListener listener = new MyActionListener(bt_1, bt_2);

⭐ 생성자 인젝션 순서 ⭐

단계설명예시 코드
1️⃣멤버변수로 받을 객체 정의Button bt_1; Button bt_2;
2️⃣생성자에 객체 자료형으로 매개변수 준비public MyActionListener(Button bt_1, Button bt_2)
3️⃣바인딩
this.멤버변수 = 매개변수
this.bt_1 = bt_1; this.bt_2 = bt_2;
4️⃣주입받을 클래스에서 객체 전달new MyActionListener(bt_1, bt_2);

메서드 인젝션

위의 생성자 인젝션을 메서드 인젝션으로 구현한다면?

public class MyActionListener implements ActionListener {
    Button bt_1, bt_2;

    // 주입 메서드
    public void setBtn(Button bt_1, Button bt_2) {
        this.bt_1 = bt_1;
        this.bt_2 = bt_2;
    }

    public void actionPerformed(ActionEvent e) { /* ... */ }
}
MyActionListener listener = new MyActionListener(); // 일단 생성
listener.setButtons(bt_1, bt_2); // 버튼 1,2의 주소값을 setBtn()으로 넘김

생성자 인젝션과 메서드 인젝션 비교

항목생성자 인젝션메서드 인젝션
전달 시점객체 생성 동시에 주입객체 생성 후에 주입
전달 방법생성자 매개변수로 전달setter나 일반 메서드로 전달
강제성주입 강제됨 (생성자 없으면 객체 못 만들어짐)선택 가능 (주입 안 해도 생성 가능)

3️⃣ 하나의 리스너가 여러 컴포넌트의 이벤트 처리하는 방법

이벤트 소스(e.getSource())와 각 컴포넌트(버튼 등)를 비교해서
일치하는 경우에만 반응하게 if문으로 조건을 주면 된다~

Object obj=e.getSource();

if(obj==bt_1){
	System.out.println("A를 눌렀어?");
}else if(obj==bt_2){
	System.out.println("B를 눌렀어?");
}
profile
아이들의 가능성을 믿었던 마음 그대로, 이제는 나의 가능성을 믿고 나아가는 중입니다.🌱

0개의 댓글