How to Use Keyeventdispatcher

How to use KeyEvent

You can use isControlDown() method:

switch (e.getKeyCode())
{
case KeyEvent.VK_A :
if(e.isControlDown())
System.out.println("A and Ctrl are pressed.");
else
System.out.println("Only A is pressed");
break;
...
}

How Do I Use KeyEventDispatcher

you have to look for KeyBindings

Sample Image

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.*;

public class MoveIcon extends JPanel {

private static final long serialVersionUID = 1L;
private static final String IMAGE_PATH = "http://duke.kenai.com/misc/Bullfight.jpg";
private static final String IMAGE_PATH_PLAYER = "http://duke.kenai.com/iconSized/duke4.gif";
public static final int STEP = 3;
private static final int TIMER_DELAY = STEP * 8;
private BufferedImage bkgrndImage = null;
private BufferedImage playerImage = null;
private Map<Direction, Boolean> directionMap = new HashMap<Direction, Boolean>();
private int playerX = 0;
private int playerY = 0;

enum Direction {

UP(KeyEvent.VK_UP, 0, -1), DOWN(KeyEvent.VK_DOWN, 0, 1),
LEFT(KeyEvent.VK_LEFT, -1, 0), RIGHT(KeyEvent.VK_RIGHT, 1, 0);
private int keyCode;
private int xDirection;
private int yDirection;

private Direction(int keyCode, int xDirection, int yDirection) {
this.keyCode = keyCode;
this.xDirection = xDirection;
this.yDirection = yDirection;
}

public int getKeyCode() {
return keyCode;
}

public int getXDirection() {
return xDirection;
}

public int getYDirection() {
return yDirection;
}
}

public MoveIcon() {
try {
URL bkgrdImageURL = new URL(IMAGE_PATH);
URL playerImageURL = new URL(IMAGE_PATH_PLAYER);
bkgrndImage = ImageIO.read(bkgrdImageURL);
playerImage = ImageIO.read(playerImageURL);
setPreferredSize(new Dimension(bkgrndImage.getWidth(), bkgrndImage.getHeight()));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
for (Direction direction : Direction.values()) {
directionMap.put(direction, false);
}
setKeyBindings();
Timer timer = new Timer(TIMER_DELAY, new TimerListener());
timer.start();
}

private void setKeyBindings() {
InputMap inMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actMap = getActionMap();
for (final Direction direction : Direction.values()) {
KeyStroke pressed = KeyStroke.getKeyStroke(direction.getKeyCode(), 0, false);
KeyStroke released = KeyStroke.getKeyStroke(direction.getKeyCode(), 0, true);
inMap.put(pressed, direction.toString() + "pressed");
inMap.put(released, direction.toString() + "released");
actMap.put(direction.toString() + "pressed", new AbstractAction() {

private static final long serialVersionUID = 1L;

@Override
public void actionPerformed(ActionEvent e) {
directionMap.put(direction, true);
}
});
actMap.put(direction.toString() + "released", new AbstractAction() {

private static final long serialVersionUID = 1L;

@Override
public void actionPerformed(ActionEvent e) {
directionMap.put(direction, false);
}
});
}

}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bkgrndImage != null) {
g.drawImage(bkgrndImage, 0, 0, null);
}
if (playerImage != null) {
g.drawImage(playerImage, playerX, playerY, null);
}
}

private class TimerListener implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
boolean moved = false;
for (Direction direction : Direction.values()) {
if (directionMap.get(direction)) {
playerX += STEP * direction.getXDirection();
playerY += STEP * direction.getYDirection();
moved = true;
}
}
if (moved) {
int x = playerX - 2 * STEP;
int y = playerY - 2 * STEP;
int w = playerImage.getWidth() + 4 * STEP;
int h = playerImage.getHeight() + 4 * STEP;
MoveIcon.this.repaint(x, y, w, h); // !! repaint just the player
}
}
}

private static void createAndShowUI() {
JFrame frame = new JFrame("MoveIcon");
frame.getContentPane().add(new MoveIcon());
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() {

@Override
public void run() {
createAndShowUI();
}
});
}
}

How to release KeyEvents events after KeyEventDispatcher fires?

The basic problem is, you are getting both a key pressed and key released event, but you are only changing optionselected on key release.

So:

  • Pressing C, on keyPressed, optionSelected is null, other will be null, on keyReleased, optionSelected becomes C, show dialog
  • Pressing T, on keyPressed optionselected is (still) C, show dialog, on keyReleased optionselected becomes T, show dialog

Instead, you should be processing only the keyReleased event

private class MyDispatcher implements KeyEventDispatcher {

@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_RELEASED) {
optionselected = e.getKeyChar();
other = String.valueOf(optionselected).toUpperCase();
switch (other) {
case "C":
JOptionPane.showMessageDialog(null, "Option 1");
break;
case "T":
JOptionPane.showMessageDialog(null, "Option 2");
break;
case "D":
JOptionPane.showMessageDialog(null, "Option 3");
break;
case "N":
JOptionPane.showMessageDialog(null, "Option 4");
break;
case "O":
JOptionPane.showMessageDialog(null, "Option 5");
break;
case "S":
JOptionPane.showMessageDialog(null, "Option 6");
break;
default:
break;
}
}
return false;
}
}

Having said all that, KeyEventDispatcher is very, very low level, a better solution might be to use the key bindings API, see How to Use Key Bindings for more details

How to use KeyEvents Listener in Java for KeyPressed

Using a KeyListener to a JPanel is not going to work. You will have to use KeyBindings instead. For example:

panel.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
panel.getActionMap().put("left", new AbstractAction() {

@Override
public void actionPerformed(ActionEvent e) {
System.out.println("left key is pressed");
}
});

However, these anonymous AbstractAction classes annoy me. That's why I would do something like that:

public class RunnableAction extends AbstractAction {

private Runnable action;

public RunnableAction(Runnable action) {
this.action = action;
}

@Override
public void actionPerformed(ActionEvent e) {
action.run();
}
}

And then:

panel.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
panel.getActionMap().put("left", new RunnableAction(panel::LeftKey));

panel.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right");
panel.getActionMap().put("right", new RunnableAction(panel::RightKey));

panel.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down");
panel.getActionMap().put("down", new RunnableAction(panel::DownKey));

panel.getInputMap().put(KeyStroke.getKeyStroke("UP"), "up");
panel.getActionMap().put("up", new RunnableAction(panel::UpKey));

However, I suggest you to try following the standard naming conventions. For example, methods should start with lower case. (panel.UpKey() should be panel.upKey(), etc)

Finally you do not have to have your main method in a class that extends Canvas. This is totally pointless.

Java how to use KeyEvent

Two keys cannot actually be pressed at the same time. The keyPressed() method is actually being called twice (once for a letter button, and once for shift). To check whether or not shift is pressed, set a global boolean value to the state of the shift press and manage the variable's state with keyPressed and keyReleased. For example:

public boolean shiftPressed;

public void keyPressed(KeyEvent e) {
if(shiftPressed && e.getKeyCode() == VK_(a letter)) {
//Execute some code
}
else if(e.getKeyCode() == VK_SHIFT) {
shiftPressed = true;
}
}

public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == VK_SHIFT) {
shiftPressed = false;
}
}


Related Topics



Leave a reply



Submit