반응형
01. 이벤트 프로그램 작성법
📌 EventHandleApp.java
package xyz.itwill.awt;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//📌이벤트 프로그램이란?
// => 컴포넌트에서는 다양한 이벤트가 발생되며, 이벤트가 발생될 경우 원하는 결과를 제공하는 명령이 실행되도록 프로그램을 작성한다.
//📌이벤트를 처리하는 프로그램 작성하는 방법
// step1. 🌈디자인 클래스 작성 - UI 구현
// => 디자인 클래스 : 컴포넌트와 컨테이너 관련 클래스 (지금까지 우리가 만들던 것!!)
// => Frame 클래스를 상속받아 작성
// => ex. public class EventHandleApp extends Frame{ }
// => 컴포넌트 또는 컨테이너에서 다양한 이벤트 발생 - XXXEvent 클래스 : 이벤트 정보를 저장하기 위한 클래스
// => 이벤트 소스(Event Source) : 이벤트가 발생된 컴포넌트 또는 컨테이너
// step2. 🍀이벤트 처리 클래스 작성 - 오버라이드선언 필수
// => 이벤트 처리 클래스 : 이벤트소스에서 발생된 이벤트를 처리하기 위한 클래스
// => 이벤트를 처리하기 위한 리스너 인터페이스를 상속받아 작성 - XXXEvent >> XXXListener
// ex) AtionEvent를 처리하기 위해서는 ActionListener 인터페이스를 상속은 클래스로 이벤트 처리
// => XXXListener인터페이스에는 컴포넌트 또는 컨테이너에서 발생되는 이벤트를 처리하기 위한 **이벤트처리 메소드가 추상메소드로 선언**되어 있으므로 **자식클래스에서 오버라이드 선언하여 이벤트 처리 명령 작성**
// step3. 🐣이벤트 소스에서 이벤트가 발생될 경우 이벤트 처리 클래스가 객체로 생성되어 이벤트 처리 메소드가 호출되어 이벤트 처리 명령이 실행되도록 설정
// => 이벤트소스에서 이벤트가 발생되면 이벤트 처리 클래스의 객체로 이벤트 처리되도록 등록
//형식) Component.addXXXListener(Listener l);
// => 이벤트 처리 클래스의 객체가 자동으로 이벤트 처리 메소드를 호출하여 이벤트 호출
// =>📌 예시 - EventHandleApp
//1.
//🌈디자인클래스
public class EventHandleApp extends Frame{
//필드
private static final long serialVersionUID = 1L;
//생성자
public EventHandleApp(String title) {
super(title);
setLayout(new FlowLayout());
//버튼을 누른 경우 ActionEvent 발생
Button exit = new Button("EXIT"); //이벤트소스
add(exit);
//3.
//🐣이벤트 처리 객체 등록 - 운영체제(OS)가 계속 감시하다가 이벤트가 발생될 경우 이벤트 처리 메소드 자동 호출
exit.addActionListener(new EventHandle());
setBounds(800,200,300,300);
setVisible(true);
}
public static void main(String[] args) {
new EventHandleApp("EventHandle");
}
}
//2.
//🍀이벤트처리클래스
//이벤트 처리 기능을 제공하기 위한 클래스 - 리스너 인터페이스를 상속받아 작성
class EventHandle implements ActionListener{
//필수
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0); //프로그램 종료
}
}
// => 2개의 클래스를 따로 만드는 것은 너무 불편ㅠ
// => 캡슐화하자 : 디자인클래스 안에 이벤트처리클래스 넣어버리자! (중첩클래스)
02. 이벤트처리프로그램은 어디에 작성하는 것이 좋을까?
🌻 EventSourceHandleApp.java
package xyz.itwill.awt;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//🌻이벤트처리프로그램은 어디에 작성하는 것이 좋을까?
// => 1. 🌻하나의 클래스 내 (디자인클래스 + 이벤트처리클래스)
// => EventSourceHandleApp.java
// => 이벤트 처리할 것이 몇 없을 때 이용, 간단한 이벤트 프로그램 만들 때 활용, 복잡한 프로그램은 비권장
// => 2. 🌻외부(디자인클래스) + 중첩(이벤트처리클래스)
// => EventInnerHandleApp.java
// => 중첩클래스로 만듦으로써 캡슐화 기능 강화
// => 3. 🌻익명의 내부클래스(이벤트처리클래스)로 이벤트처리까지
// => EventAnnoymousHandleApp
// => 컴포넌트의 갯수가 몇개 없을 때 익명의 내부 클래스 이용
// => ex) 버튼클릭 시 프로그램종료
//디자인 클래스와 이벤트 처리 클래스를 하나의 클래스로 통합하여 작성
//🌈디자인 클래스이자 🍀이벤트 처리 클래스
public class EventSourceHandleApp extends Frame implements ActionListener{
//필드
private static final long serialVersionUID = 1L;
//생성자
public EventSourceHandleApp(String title) {
super(title);
setLayout(new FlowLayout());
Button exit = new Button("EXIT");
add(exit);
exit.addActionListener(this); //🐣this 키워드를 사용하여 이벤트 처리 객체 등록
setBounds(800,200,300,300);
setVisible(true);
}
//main메소드
public static void main(String[] args) {
new EventSourceHandleApp("EventHandle");
}
//🍀오버라이드 선언한 actionPerformed메소드
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
🌻EventInnerHandleApp.java
package xyz.itwill.awt;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//디자인 클래스 내부에 이벤트 처리 클래스를 선언 - 중첩 클래스(Nested Class)
//🌈외부클래스(디자인클래스)
public class EventInnerHandleApp extends Frame{
//필드
private static final long serialVersionUID = 1L;
//생성자
public EventInnerHandleApp(String title) {
super(title);
setLayout(new FlowLayout());
Button exit = new Button("EXIT");
add(exit);
exit.addActionListener(new EventHandle()); //🐣외부클래스에서는 내부클래스를 사용하여 객체 생성 가능
setBounds(800,200,300,300);
setVisible(true);
}
//main메소드
public static void main(String[] args) {
new EventInnerHandleApp("EventHandle");
}
//🍀중첩클래스 (이벤트처리클래스)
//=> 중첩클래스 : 다중스레드프로그램만들 때, 이벤트프로그램만들 때 사용함
//=> 내부클래스는 외부클래스의 필드와 메소드를 접근제한자에 상관없이 사용 가능
//=> 중첩클래스로 만듦으로써 캡슐화 기능 강화
public class EventHandle implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
}
🌻EventAnnoymousHandleApp.java
package xyz.itwill.awt;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//컴포넌트에 대한 이벤트 처리를 위해 익명의 내부클래스 사용
//🌈디자인클래스
public class EventAnnoymousHandleApp extends Frame{
//필드
private static final long serialVersionUID = 1L;
//생성자
public EventAnnoymousHandleApp(String title) {
super(title);
setLayout(new FlowLayout());
Button exit = new Button("EXIT");
add(exit);
//🍀🐣익명객체 - 리스너 인터페이스를 상속받은 익명의 클래스를 이용하여 이벤트 처리 객체 등록
exit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
setBounds(800,200,300,300);
setVisible(true);
}
//main메소드
public static void main(String[] args) {
new EventAnnoymousHandleApp("EventAnnoymousHandle");
}
}
03. 이벤트처리클래스
🍀[WindowListener 인터페이스 상속] WindowListenerApp.java
package xyz.itwill.awt;
import java.awt.Frame;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
//프레임에서는 WindowEvent 발생
// => WindowListener 인터페이스를 상속받은 자식클래스로 이벤트 처리
//🌈디자인클래스
public class WindowListenerApp extends Frame{
private static final long serialVersionUID = 1L;
public WindowListenerApp(String title) {
super(title);
//🐣프레임에서 이벤트가 발생될 경우 동작될 이벤트 처리 객체 등록
addWindowListener(new WindowEventHandle());
setBounds(800,200,300,300);
setVisible(true);
}
//main메소드
public static void main(String[] args) {
new WindowListenerApp("WindowEvent");
}
//🍀중첩클래스(이벤트처리클래스)
// => 이벤트클래스가 WindowListener인터페이스를 상속받음
public class WindowEventHandle implements WindowListener{
@Override
public void windowOpened(WindowEvent e) {
System.out.println("windowOpened 메소드호출");
}
//이 아이만 쓸껀데ㅜㅜㅜㅜ 오버라이드 선언 다 해줘야함
@Override
public void windowClosing(WindowEvent e) {
System.out.println("windowClosing 메소드호출");
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("windowClosed 메소드호출");
}
@Override
public void windowIconified(WindowEvent e) {
System.out.println("windowIconified 메소드호출");
}
@Override
public void windowDeiconified(WindowEvent e) {
System.out.println("windowDeiconified 메소드호출");
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println("windowActivated 메소드호출");
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println("windowDeactivated 메소드호출");
}
}
// => windowClosing 메소드만 사용할 건데, WindowListener가 가진 모든 추상메소드를 오버라이든 선언해야함ㅠ
// => 불편하다. 그래서 만들어진 것이 Adapter클래스
}
🍀[WindowAdapter 클래스 상속] WindowAdapterApp.java
package xyz.itwill.awt;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//이벤트 처리를 위해 리스너 인터페이스 대신 어댑터 클래스를 상속받아 사용 가능
// => 리스너 인터페이스에 추상메소드가 2개이상 선언된 경우 리스너 인터페이스 대신 사용할 어댑터 클래스 제공
// => 어댑터 클래스를 이용하면 필요한 이벤트 처리 메소드만 오버라이드 선언하여 사용 가능
// => 네트워크프로그램은 닫기버튼 눌러도 프로그램 종료 안돼! - ex) 카카오톡
// => 일반적으로 닫기버튼 누르면 프로그램은 종료되니 내부의 익명클래스 이용
//🌈디자인클래스
public class WindowAdapterApp extends Frame{
private static final long serialVersionUID = 1L;
public WindowAdapterApp(String title) {
super(title);
//🐣방법1.
//addWindowListener(new WindowEventHandle());
//🐣🍀방법2.
//내부의 익명클래스를 사용해 프레임의 닫기 버튼을 누른 경우 프로그램 종료되도록 이벤트 처리 객체 등록
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setBounds(800, 200, 300, 300);
setVisible(true);
}
//main메소드
public static void main(String[] args) {
new WindowAdapterApp("WindowAdapter");
}
//🍀방법1. 이벤트처리클래스(중첩클래스)
// => 이벤트클래스가 WindowAdapter클래스를 상속받음
/*
public class WindowEventHandle extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
*/
}
04. 만약 처리해야할 이벤트소스가 여러개라면? ActionListener 인터페이스 상속
🍀 EventSourceGetApp.java
package xyz.itwill.awt;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//🌈디자인클래스
public class EventSourceGetApp extends Frame{
//필드
// => 이벤트 처리 메소드에서 사용할 컴포넌트 또는 컨테이너는 필드로 선언 - 생성자 내에 만들면, 생성자 블록 종료 시 소멸되기 때문에 필드에 선언함
private static final long serialVersionUID = 1L;
Button red,green,blue,white; //버튼필드
Canvas canvas; //캔버스필드
//생성자
public EventSourceGetApp(String title) {
super(title);
//1.
//버튼생성
red = new Button("RED");
green = new Button("GREEN");
blue = new Button("BLUE");
white = new Button("WHITE");
//2.
//Panel 생성 -> Panel에 Button들 부착 -> 레이아웃배치
//=>Button들의 레이아웃 : GridLayout(1,4)
//=>Panel의 레이아웃 : BorderLayout.NORTH
Panel panel = new Panel();
panel.add(red);
panel.add(green);
panel.add(blue);
panel.add(white);
panel.setLayout(new GridLayout(1,4));
add(panel, BorderLayout.NORTH);
//3.
//Panel꾸미기
panel.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
//4.
//Canvas 생성 -> 레이아웃배치
//=>Canvas의 레이아웃 : BorderLayout.CENTER
canvas = new Canvas();
add(canvas, BorderLayout.CENTER);
//5.
//이벤트발생 시 이벤트객체 생성!!!!!
//이벤트소스가 여러개 :
//🐣방법1.
/*red.addActionListener(new RedButtonHandle());
green.addActionListener(new GreenButtonHandle());
blue.addActionListener(new BlueButtonHandle());
white.addActionListener(new WhiteButtonHandle());*/
//🐣방법2.
red.addActionListener(new ColorButtonEventHandle());
green.addActionListener(new ColorButtonEventHandle());
blue.addActionListener(new ColorButtonEventHandle());
white.addActionListener(new ColorButtonEventHandle());
//6.
//🐣🍀익명의내부객체로 윈도우 창 닫는 이벤트만듦
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//7.
setBounds(800, 200, 400, 400);
setVisible(true);
}
//main메소드
public static void main(String[] args) {
new EventSourceGetApp("EventSourceGet");
}
//🍀방법1. 이벤트처리클래스
/*public class RedButtonHandle implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
canvas.setBackground(Color.RED);
}
}
public class GreenButtonHandle implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
canvas.setBackground(Color.GREEN);
}
}
public class BlueButtonHandle implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
canvas.setBackground(Color.BLUE);
}
}
public class WhiteButtonHandle implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
canvas.setBackground(Color.WHITE);
}
}*/
//🍀방법2. 이벤트처리클래스
public class ColorButtonEventHandle implements ActionListener{
//이벤트 처리 메소드 이벤트가 발생된 경우 JVM에 의해 자동호출되는 메소드
//=> 이벤트 처리 메소드는 매개변수로 이벤트 정보가 저장된 XXXEvent 객체 제공
@Override
public void actionPerformed(ActionEvent e) {
//Event.getSource() : 이벤트가 발생된 컴포넌트를 반환하는 메소드
//=> 이벤트가 발생된 컴포넌트를 Object 타입의 객체로 반환
//=> 컴포넌트를 Obeject객체로 주기때문에 자식참조변수에 저장 불가능!
//Button eventSource = e.getSource(); //error
//=> 명시적 객체 형변환을 사용하여 원하는 컴포넌트로 변환하여 사용 가능
Button eventSource = (Button)e.getSource(); //ok
//Object eventSource = e.getSource();
//이벤트가 발생된 컴포넌트를 구분하여 명령 실행
if(eventSource == red) { //이벤트가 발생된 컴포넌트를 비교하여 같은 경우
canvas.setBackground(Color.RED);
} else if(eventSource == green) {
canvas.setBackground(Color.GREEN);
}else if(eventSource == blue) {
canvas.setBackground(Color.BLUE);
}else if(eventSource == white) {
canvas.setBackground(Color.WHITE);
}
}
}
}
반응형
'java > java.awt & java.swing' 카테고리의 다른 글
[java.swing] 4. java.swing 패키지로 GUI 프로그램 만드는 법 | windowbuilder사용법 | 디지털시계 프로그램 | 계산기 프로그램 (0) | 2024.06.29 |
---|---|
[java.awt] 2. java.awt 패키지로 GUI 프로그램 만드는 법 (0) | 2024.06.29 |
[java.awt & java.swing] 1. GUI프로그램의 개념 (0) | 2024.06.28 |