

1️⃣ ActionEvent.getSource()를 이용한 이벤트 발생 주체 식별
2️⃣ 생성자 주입(Injection) 방식으로 외부 버튼 참조
3️⃣ 중복 리스너 객체 생성 없이 하나의 ActionListener가 두 개의 버튼 이벤트를 모두 처리
사용자가 액션 이벤트를 발생
(예: 버튼 클릭)
↓
운영체제(OS)가 사용자 입력을 감지하고 JVM에 전달
↓
JVM은 해당 이벤트 정보를 기반으로
→ 적절한 이벤트 객체(ActionEvent)를 인스턴스화(객체 생성)
↓
생성된 이벤트 객체는
→ 등록된 리스너의 actionPerformed(ActionEvent e) 메서드로 전달됨
↓
개발자는 이e객체(ActionEvent)를 통해
→ 어떤 컴포넌트가, 어떤 상황에서 이벤트를 발생시켰는지 모든 정보를 얻을 수 있음
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);
}
}
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를 눌렀어?");
}
}
}
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) 객체가 되는 거야.
⭐주소값(참조값) 전달하면 해당 객체를 제어할 수 있다!
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나 일반 메서드로 전달 |
| 강제성 | 주입 강제됨 (생성자 없으면 객체 못 만들어짐) | 선택 가능 (주입 안 해도 생성 가능) |
이벤트 소스(
e.getSource())와 각 컴포넌트(버튼 등)를 비교해서
일치하는 경우에만 반응하게 if문으로 조건을 주면 된다~Object obj=e.getSource(); if(obj==bt_1){ System.out.println("A를 눌렀어?"); }else if(obj==bt_2){ System.out.println("B를 눌렀어?"); }