Reputation: 14361
I'm trying to reduce the amount of code I need to handle keyboard presses/releases by using a common Action, while still using the InputMap/ActionMap paradigm (Need separate Press/Released information).
The problem I'm trying to solve is how to get the keyPressed/keyReleased information from the ActionEvent.
KeyStroke rKeyStrokeReleased = KeyStroke.getKeyStroke(KeyEvent.VK_R,
0, true);
KeyStroke rKeyStrokePressed = KeyStroke.getKeyStroke(KeyEvent.VK_R,
0, false);
Action rAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
// How do I get the pressed/release information here?
System.out.println(e);
}
};
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
rKeyStrokeReleased, "R_RELEASED");
getRootPane().getActionMap().put("R_RELEASED", rAction );
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
rKeyStrokePressed, "R_PRESSED");
getRootPane().getActionMap().put("R_PRESSED", rAction);
Upvotes: 1
Views: 113
Reputation: 324078
how to get the keyPressed/keyReleased information from the ActionEvent.
You can't get the information from the ActionEvent
.
You can get the information from the EventQueue
:
EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
AWTEvent event = queue.getCurrentEvent();
System.out.println(event.getID());
Upvotes: 4
Reputation: 285415
One way -- use the same class that extends AbstractAction, but use separate instances for pressed and released, and pass a boolean into the constructor, telling it which state it's in. For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class KeyBindingEg extends JPanel {
private static final String UP_KEY_PRESSED = "up key pressed";
private static final String UP_KEY_RELEASED = "up key released";
private static final int UP_TIMER_DELAY = 200;
private static final Color FLASH_COLOR = Color.red;
private Timer upTimer;
private JLabel label = new JLabel();
public KeyBindingEg() {
label.setFont(label.getFont().deriveFont(Font.BOLD, 32));
label.setOpaque(true);
add(label);
setPreferredSize(new Dimension(400, 300));
int condition = WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
KeyStroke upKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false);
KeyStroke upKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true);
inputMap.put(upKeyPressed, UP_KEY_PRESSED);
inputMap.put(upKeyReleased, UP_KEY_RELEASED);
actionMap.put(UP_KEY_PRESSED, new UpAction(false));
actionMap.put(UP_KEY_RELEASED, new UpAction(true));
}
private class UpAction extends AbstractAction {
private boolean onKeyRelease;
public UpAction(boolean onKeyRelease) {
this.onKeyRelease = onKeyRelease;
}
@Override
public void actionPerformed(ActionEvent evt) {
if (!onKeyRelease) {
if (upTimer != null && upTimer.isRunning()) {
return;
}
System.out.println("key pressed");
label.setText(UP_KEY_PRESSED);
upTimer = new Timer(UP_TIMER_DELAY, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Color c = label.getBackground();
if (FLASH_COLOR.equals(c)) {
label.setBackground(null);
label.setForeground(Color.black);
} else {
label.setBackground(FLASH_COLOR);
label.setForeground(Color.white);
}
}
});
upTimer.start();
} else {
System.out.println("Key released");
if (upTimer != null && upTimer.isRunning()) {
upTimer.stop();
upTimer = null;
}
label.setText("");
}
}
}
private static void createAndShowGui() {
KeyBindingEg mainPanel = new KeyBindingEg();
JFrame frame = new JFrame("KeyBindingEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Upvotes: 3