整个JFrame采用null布局,图片放在Jlabel中,实现了使用键盘上面的方向键控制图片的移动。可以选择方向为上,下,左,右,左上,左下,右上,右下等8个方向,当图片移动到窗口边缘时就不再移动。
KEY枚举:根据按键结果得到的移动方向
HORIZION枚举:键盘上按下的左右方向键(左、右)
VERTICAL枚举:键盘上按下的上下方向键(上、下)
STEP:图片响应按键时移动的单位
怎么响应两个键?
若一个键按下(发出press事件)后没有弹起(未发出release事件)时,按下了另一个键(发出press事件),此时就是两个键同时按下了。
由于按键由程序的枚举量记录,当按下相反方向键时(不是同时按住,也就是说按一个键后弹起了再按另一个),需要将前一次按下的方向记录清除(如:先按了左,然后再按右,此时将左的记录清除)。
- package com.cnblogs.hyjiacan;
- import java.awt.Color;
- import java.awt.Point;
- import java.awt.event.KeyAdapter;
- import java.awt.event.KeyEvent;
- import javax.swing.Icon;
- import javax.swing.ImageIcon;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- enum KEY {
- UP, RIGHT, DOWN, LEFT, RIGHT_UP, RIGHT_DOWN, LEFT_UP, LEFT_DOWN
- }
- enum HORIZION {
- LEFT, RIGHT
- }
- enum VERTICAL {
- UP, DOWN
- }
- public class MoveImage {
- JFrame win;
- Icon img;
- JLabel lb;
- static final int STEP = 2;
- KEY key;
- HORIZION hor;
- VERTICAL ver;
- public MoveImage() {
- hor = null;
- ver = null;
- win = new JFrame("MoveImage");
- win.setLayout(null);
- // 加载图片
- img = new ImageIcon(getClass().getResource("img.gif"));
- lb = new JLabel();
- lb.setSize(img.getIconWidth(), img.getIconHeight());
- // 装载图片
- lb.setIcon(img);
- win.setBounds(200, 0, 400, 300);
- // 响应键盘上的键按下事件
- win.addKeyListener(new KeyAdapter() {
- // 键值临时量
- int k;
- @Override
- public void keyPressed(KeyEvent e) {
- k = e.getKeyCode();
- switch (k) {
- case KeyEvent.VK_UP:
- ver = VERTICAL.UP;
- break;
- case KeyEvent.VK_DOWN:
- ver = VERTICAL.DOWN;
- break;
- case KeyEvent.VK_RIGHT:
- hor = HORIZION.RIGHT;
- break;
- case KeyEvent.VK_LEFT:
- hor = HORIZION.LEFT;
- break;
- }
- if (ver == null) {
- if (hor == HORIZION.RIGHT) {
- key = KEY.RIGHT;
- } else {
- key = KEY.LEFT;
- }
- } else if (hor == null) {
- if (ver == VERTICAL.UP) {
- key = KEY.UP;
- } else {
- key = KEY.DOWN;
- }
- } else {
- if (hor == HORIZION.RIGHT) {
- if (ver == VERTICAL.UP) {
- key = KEY.RIGHT_UP;
- } else {
- key = KEY.RIGHT_DOWN;
- }
- } else {
- if (ver == VERTICAL.UP) {
- key = KEY.LEFT_UP;
- } else {
- key = KEY.LEFT_DOWN;
- }
- }
- }
- move(key);
- }
- @Override
- public void keyReleased(KeyEvent e) {
- k = e.getKeyCode();
- switch (k) {
- case KeyEvent.VK_UP:
- ver = null;
- break;
- case KeyEvent.VK_DOWN:
- ver = null;
- break;
- case KeyEvent.VK_RIGHT:
- hor = null;
- break;
- case KeyEvent.VK_LEFT:
- hor = null;
- break;
- }
- }
- });
- win.add(lb);
- win.getContentPane().setBackground(Color.WHITE);
- win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- win.setVisible(true);
- win.validate();
- }
- /**
- * 移动图片, 只处理上下左右4个方向键,其它的不处理
- *
- * @param keyCode
- * 按下的键盘上的键的键值
- */
- void move(KEY key) {
- // 记下当前的位置
- Point pos = lb.getLocation();
- switch (key) {
- case UP:// 上方向
- pos.y -= STEP;
- break;
- case RIGHT:// 右方向
- pos.x += STEP;
- break;
- case DOWN:// 下方向
- pos.y += STEP;
- break;
- case LEFT:// 左方向
- pos.x -= STEP;
- break;
- case RIGHT_UP:// 右上方向
- pos.x += STEP;
- pos.y -= STEP;
- break;
- case RIGHT_DOWN:// 右下方向
- pos.x += STEP;
- pos.y += STEP;
- break;
- case LEFT_DOWN:// 左下方向
- pos.x -= STEP;
- pos.y += STEP;
- break;
- case LEFT_UP:// 左上方向
- pos.x -= STEP;
- pos.y -= STEP;
- break;
- }
- // 是否移动到了边缘
- if (pos.x >= win.getWidth() - lb.getWidth() || pos.x < 0
- || pos.y >= win.getHeight() - lb.getHeight() || pos.y < 0)
- return;
- // 设置新位置
- lb.setLocation(pos);
- lb.validate();
- }
- public static void main(String[] args) {
- MoveImage m = new MoveImage();
- }
- }
遗留问题:
在同时按住上下或者左右方向时,图片会朝着后面按下的那个方向键指定的方向移动(理论上此时应该不动的)
在同时按住两个方向键移动时,图片会先移动一下,然后会顿一下,再继续移动。
原文链接:http://www.cnblogs.com/hyjiacan/archive/2012/05/02/swing-move-image-via-keyboard.html
【编辑推荐】