9.1 이벤트 기반 GUI 프로그래밍
이벤트 기반 프로그래밍
- 이벤트 기반 프로그래밍(event driven programming): 이벤트 발생에 의해 프로그램 흐름이 결정되는 방식
- 배치 실행(batch programming): 프로그램의 개발자가 프로그램의 흐름을 결정하는 방식
자바의 이벤트 기반 GUI 응용프로그램 구조
: 각 이벤트마다 처리하는 리스너 코드를 보유한다.
▶ 자바 스윙 프로그램에서 이벤트 처리 과정:
- 이벤트 발생
- 이벤트 객체 생성: 현재 발생한 이벤트에 대한 정보를 가진 객체
- 응용프로그램에 작성된 이벤트 리스너 찾기
- 이벤트 리스너 실행
- 리스너에 이벤트 객체 전달
- 리스너 코드 실행
9.2 이벤트 객체
이벤트 객체와 이벤트 정보
- 이벤트 객체: 발생한 이벤트에 관한 정보를 가진 객체
이벤트 객체와 이벤트 소스
9.3 사용자 이벤트 리스너 작성
리스너 인터페이스
이벤트 리스너 작성
- 이벤트와 이벤트 리스너 선택: 목적에 필요한 이벤트와 리스터 인터페이스 선택
- 이벤트: Action 이벤트
- 이벤트 리스너: ActionListener
- 이벤트 객체: ActionEvent
- 이벤트 리스너 클래스 작성: 리스너 인터페이스를 상속받는 클래스를 작성하고, 추상 메소드 모두 구현
- 독립 클래스로 작성
- 내부 클래스(inner class)로 작성
- 익명 클래스(anonymous class)로 작성
- 이벤트 리스너 등록: 이벤트를 받을 GUI 컴포넌트에 이벤트 리스너 등록
▶ 독립 클래스를 이용한 이벤트 리스너 작성
/*
* 예제 9-1: 독립 클래스로 Action 이벤트 리스너 만들기
* 버튼을 클릭할 때 발생하는 Action 이벤트를 처리할 MyActionListener 클래스를 독립 클래스로 작성하여,
* 클릭할 때마다 버튼 문자열이 Action과 액션으로 번갈아 변하도록 한다.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class IndepClassListener extends JFrame {
public IndepClassListener() {
setTitle("Action 이벤트 리스너 예제");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JButton btn = new JButton("Action");
btn.addActionListener(new MyActionListener()); // Action 이벤트 리스너 달기
c.add(btn);
setSize(250, 120);
setVisible(true);
}
public static void main(String[] args) {
new IndepClassListener();
}
// 독립된 클래스로 이벤트 리스너를 작성한다.
class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
JButton b = (JButton)e.getSource(); // 이벤트 소스 버튼 알아내기
if(b.getText().equals("Action")) // 버튼의 문자열이 Action인지 비교
b.setText("액션");
else
b.setText("Action");
}
}
}
▶ 내부 클래스를 이용한 이벤트 리스너 작성
/*
* 예제 9-2: 내부 클래스로 Action 이벤트 리스너 만들기
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class InnerClassListener extends JFrame {
public InnerClassListener() {
setTitle("Action 이벤트 리스너 예제");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JButton btn = new JButton("Action");
btn.addActionListener(new MyActionListener());
c.add(btn);
setSize(200,120);
setVisible(true);
}
// 내부 클래스로 Action 리스너를 작성한다.
private class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
JButton b = (JButton)e.getSource();
if(b.getText().equals("Action"))
b.setText("액션");
else
b.setText("Action");
// InnerClassListener의 멤버나 JFrame의 멤버를 호출할 수 있음
InnerClassListener.this.setTitle(b.getText()); // 프레임의 타이틀에 버튼 문자열을 출력한다.
}
}
public static void main(String[] args) {
new InnerClassListener();
}
}
▶ 익명 클래스(anonymous class)로 이벤트 리스너 작성
/*
* 예제 9-3: 익명 클래스를 이용하여 이벤트 리스너 작성
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AnonymousClassListener extends JFrame {
public AnonymousClassListener() {
setTitle("Action 이벤트 리스너 작성");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JButton btn = new JButton("Action");
c.add(btn);
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
JButton b = (JButton)e.getSource();
if(b.getText().equals("Action"))
b.setText("액션");
else
b.setText("Action");
// AnonymousClassListener의 멤버나 JFrame의 멤버를 호출할 수 있음
setTitle(b.getText());
}
});
setSize(200,120);
setVisible(true);
}
public static void main(String[] args) {
new AnonymousClassListener();
}
}
/*
* 예제 9-4: 마우스 이벤트 리스너 작성 연습 - 마우스로 문자열 이동시키기
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MouseListenerEx extends JFrame {
private JLabel la = new JLabel("Hello"); // Hello 문자열을 출력하기 위한 레이블
public MouseListenerEx() {
setTitle("Mouse 이벤트 예제");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.addMouseListener(new MyMouseListener()); // 컨텐트팬에 이벤트 리스너 달기
c.setLayout(null); // 컨텐트팬의 배치관리자 삭제
la.setSize(50, 20); // 레이블의 크기 50x20 설정
la.setLocation(30, 30); // 레이블의 위치 (30,30)으로 설정
c.add(la); // 레이블 삽입
setSize(200,200);
setVisible(true);
}
// Mouse 리스너 구현
class MyMouseListener implements MouseListener{
public void mousePressed(MouseEvent e) {
int x=e.getX(); // 마우스 클릭 좌표 x
int y=e.getY(); // 마우스 클릭 좌표 y
la.setLocation(x,y);
}
public void mouseReleased(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
public static void main(String[] args) {
new MouseListenerEx();
}
}
9.4 어댑터(Adapter) 클래스
: 리스너의 모든 메소드를 단순 리턴하도록 만든 클래스
/*
* 예제 9-5: MouseAdapter를 상속받아 마우스 리스너 작성
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MouseAdapterEx extends JFrame {
private JLabel la = new JLabel("Hello"); // Hello 문자열을 출력하기 위한 레이블 컴포넌트
public MouseAdapterEx() {
setTitle("Mouse 이벤트 예제");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.addMouseListener(new MyMouseAdapter()); // 컨텐트팬에 Mouse 이벤트 리스너 달기
c.setLayout(null); // 컨텐트팬의 배치관리자 삭제
la.setSize(50,20); // 레이블의 크기 50x20 설정
la.setLocation(30,30); // 레이블의 위치 (30,30)으로 설정
c.add(la); // 레이블 컴포넌트 삽입
setSize(200,200);
setVisible(true);
}
// MouseAdapter를 상속받아 리스너 구현
class MyMouseAdapter extends MouseAdapter{
public void mousePressed(MouseEvent e) {
int x=e.getX(); // 마우스 클릭 좌표 x
int y=e.getY(); // 마우스 클릭 좌표 y
la.setLocation(x,y); // 레이블의 위치를 (x,y)로 이동
}
}
public static void main(String[] args) {
new MouseAdapterEx();
}
}
9.5 Key 클래스와 KeyListener
Key 이벤트와 포커스
- Key 이벤트: 사용자가 키를 입력할 때 발생하는 이벤트
- 포커스(focus): 컴포넌트나 응용프로그램이 Key 이벤트를 독점하는 권한
- 현재 포커스(focus)를 가진 컴포넌트가 Key 이벤트를 독점한다.
KeyListener
: 키 이벤트 리스너는 KeyListener를 상속받아 구현한다.
키 이벤트 리스너 달기
: addKeyListener() 메소드
component.addKeyListener(myKeyListener);
가상 키와 입력된 키 판별
- char KeyEvent.getKeyChar(): 입력된 키의 유니코드 값을 리턴하며, 유니코드 키가 아닌 경우 KeyEvent.CHAR_UNDEFINED를 리턴한다.
- int KeyEvent.getKeyCode(): 모든 키에 대해 정수형의 키 코드(key code) 값을 리턴한다.
KeyEvent와 KeyListener 활용
/*
* 예제 9-6: KeyLister 활용 - 입력된 문자 키 판별
* <Enter> 키를 입력할 때마다 배경색을 랜덤하게 바꾸고,
* 'q' 키를 입력하면 프로그램을 종료시켜라.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class KeyCharEx extends JFrame {
private JLabel la = new JLabel("<Enter> 키로 배경색이 바뀝니다.");
public KeyCharEx() {
super("KeyListener의 문자 키 입력 예제");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane(); // 컨텐트팬 알아내기
c.setLayout(new FlowLayout());
c.add(la);
c.addKeyListener(new MyKeyListener()); // 키 리스너 달기
setSize(250, 150);
setVisible(true);
c.setFocusable(true); // 컨텐트팬이 포커스를 받을 수 있도록 설정
c.requestFocus(); // 컨텐트팬에 포커스 설정. 키 입력 가능해짐
}
class MyKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent e) {
// 임의의 색을 만들기 위해 랜덤하게 r, g, b 성분 생성
int r = (int)(Math.random()*256); // 0~255 사이의 임의의 red 성분
int g = (int)(Math.random()*256);
int b = (int)(Math.random()*256);
// 입력된 키 문자
switch(e.getKeyChar()) {
case '\n': // <Enter> 키 입력
la.setText("r=" + r + ", g=" + g + ", b=" + b);
getContentPane().setBackground(new Color(r,g,b)); // 컨텐트팬의 배경색 설정
break;
case 'q':
System.exit(0); // 프로그램 종료
break;
}
}
}
public static void main(String[] args) {
new KeyCharEx();
}
}
/*
* 예제 9-7: KeyListener 활용 - 상,하,좌,우 키로 문자열 움직이기
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FlyingTextEx extends JFrame {
private JLabel la = new JLabel("HELLO"); // 키 입력에 따라 움직일 레이블 컴포넌트
public FlyingTextEx() {
super("상,하,좌,우 키를 이용하여 텍스트 움직이기");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(null); // 컨텐트팬의 배치관리자 삭제
c.addKeyListener(new MyKeyListener());
la.setLocation(50,50); // 레이블의 초기 위치는 (50,50)
la.setSize(100,20);;
c.add(la);
setSize(200,200);
setVisible(true);
c.setFocusable(true); // 컨텐트팬이 포커스를 받을 수 있도록 설정
c.requestFocus(); // 컨텐트팬이 키 입력을 받을 수 있도록 포커스 강제 지정
}
// Key 리스너 구현
class MyKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode(); // 입력된 키의 키 코드를 알아낸다.
switch(keyCode) { // 키 코드에 따라 상,하,좌,우 키 판별, 레이블의 위치 이동
case KeyEvent.VK_UP: // UP 키
la.setLocation(la.getX(), la.getY() - 10);
break;
case KeyEvent.VK_DOWN: // DOWN 키
la.setLocation(la.getX(), la.getY() + 10);
break;
case KeyEvent.VK_LEFT: // LEFT 키
la.setLocation(la.getX() - 10, la.getY());
break;
case KeyEvent.VK_RIGHT: // RIGHT 키
la.setLocation(la.getX() + 10, la.getY());
break;
}
}
}
public static void main(String[] args) {
new FlyingTextEx();
}
}
9.6 Mouse 이벤트와 MouseListener, MouseMotionListener
- Mouse 이벤트: 사용자의 마우스 조작에 따라 발생하는 이벤트
마우스 리스너 달기
MouseEvent 객체 활용
Mouse 이벤트 처리 예
/*
* Mouse 이벤트 처리 예
* 마우스가 컨텐트팬에 올라가면 배경색을 CYAN으로, 컨텐트팬에서 내려가면 YELLOW로 변경한다.
*/
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class MouseEventAllEx extends JFrame {
private JLabel la = new JLabel(" Move Me"); // 마우스로 이동시킬 레이블 컴포넌트
public MouseEventAllEx() {
setTitle("MouseListener와 MouseMotionListener 예제");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
MyMouseListener listener = new MyMouseListener(); // 마우스/모션 리스너 객체 생성
c.addMouseListener(listener); // MouseListener 리스너 등록
c.addMouseMotionListener(listener); // MouseMotionListener 리스너 등록
c.setLayout(null); // 배치 관리자를 삭제하여 레이블을 마음대로 움직일 수 있게 함
la.setSize(80,20);
la.setLocation(100,80);
c.add(la); // 레이블 컴포넌트 삽입
setSize(320,200);
setVisible(true);
}
// Mouse 리스너와 MouseMotion 리스너를 모두 가진 리스너
class MyMouseListener implements MouseListener, MouseMotionListener{
// MouseListener의 5개 메소드 구현
public void mousePressed(MouseEvent e) {
la.setLocation(e.getX(), e.getY()); // 마우스가 눌러진 위치로 레이블 이동
setTitle("mousePressed(" + e.getX() + "," + e.getY() + ")"); // 눌러진 위치 출력
}
public void mouseReleased(MouseEvent e) {
la.setLocation(e.getX(), e.getY()); // 마우스가 놓여진 위치에 레이블 이동
setTitle("mouseReleased(" + e.getX() + "," + e.getY() + ")"); // 떼어진 위치 출력
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {
Component comp = (Component)e.getSource();
comp.setBackground(Color.CYAN); // 마우스가 올라간 곳 색 변경
}
public void mouseExited(MouseEvent e) {
Component comp = (Component)e.getSource();
comp.setBackground(Color.YELLOW); // 마우스가 내려간 곳 색 변경
setTitle("mouseExited(" + e.getX() + "," + e.getY() + ")"); // 벗어난 위치 출력
}
// MouseMotionListener의 2개 메소드 구현
public void mouseDragged(MouseEvent e) { // 마우스가 드래깅되는 동안 계속 호출
la.setLocation(e.getX(), e.getY());
setTitle("mouseDragged(" + e.getX() + "," + e.getY() + ")"); // 무브 위치 출력
}
public void mouseMoved(MouseEvent e) {
// 마우스가 이동할 때 호출
}
}
public static void main(String[] args) {
new MouseEventAllEx();
}
}
'Programming > Java프로그래밍및실습' 카테고리의 다른 글
[자프실] 11. 그래픽 (0) | 2024.01.15 |
---|---|
[자프실] 10. 스윙 컴포넌트 활용 (1) | 2024.01.13 |
[자프실] 8. 자바 GUI 스윙 기초 (1) | 2024.01.10 |
[자프실] 7. 컬렉션과 제네릭 (0) | 2024.01.07 |
[자프실] 6. 모듈과 패키지 개념, 자바 패키지 활용 (1) | 2024.01.05 |