본문 바로가기

coding/Java

[Java] GUI 응용프로그램(2) - Event Listener

자바의 GUI(Graphical User Interface) 기반으로 응용프로그램을 작성해보자.

이제 이벤트 처리를 배움으로써 '작동하는 프로그램'을 생성할 수 있다. 이벤트 기반 프로그래밍은 이벤트의 발생에 의해 프로그램 실행 흐름이 결정되는 방식의 프로그래밍 패러다임이다. 이벤트는 키 입력, 마우스 클릭, 마우스 드래그 등 사용자의 액션이나 센서 같은 외부 장치로부터의 입력, 네트워크를 통한 데이터 수신 등에 의해 발생된다.

이를 위해서는 각 이벤트를 처리하는 이벤트 리스너(Event Listener)를 implement 하고 컴포넌트에 이벤트 처리 객체를 등록해야 하는데, 이벤트가 발생될 때마다 리스너가 실행된다.

java.awt.event.*; 를 추가적으로 import 해줘야 한다.

 

사실 이건 예시를 직접 해봐야 이해가 쉽다. 예시는 이벤트 리스너의 종류에 따라 하나씩 보겠다.

 

 

(1) ActionListener

버튼을 누르는 Action 이벤트를 발생시킬 때 사용한다. ActionListener의 인터페이스는 자바 패키지에 선언되어 있는데, 다음과 같음. 우리는 actionPerformed 메소드를 반드시 오버라이드 해줘야 한다는 것을 알 수 있다.

interface ActionListener {
	public void actionPerformed(ActionEvent e); //Action 이벤트 발생 처리
}

 

 

"증가"라는 버튼을 누르면 카운터 값이 0부터 순차적으로 증가하는 프로그램을 구현해보자. 이벤트를 처리하는 방법(말이 이상한데... 클래스를 어떻게 구성할 건지에 따라 나눈다)에는 크게 3가지가 있다.

  1. 프레임 클래스가 이벤트를 처리
  2. 무명 클래스가 이벤트를 처리
  3. 클래스를 따로 생성

 

3번은 비효율적이다. 필자는 2번이 제일 편하지만 시험 공부를 위해서는 1번 2번 둘다 해봐야하기 때문에^^ 일단 프레임 클래스가 이벤트를 처리하는 방식으로 코드를 짜봤다. 프레임 클래스가 이벤트를 처리한다 = implement 해주기

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class MyFrame extends JFrame implements ActionListener{
	private JButton button;
	private JLabel label;
	private int counter = 0; //카운터값 초기화
	
	public void actionPerformed(ActionEvent e) {
		counter++;
		label.setText("현재의 카운터값: " + counter); //레이블에 출력되는 텍스트 counter에 따라 바꿔줌
	}
	public MyFrame() {
		setSize(400, 150);
		setLocation(200, 300);
		setTitle("이벤트 예제");
		setLayout(new FlowLayout());
		
		button = new JButton("증가");
		label = new JLabel("현재의 카운터값: " + counter);
		
		button.addActionListener(this);
		
		add(label, "Center");
		add(button, "East");
		setVisible(true);
	}
}

public class FinalTermTest {
	public static void main(String[] args) {
		MyFrame frame = new MyFrame();
	}
}

 

이번에는 무명 클래스가 이벤트를 처리한다.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class MyFrame extends JFrame {
	private JButton button;
	private JLabel label;
	private int counter = 0;
	
	public MyFrame() {
		setSize(400, 150);
		setTitle("이벤트 예제");
		setLayout(new FlowLayout());
		
		button = new JButton("증가");
		label = new JLabel("현재의 가운터값: " + counter);

		//무명 클래스 생성
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				counter++; 
				label.setText("현재의 카운터값: " + counter); 
			}
		}); //괄호 닫는거 조심해라!!!
		
		add(label, "Center");
		add(button, "East");
		setVisible(true);
	}
}

public class FinalTermTest {
	public static void main(String[] args) {
		MyFrame frame = new MyFrame();
	}
}

버튼을 누를 때 이벤트가 발생하니까 button.addactionPerformed를 해준다.

 

 

 

(2) KeyListener

사용자가 키보드를 이용하여 입력하는 하는 경우에 발생한다.

interface KeyListener {
	public void KeyPressed(KeyEvent e);
    	public void KeyReleased(KeyEvent e);
   	public void KeyTyped(KeyEvent e);
}

키 이벤트가 발생하려면 키보드 포커스가 맞아야 하는데, 다음 두 코드를 꼭 포함해줘야 한다.

이거 없으면 입력이 안됨(경험담이다)

  • panel.requestFocus();
  • panel.setFocusable(true);

 

엔터를 누를 때마다 랜덤 숫자를 보여주는 프로그램을 짜보자.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class MyFrame extends JFrame {
	int n1, n2, n3; //발생되는 숫자들
	JButton b1, b2, b3;
	
	public MyFrame() {
		setSize(300, 150);
		setLocation(200, 300);
		setTitle("Simple Game Machine");
		JPanel p = new JPanel();
		
		b1 = new JButton(""+n1); //강제 형변환 숫자->문자
		p.add(b1);
		b2 = new JButton(""+n2); //강제 형변환 숫자->문자
		p.add(b2);
		b3 = new JButton(""+n3); //강제 형변환 숫자->문자
		p.add(b3);
		
		p.requestFocus();
		p.setFocusable(true);
		
		p.addKeyListener(new KeyListener() {
			public void keyPressed(KeyEvent e) {
				int keycode = e.getKeyCode();
				if(keycode == KeyEvent.VK_ENTER) {
					n1 = (int)(Math.random()*10); //0~9사이의 값
					n2 = (int)(Math.random()*10); //0~9사이의 값
					n3 = (int)(Math.random()*10); //0~9사이의 값
					b1.setText(""+n1);
					b2.setText(""+n2);
					b3.setText(""+n3);
				}
			}
			//나머지 두 메소드는 안쓰니깐 열고닫기만 해서 재정의 끝
			@Override
			public void keyTyped(KeyEvent e) {}
			@Override
			public void keyReleased(KeyEvent e) {}
		});
		
		add(p);
		setVisible(true);
	}
}

public class FinalTermTest {
	public static void main(String[] args) {
		MyFrame frame = new MyFrame();
	}
}

 

방향키를 이용해 자동차를 움직이는 프로그램.

mport javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class MyFrame extends JFrame {
	private int x; //x축 좌표
	private int y; //y축 좌표
	
	public MyFrame() {
		x = 150;
		y = 150;
		setSize(600, 300);
		JButton b = new JButton();
		
		//이미지 작업
		ImageIcon icon = new ImageIcon("car.png"); //이미지 경로 써주기
		b.setIcon(icon); //버튼에 아이콘 넣기
		b.setLocation(x, y);
		
		JPanel p = new JPanel();
		p.add(b);
		p.requestFocus();
		p.setFocusable(true);
		
		//이벤트 처리(무명클래스)
		p.addKeyListener(new KeyListener() {
			public void keyPressed(KeyEvent e) {
				int keycode = e.getKeyCode();
				switch(keycode) {
				case KeyEvent.VK_UP: y-=10; break;
				case KeyEvent.VK_DOWN: y+=10; break;
				case KeyEvent.VK_LEFT: x-=10; break;
				case KeyEvent.VK_RIGHT: x+=10; break;
				}
				System.out.println("x="+x+" y="+y);
				b.setLocation(x, y); //바뀐거 적용
			}
			@Override
			public void keyTyped(KeyEvent e) {}
			@Override
			public void keyReleased(KeyEvent e) {}
		});
		
		add(p);
		setVisible(true);
	}
}

public class FinalTermTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyFrame frame = new MyFrame();
	}

}