우리가 만든 UI에서 사용자가 창을 늘리거나 버튼을 누르는 등의 모든 행위를 말한다.
→ 이벤트가 발생한 Component를 말한다.
즉, 어디서 이벤트가 발생했는지를 의미한다.
→ 이벤트가 발생하는지 안하는지 지켜보고 있다가 이벤트가 발생하면 그에 대한 행동을 하는 것을 말한다.
→ 이벤트이름 + listener 를 붙이는 네이밍 규칙을 가진다.
→ 어떤 이벤트가 일어났는지 알 수가 없고, 이벤트 발생 시에 어떤 행동을 해야할 지 미리 정할 수 없기에 인터페이스로 되어 있다.
예를 들어
event -> 행위를 나타내는 객체
ActionEvent -> 누르는 행위를 나타내는 개체이다.
"사용자가 창에서 버튼을 누른다"라고 했을 때,
사용자가 버튼을 누른다 -> event(ActionEvent)
버튼 -> event-source(JButton)
버튼을 눌렀을 때 무슨 일이 발생한다 -> event-listener(ActionListener)
이다.
1. UI 구상, 구현
: 이쁘게 만드는 것은 프론트가 하는 일이다.
우리가 해야하는 일은 사용자가 사용하기 편하고 알아보기 쉽게 직관적으로 만들어 주는 일을 한다.
⇒ 기능 정의 완료
2. 처리할 event를 선정
: 이벤트가 발생했을 때 어떤 행동을 할 것인 지 아니면 행동하지 않을 것인지를 결정한다.
3. event-listener를 구현
: 실제로 기능을 구현한다.
4. event-source 와 event-listener 연결
: event source명.add...listener(event-listener) 의 메소드를 이용해서 이벤트 연결을 해준다.
class Counter1 extends JFrame implements ActionListener {
private JButton btnPlus;
private JLabel lblNum;
public Counter1() {
init();
setDisplay();
addListeners();
showFrame();
}
private void init() {
btnPlus = new JButton("plus");
lblNum = new JLabel("0", JLabel.CENTER);
lblNum.setFont(new Font(Font.DIALOG, Font.BOLD, 50));
}
private void setDisplay() {
add(lblNum, BorderLayout.CENTER);
add(btnPlus, BorderLayout.SOUTH);
}
private void addListeners() {
btnPlus.addActionListener(this);
}
private void showFrame() {
setTitle("counter1");
setSize(300, 400);
setLocation(100, 100);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent ae){
// 1. lblNum에서 값을 가져온다.
String strNum = lblNum.getText();
// 2. String -> int
int num = Integer.parseInt(strNum);
// 3. 1증가
num++;
// 4. int -> String
strNum = String.valueOf(num);
// 5. lblNum에 넣기
lblNum.setText(strNum);
}
}
public class EventEx2 {
public static void main(String[] args) {
new Counter1();
}
}
→ 위 코드를 실행시키면 다음과 같이 나오고, plus 버튼을 누르면 숫자가 증가한다.
→ actionPerformed 메소드를 오버라이드해서 행동을 결정한다.
윈도우와 관련된 행동에 대한 이벤트
<implemant WindowListener 하지 않는 이유>
→ WindowListener 에는 총 7개의 메소드가 존재한다.
implement 해버리면 사용하지 않는 메소드까지 전부 오버라이드 해야한다.
추상클래스로 원하는 메소드만 오버라이드해서 사용가능하다.
<추상메소드가 없는데 추상클래스로 만든 이유>
→ 객체를 생성하지 않기 위해서, 그리고 추상클래스로 만들면 그 중 내가 원하는 메소드만 상속받은 클래스에서 오버라이드해서 사용할 수 있다.
예를 들어
public abstract class WindowAdapter implements WindowListener
여기서 Adapter는 연결해주는 아이를 의미한다.
<WindowListener 예제>
class MyWindowListener extends WindowAdapter{
private MyWindow window;
public MyWindowListener(MyWindow window) {
this.window = window;
}
@Override
public void windowClosing(WindowEvent we) {
window.closeWindow();
}
}
public class MyWindow extends JFrame {
public MyWindow() {
addWindowListener(new MyWindowListener(this));
setTitle("MyWindow");
setSize(400,300);
setLocation(100,100);
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
setVisible(true);
}
public void closeWindow() {
int result = JOptionPane.showConfirmDialog(
this,
"종료하시겠습니까??",
"종료",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE
);
if (result == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
public static void main(String[] args) {
MyWindow w = new MyWindow();
// w.closeWindow();
}
}