KeyEvent와 KeyListener
Key 이벤트와 포커스
Key 이벤트는 사용자가 키를 입력할 때 발생하는 이벤트이며, 모든 컴포넌트가 Key 이벤트를 받을 수 있습니다. 그러나 응용프로그램 내에 포커스(focus)를 가진 컴포넌트가 키 입력을 독점하기 때문에, 현재 포커스를 가진 컴포넌트에만 Key 이벤트가 전달됩니다. 포커스란 키 입력의 독점권을 뜻합니다. 버튼을 누르기 위해 <Enter> 키를 입력하더라도 버튼이 포커스를 가지고 있지 않다면 Key 이벤트를 받을 수 없습니다.
어떤 컴포넌트에게 키를 입력하고자 하면 <Tab> 키나 마우스 클릭으로 포커스를 그 컴포넌트에게 이동시키켜야 합니다. 스윙 응용프로그램에서는 강제로 임의의 컴포넌트에 포커스를 주기 위해 다음 두 코드가 모두 필요합니다.
component.setFocusable(true); // component가 포커스를 받을 수 있도록 설정한다.
component.requestFocus(); // component에게 포커스를 주어 키 입력을 받을 수 있게 함
component.requestFocus()만으로 component가 키 입력을 받을 수 있는 경우가 대부분이지만, 컴퓨터의 설치 상황(실행 환경)에 따라 component.setFocusable(true)가 없으면 키 입력을 받지 못하는 경우가 있으므로 반드시 두 코드를 이용해야 합니다.
컴포넌트에 포커스 주기
키 입력을 받기 위해서는 포커스를 주는 시점 또한 중요합니다. 첫째, 스윙 프레임이 만들어질 때, 어떤 컴포넌트에게 포커스를 주고자 한다면, JFrame의 setVisible(true) 코드를 실행한 후 컴포넌트의 requestFocus() 메서드를 호출해야 합니다. JFrame의 setVisible(true) 메서드는 프레임을 출력한 후 포커스를 임의로 움직이기 때문입니다.
setVisible(true); // 스윙 프레임 출력
component.setFocusable(true);
component.requestFocus(); // component 컴포넌트에게 포커스 설정
둘째, 사용자가 마우스를 컴포넌트를 클릭하면 그때 컴포넌트가 포커스를 얻도록 하는 방법으로 다음 코그를 작성하면 됩니다.
component.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvnet e) {
Compoment c = (Component) e.getSource(); // 마우스가 클릭된 컴포넌트
c.setFocusable(true);
c.requestFocus(); // 마우스가 클릭된 컴포넌트에게 포커스 설정
}
});
Key 이벤트와 KeyListener
모든 키에 대해서 '키를 누르는 순간', 누른 키를 떼는 순간'에 각각 Key 이벤트가 한 번씩 발생합니다. 특별히 문자 키(유니코드 키)인 경우에는 '누른 키를 떼는 순간'에 Key 이벤트가 한 번 더 발생하여 총 3번의 Key 이벤트가 발생하며, KeyListener의 메서드가 호출됩니다.
KeyListener 인터페이스는 3개의 추상 메서드로 구성됩니다. KeyPressed()는 키를 누르는 순간에, KeyReleased()는 누른 키를 떼는 순간에 호출되며, 문자 키(유니코드)의 경우에는 누른 키가 뗴어지는 순간 keyTyped()가 추가적으로 호출됩니다.
유니코드(Unicode)란 전 세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다루고자 설계된 국제 산업 표준입니다.
<Function> 키, <Home> 키, <Up> 키 등 문자가 아닌 제어 키들에 대해서는 유니코드 값을 정의하지 않습니다.
유니코드 키가 입력될 때, KeyListener의 메소드가 호출되는 순서는 다음과 같습니다.
KeyPressed(), KeyTyped(), KeyReleased()
키 이벤트 리스너 달기
컴포넌트에 키 이벤트 리스너를 등록하기 위해서는 다음과 같이 addKeyListener() 메서드를 이용합니다.
component.addKeyListener(myKeyListener);

입력된 키 판별
키 이벤트가 발생하면 입력된 키 정보가 KeyEvent 객체에 담겨저 리스너에게 전달됩니다. KeyEvent 객체의 다음 2개의 메서드를 통해 입력된 키를 판별할 수 있습니다.
char KeyEvent.getKeyChar()
입력된 키의 문자코드(유니코드 값)를 리턴하며, 유니코드 키가 아닌 경우 KeyEvent.CHAR_UNDEFINED를 리턴합니다. getKeyChar()의 리턴 값과 문자 'q'를 서로 비교하면 됩니다.
int KeyEvent.getKeyCode()
이 메서드는 유니코드 키를 포함한 모든 키에 대해 정수형의 키 코드(key code) 값을 리턴합니다. 키 코드는 운영체제나 하드웨어에 따라 서로 다를 수 있기 때문에, 입력된 키를 판별하기 위해서는 반드시 getKeyCode()가 리턴한 키 코드와 가상 키(Virtual Key) 값을 비교해야 합니다. 가상 키는 KeyEvent 클래스에 VK_로 시작하는 static 상수로 선언되어 있습니다.


KeyEvent와 KeyListener의 활용
키 이름의 문자열은 KeyEvent 클래스의 static 타입 getKeyText() 메서드로부터 얻을 수 있습니다. 이 메서드는 키 코드 값을 인지로 받아 키 이름 문자열을 리턴합니다.
static String KeyEvent.getKeyText(int KeyCode)
다양한 KeyEvent와 KeyListener 활용
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class KeyListenerEx extends JFrame {
private JLabel [] keyMessage; // 3개의 메시지를 출력할 레이블 컴포넌트 배열
public KeyListenerEx() {
setTitle("keyListener 예제");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new FlowLayout());
c.addKeyListener(new MyKeyListener());
// 레이블 배열을 3개 생성하고 각 레이블 컴포넌트 생성
keyMessage = new JLabel [3]; // 레이블 배열 생성
keyMessage[0] = new JLabel(" getKeyCode() ");
keyMessage[1] = new JLabel(" getKeyChar() ");
keyMessage[2] = new JLabel(" getKeyText() ");
// 3개의 레이블 컴포넌트를 컨텐트팬에 부착
for(int i=0; i<keyMessage.length; i++) {
c.add(keyMessage[i]);
keyMessage[i].setOpaque(true); // 배경색이 보이록 불투명 속성 설정
keyMessage[i].setBackground(Color.YELLOW); // 배경색을 CYAN 색으로 변경
}
setSize(300,150);
setVisible(true);
// 컨텐트팬이 키 입력을 받을 수 있도록 포커스 강제 지정
c.setFocusable(true);
c.requestFocus();
}
// Key 리스너 구현
class MyKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode(); // 키 코드 알아내기
char keyChar = e.getKeyChar(); // 키 문자 값 알아내기
keyMessage[0].setText(Integer.toString(keyCode)); // 키 코드 출력
keyMessage[1].setText(Character.toString(keyChar)); // 키 문자 출력
keyMessage[2].setText(KeyEvent.getKeyText(keyCode)); // 키 이름 문자열 출력
System.out.println("KeyPressed"); // 콘솔창에 메소드 이름 출력
}
public void keyReleased(KeyEvent e) {
System.out.println("KeyReleased"); // 콘솔창에 메소드 이름 출력
}
public void keyTyped(KeyEvent e) {
System.out.println("KeyTyped"); // 콘솔창에 메소드 이름 출력
}
}
public static void main(String [] args) {
new KeyListenerEx();
}
}
[실행 결과]


<F1> 키를 입력받으면 컨텐트 팬의 배경을 초록색으로 '% 키를 입력받으면 노란색으로 변경
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class KeyCodeEx extends JFrame {
private JLabel la = new JLabel(); // 빈 레이블 컴포넌트 생성
public KeyCodeEx() {
setTitle("Key Code 예제 : F1키:초록색, % 키 노란색");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.addKeyListener(new MyKeyListener());
c.add(la);
setSize(300,150);
setVisible(true);
// 컨텐트팬이 키 입력을 받을 수 있도록 포커스 강제 지정
c.setFocusable(true);
c.requestFocus();
}
// Key 리스너 구현
class MyKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
Container contentPane = (Container)e.getSource();
// la에 입력된 키의 키 이름 문자열을 출력하여 사용자에게 보고함
la.setText(KeyEvent.getKeyText(e.getKeyCode())+"키가 입력되었음");
if(e.getKeyChar() == '%') // 입력된 키가 % 인 경우
contentPane.setBackground(Color.YELLOW);
else if(e.getKeyCode() == KeyEvent.VK_F1) // 입력된 키가 <F1> 인가
contentPane.setBackground(Color.GREEN);
}
}
public static void main(String [] args) {
new KeyCodeEx();
}
}
[실행 결과]


상(UP), 하(DOWN), 죄(LEFT), 우(RIGHT) 키로 "HELLO" 문자열을 마음대로 출력하기
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class FlyingTextEx extends JFrame {
private final int FLYING_UNIT = 10; // 레이블이 한 번 움직이는 단위는 10픽셀
private JLabel la = new JLabel("HELLO"); // 키 입력에 따라 움직일 레이블 컴포넌트
public FlyingTextEx() {
setTitle("상,하,좌,우 키를 이용하여 텍스트 움직이기");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(null); // 컨텐트팬의 배치관리자 삭제
c.addKeyListener(new MyKeyListener()); // 컨텐트팬에 Key 리스너 달기
la.setLocation(50,50); // la의 초기 위치는 (50,50)
la.setSize(100,20);
c.add(la);
setSize(300,300);
setVisible(true);
c.setFocusable(true);
c.requestFocus(); //컨텐트팬이 키 입력을 받을 수 있도록 포커스 강제 지정
// 다음 코드는 컨텐트팬에 포커스를 잃은 경우 마우스를 클릭하면 다시 포커스를 얻게 함
c.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
Component c = (Component)e.getSource(); // 마우스가 클릭된 컴포넌트
c.setFocusable(true);
c.requestFocus(); // 컴포넌트에게 포커스 설정
}
});
}
// Key 리스너 구현
class MyKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode(); // 입력된 키의 키코드를 알아낸다.
// 키 코드 값(keyCode)에 따라 상,하,좌,우 키를 판별하고 la의 위치를 이동시킨다.
switch(keyCode) {
case KeyEvent.VK_UP: // UP 키
la.setLocation(la.getX(), la.getY()-FLYING_UNIT); break;
case KeyEvent.VK_DOWN: // DOWN 키
la.setLocation(la.getX(), la.getY()+FLYING_UNIT); break;
case KeyEvent.VK_LEFT: // LEFT 키
la.setLocation(la.getX()-FLYING_UNIT, la.getY()); break;
case KeyEvent.VK_RIGHT: // RIGHT 키
la.setLocation(la.getX()+FLYING_UNIT, la.getY()); break;
}
}
}
public static void main(String [] args) {
new FlyingTextEx();
}
}
[실행 결과]


'프로그래밍 언어 > JAVA' 카테고리의 다른 글
| 스윙 컴포넌트 소개 (2) | 2025.06.20 |
|---|---|
| MouseEvent와 MouseListener, MouseMotionListener, MouseWheelListener (1) | 2025.06.17 |
| 어댑터(Adapter) 클래스 (1) | 2025.06.11 |
| 이벤트 리스너 (1) | 2025.06.08 |
| 이벤트 객체 (0) | 2025.06.05 |