在 Java 圖形介面開發中,捕捉鍵盤事件是實現使用者互動的基礎。雖然早期的 AWT `Applet` 透過 `keyDown(Event, int)` 方法處理按鍵,但現代 Java 開發已全面轉向 Swing 與 JavaFX,並採用事件監聽器模式。本文將回顧經典的 AWT 寫法,並引導你遷移至現代標準的 `KeyListener` 介面實作。
早期教學常見的範例繼承 `java.applet.Applet`,覆寫 `keyDown` 方法:
import java.awt.Graphics;
import java.awt.Event;
import java.awt.Font;
import java.awt.Color;
public class Keys extends java.applet.Applet {
char currKey;
int currX, currY;
public void init() {
currX = (this.getSize().width / 2) - 8;
currY = (this.getSize().height / 2) - 16;
setBackground(Color.white);
setFont(new Font("Helvetica", Font.BOLD, 36));
}
public boolean keyDown(Event evt, int key) {
switch (key) {
case Event.DOWN: currY += 5; break;
case Event.UP: currY -= 5; break;
case Event.LEFT: currX -= 5; break;
case Event.RIGHT: currX += 5; break;
default:
currKey = (char) key;
}
repaint();
return true;
}
public void paint(Graphics g) {
if (currKey != 0) {
g.drawString(String.valueOf(currKey), currX, currY);
}
}
}
缺點: 依賴已棄用的 `Event` 類別與 `Applet` 架構,無法在現代 JFrame 或 JavaFX 應用中直接使用。
在 Swing 中,應實作 `java.awt.event.KeyListener` 介面,並向元件註冊監聽器。以下範例展示在 `JPanel` 中移動物體與顯示字元:
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyEventDemo extends JPanel implements KeyListener {
private int x = 150, y = 150;
private char currentChar = 0;
public KeyEventDemo() {
setFocusable(true);
addKeyListener(this);
setPreferredSize(new Dimension(300, 300));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (currentChar != 0) {
g.setFont(new Font("Helvetica", Font.BOLD, 36));
g.drawString(String.valueOf(currentChar), x, y);
}
}
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_UP: y -= 5; break;
case KeyEvent.VK_DOWN: y += 5; break;
case KeyEvent.VK_LEFT: x -= 5; break;
case KeyEvent.VK_RIGHT: x += 5; break;
}
repaint();
}
@Override
public void keyTyped(KeyEvent e) {
currentChar = e.getKeyChar();
repaint();
}
@Override
public void keyReleased(KeyEvent e) { /* 不處理 */ }
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("鍵盤事件示範");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new KeyEventDemo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}