package yr12.m07.a;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
public class KeyBindingsGuiTest {
private static void createAndShowUI() {
KeyBindingsGui guiPanel = new KeyBindingsGui();
JFrame frame = new JFrame("KeyBindingsGuiTest");
frame.getContentPane().add(guiPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
@SuppressWarnings("serial")
class KeyBindingsGui extends JPanel {
private static final Dimension SIZE = new Dimension(600, 600);
private static final int SPRITE_WIDTH = 26;
private static final int SPRITE_HEIGHT = SPRITE_WIDTH;
private static final int STROKE_WIDTH = 3;
private static final Color SPRITE_COLOR = Color.red;
private static final Color GUI_BCKGRD = Color.white;
private static final String PRESSED = "Pressed";
private static final String RELEASED = "Released";
public static final int SPRITE_STEP = 8;
private static final int SPRITE_STEP_PERIOD = 20;
private BufferedImage sprite;
private int spriteX = 0;
private int spriteY = 0;
private Map<Direction, Boolean> directionMap = new HashMap<Direction, Boolean>();
public KeyBindingsGui() {
setBackground(GUI_BCKGRD);
setPreferredSize(SIZE);
sprite = createSprite();
spriteX = (SIZE.width - SPRITE_WIDTH) / 2;
spriteY = (SIZE.height - SPRITE_HEIGHT) / 2;
for (Direction direction : Direction.values()) {
directionMap.put(direction, Boolean.FALSE);
}
setBindings();
Timer timer = new Timer(SPRITE_STEP_PERIOD, new GameLoopListener());
timer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (sprite != null) {
g.drawImage(sprite, spriteX, spriteY, null);
}
}
private void setBindings() {
int context = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(context);
ActionMap actionMap = getActionMap();
for (Direction direction : Direction.values()) {
inputMap.put(KeyStroke.getKeyStroke(direction.getKeyCode(), 0, false),
direction.getName() + PRESSED);
inputMap.put(KeyStroke.getKeyStroke(direction.getKeyCode(), 0, true),
direction.getName() + RELEASED);
// set corresponding actions for the key presses and releases above
actionMap.put(direction.getName() + PRESSED, new ArrowKeyAction(true,
direction));
actionMap.put(direction.getName() + RELEASED, new ArrowKeyAction(
false, direction));
}
}
private BufferedImage createSprite() {
BufferedImage sprite = new BufferedImage(SPRITE_WIDTH, SPRITE_HEIGHT,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = sprite.createGraphics();
g2d.setStroke(new BasicStroke(STROKE_WIDTH));
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(SPRITE_COLOR);
g2d.drawOval(STROKE_WIDTH, STROKE_WIDTH, SPRITE_WIDTH - 2 * STROKE_WIDTH,
SPRITE_HEIGHT - 2 * STROKE_WIDTH);
g2d.dispose();
return sprite;
}
private class ArrowKeyAction extends AbstractAction {
private Boolean pressed;
private Direction direction;
public ArrowKeyAction(boolean pressed, Direction direction) {
this.pressed = Boolean.valueOf(pressed);
this.direction = direction;
}
@Override
public void actionPerformed(ActionEvent arg0) {
directionMap.put(direction, pressed);
}
}
private class GameLoopListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
int x0 = spriteX;
int y0 = spriteY;
for (Direction direction : Direction.values()) {
if (directionMap.get(direction)) {
spriteX += SPRITE_STEP * direction.getVector().x;
spriteY += SPRITE_STEP * direction.getVector().y;
}
}
int x = Math.min(x0, spriteX);
int y = Math.min(y0, spriteY);
int w = Math.max(x0, spriteX) - x + SPRITE_WIDTH;
int h = Math.max(y0, spriteY) - y + SPRITE_HEIGHT;
repaint(x, y, w, h);
}
}
}
enum Direction {
UP("Up", KeyEvent.VK_UP, new Point(0, -1)), DOWN("Down", KeyEvent.VK_DOWN,
new Point(0, 1)), LEFT("Left", KeyEvent.VK_LEFT, new Point(-1, 0)), Right(
"Right", KeyEvent.VK_RIGHT, new Point(1, 0));
private String name;
private int keyCode;
private Point vector;
private Direction(String name, int keyCode, Point vector) {
this.name = name;
this.keyCode = keyCode;
this.vector = vector;
}
public String getName() {
return name;
}
public int getKeyCode() {
return keyCode;
}
public Point getVector() {
return vector;
}
@Override
public String toString() {
return name;
}
}