1. 이벤트 처리
▷ UI 프로그램은 사용자와 상호작용을 하면서 코드를 실행함
▷ 사용자가 UI의 컴포넌트를 사용하는 순간 이벤트가 발생, 프로그램은 이벤트를 처리하기 위해 코드를 실행함
▷ 위임형 방식 : 이벤트가 발생하면 직접 처리하지 않고 소스에 추가된 리스너에게 이벤트 처리를 위임하는 방식
▷ 동시에 여러 개의 이벤트가 발생하기도 함.
◎ 대표적 이벤트 및 이벤트 처리 리스너
NO | 이벤트 소스 | 발생 이벤트 | 발생 원인 | 리스너 |
1 | JFrame | WindowEvent | 중 하나를 클릭했을 때 | WindowListene |
2 | JDialog | WindowEvent | 중 하나를 클릭했을 때 | WindowListene |
3 | JTextField | ActionEvent | Enter 키를 눌렀을 때 | ActionListener |
4 | JButton | ActionEvent | 클릭했을 때 | ActionListener |
5 | JRadioButton | ActionEvent | 클릭했을 때 | ActionListener |
6 | JCheckBox | ActionEvent | 클릭했을 때 | ActionListener |
7 | JMenuItem | ActionEvent | 선택했을 때 | ActionListener |
8 | JComboBox | ActionEvent | 다른 항목을 선택했을 때 | ActionListener |
9 | JList | ListSelectionEvent | 다른 항목을 선택했을 때 | ListSelectionListener |
(1) Listener와 Adapter
▷ 리스너 클래스를 생성하는 방법은 리스너 인터페이스를 구현하는 방법과 어댑터 클래스를 상속하는 방법이 있음
◎ 리스너 인터페이스 구현 방법
class MyWindowListener implements WindowListener { public void windowActivated(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowClosing(WindowEvent e) { //닫기(x) 버튼을 클릭했을 때 처리 방법 코딩 } public void windowDeactivated(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowOpened(WindowEvent e) {} }
닫기 버튼에서 발생하는 WindowEvent만 처리하고 싶어도 windowClosing() 및 나머지 6개를 위와 같이 재정의 해야함
◎ 리스너 어댑터를 상속하는 방법
▷ 리스너 어댑터를 상속하면 관심 있는 이벤트 처리 메소드만 재정의할 수 있기 때문에 리스너 인터페이스를 구현하는 방법보다 좀 더 효율적임
▷ WindowAdapter 클래스를 상속할 경우 windowClosing() 메소드만 재정의하면 됨
▶ 나머지 6개의 메소드는 WindowAdapter에서 내용이 없는 채로 이미 구현되어 있음
▷ 리스너 인터페이스에 대응되는 어댑터 클래스가 모두 존재하는 것은 아님
▷ 리스너 인터페이스에 2개 이상의 이벤트 처리 메소드가 정의되어 있을 경우에만 어댑터 클래스가 제공됨
◎ 리스너 인터페이스와 대응되는 어댑터 클래스
NO | 리스너 인터페이스 | 어댑터 |
1 | java.awt.event.WindowListener | java.awt.event.WindowAdapter |
2 | java.awt.event.MouseListener | java.awt.event.MouseAdapter |
3 | java.awt.event.KeyListener | java.awt.event.KeyAdapter |
4 | java.awt.event.ActionListener | 없음 |
5 | javax.swing.event.ListSelectionListener | 없음 |
◎ 제목 표시줄 닫기(x)버튼(JFrame), btnClose 버튼(하단)을 이용한 프로그램 종료 예제
import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class ClosableExample1 extends JFrame { private JButton btnClose; // 메인 윈도우 설정 public ClosableExample1() { this.setTitle("CloseExample"); this.setSize(300, 100); this.setLayout(new FlowLayout()); this.getContentPane().add(getBtnClose()); // WindowListener 추가 this.addWindowListener(new MyWindowAdapter()); } // 닫기 버튼 생성 private JButton getBtnClose() { if(btnClose == null) { btnClose = new JButton(); btnClose.setText("닫기"); // ActionListener 추가 btnClose.addActionListener(new MyActionListener()); } return btnClose; } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { ClosableExample1 jFrame = new ClosableExample1(); jFrame.setVisible(true); } }); } // WindowAdapter 클래스를 상속해서 WindowListener 클래스 작성 // 윈도우 창의 닫기 X 버튼 class MyWindowAdapter extends WindowAdapter{ @Override public void windowClosing(WindowEvent e) { System.exit(0); } } // WindowAdapter 클래스를 상속해서 WindowListener 클래스 작성 class MyActionListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.exit(0); } } }
◎ Anonymous Listener
▷ 이벤트를 처리할 때 리스너 클래스를 외부 클래스로 선언하면 컨테이너의 필드와 메소드에 접근하는 것이 불편함
▶ 리스너는 일반적으로 익명(Anonymous) 객체로 작성함
◎ 익명 객체를 이용한 프로그램 종료 예제
import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class ClosableExample2 extends JFrame { private JButton btnClose; // 메인 윈도우 설정 public ClosableExample2() { this.setTitle("CloseExample"); this.setSize(300, 100); this.setLayout(new FlowLayout()); this.getContentPane().add(getBtnClose()); // 익명 WindowListener 객체 추가 this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } // 닫기 버튼 생성 private JButton getBtnClose() { if(btnClose == null) { btnClose = new JButton(); btnClose.setText("닫기"); // 익명 ActionListener 추가 btnClose.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.exit(0); } }); } return btnClose; } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { ClosableExample2 jFrame = new ClosableExample2(); jFrame.setVisible(true); } }); } }
메소드만 따로 만들지 않고 익명 객체를 작성해도 위와 동일한 출력이 나타납니다.
▷ 복수 개의 컴포넌트에서 동일한 리스너를 사용해서 이벤트를 처리하고 싶다면 리스너를 필드로 선언
◎ 두 개의 JButton에서 발생하는 ActionEvent를 하나의 ActionListener 익명 객체로 처리하는 예제
import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class ActionListenerExample extends JFrame { private JButton btnOk; private JButton btnCancel; // 메인 윈도우 설정 public ActionListenerExample() { this.setTitle("ActionListenerExample"); this.setSize(300, 100); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(new FlowLayout()); this.getContentPane().add(getBtnOk()); this.getContentPane().add(getBtnCancel()); } // ActionListener 타입의 필드 선언 및 익명 객체로 초기화 private ActionListener actionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // ActionEvent가 발생한 컴포넌트 구분 if(e.getSource() == btnOk) { System.out.println("확인 버튼을 클릭했습니다."); } else if(e.getSource() == btnCancel) { System.out.println("취소 버튼을 클릭했습니다."); } } }; // Ok 버튼 생성 private JButton getBtnOk() { if(btnOk == null) { btnOk = new JButton(); btnOk.setText("확인"); // actionListener 필드 대입 btnOk.addActionListener(actionListener); } return btnOk; } // Cancel 버튼 생성 private JButton getBtnCancel() { if(btnCancel == null) { btnCancel = new JButton(); btnCancel.setText("취소"); // actionListener 필드 대입 btnCancel.addActionListener(actionListener); } return btnCancel; } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { ActionListenerExample jFrame = new ActionListenerExample(); jFrame.setVisible(true); } }); } }
Listener와 Adapter을 이용해서 버튼 조작으로 닫기 버튼 조작을 가능할 수 있게 만들었습니다.
html, css, java script 했던 것과 비슷하네요ㅎㅎ
많은 분들의 피드백은 언제나 환영합니다! 많은 댓글 부탁드려요~~
'BackEnd > Java' 카테고리의 다른 글
[java]이것이 자바다 부록 Java UI 6 (Swing을 이용한 텍스트 컴포넌트) (1) | 2023.02.16 |
---|---|
[java]이것이 자바다 부록 Java UI 5 (Swing을 이용한 버튼 컴포넌트) (0) | 2023.02.16 |
[java]이것이 자바다 부록 Java UI 3 (Swing을 이용한 컴포넌트 배치 2) (1) | 2023.02.15 |
[java] 이것이 자바다 부록 Java UI 2 (Swing을 이용한 컴포넌트 배치 1) (0) | 2023.02.15 |
[java] 이것이 자바다 부록 Java UI 1 (Swing) (0) | 2023.02.15 |