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
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
isnull
,other
will benull
, onkeyReleased
,optionSelected
becomesC
, show dialog - Pressing T, on
keyPressed
optionselected
is (still)C
, show dialog, onkeyReleased
optionselected
becomesT
, 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
How to Rotate an Image Gradually in Swing
Module Error When Running Javafx Media Application
How to Directly Initialize a Hashmap (In a Literal Way)
Slf4J: Failed to Load Class "Org.Slf4J.Impl.Staticloggerbinder"
Handling Interruptedexception in Java
Under What Conditions Is a Jsessionid Created
Convert Java.Util.Date to Java.Time.Localdate
No Appenders Could Be Found for Logger(Log4J)
Differencebetween Up-Casting and Down-Casting with Respect to Class Variable
How to Add Custom Method to Spring Data JPA
Regex Doesn't Work in String.Matches()
Display Indeterminate Jprogressbar While Batch File Runs
What Is the Easiest/Best/Most Correct Way to Iterate Through the Characters of a String in Java
How to Extract a Substring Using Regex
Spring Boot and Multiple External Configuration Files
How Are Spring Data Repositories Actually Implemented
What's the Nearest Substitute for a Function Pointer in Java