Background
My window is a java.awt.Frame, and inside of the Frame are two Panels (java.awt.Panel). I'm trying to make it so that the window handles buttons I press.
Try Number 1
I tried using a KeyListener, making the Frame implement the KeyListener. I added the KeyListener to the Frame, but the KeyListener functions didn't do anything when I pressed keys. (I tried printing with System.out.println().)
Try Number 2
I tried following this tutorial: http://tips4java.wordpress.com/2008/10/10/key-bindings/ . Here is the my attempt to handle pressing the SPACEBAR:
public void registerActions(){ //01
Action myAction = new AbstractAction(){ //02
@Override //03
public void actionPerformed(ActionEvent e) { //04
System.out.println("GREAT SUCCESS!"); //05
} //06
}; //07
KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0); //08
component.getInputMap().put(key, "myAction"); //09
component.getActionMap().put("myAction", myAction); //10
} //11
The main problem is that I don't know what 'component' should be in lines 09 & 10, because my application does not have any JComponents.
My Question
Is there a way to do this without using swing components? Or is there another way to handle key presses?
I found that I could do this with an AWTEventListener.
public class MyFrame extends Frame implements AWTEventListener {
...
public MyFrame(String title){
super(title);
...
this.getToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
}
@Override
public void eventDispatched(AWTEvent event) {
if(event instanceof KeyEvent){
KeyEvent key = (KeyEvent)event;
if(key.getID()==KeyEvent.KEY_PRESSED){ //Handle key presses
System.out.println(key.getKeyChar());
//TODO: do something with the key press
key.consume();
}
}
}
}
Okay, here's an example using a JPanel
.
I created a Frame
, set it's layout to BorderLayout
added to the KeyPane
to it and voila...
public class KeyPane extends JPanel {
private Timer paintTimer;
private MouseFocusHandler mouseFocusHandler;
private boolean spaceOn = false;
private int yPos = 0;
private int direction = 2;
private Rectangle blob = new Rectangle(0, 0, 10, 10);
public KeyPane() {
setFocusable(true);
InputMap im = getInputMap(WHEN_FOCUSED);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "Space");
am.put("Space", new SpaceAction());
setPreferredSize(new Dimension(100, 100));
getPaintTimer().setCoalesce(false);
getPaintTimer().start();
}
@Override
public void addNotify() {
super.addNotify();
requestFocusInWindow();
addMouseListener(getMouseFocusHandler());
getPaintTimer().start();
}
@Override
public void removeNotify() {
removeMouseListener(getMouseFocusHandler());
getPaintTimer().stop();
super.removeNotify();
}
protected Timer getPaintTimer() {
if (paintTimer == null) {
paintTimer = new Timer(40, new RepaintAction());
paintTimer.setRepeats(true);
paintTimer.setCoalesce(true);
}
return paintTimer;
}
protected MouseFocusHandler getMouseFocusHandler() {
if (mouseFocusHandler == null) {
mouseFocusHandler = new MouseFocusHandler();
}
return mouseFocusHandler;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth() - 1;
int height = getHeight() - 1;
g2d.setColor(Color.GREEN);
blob.x = (width - blob.width) / 2;
System.out.println(blob);
g2d.fill(blob);
if (spaceOn) {
g2d.setFont(UIManager.getFont("Label.font").deriveFont(24f));
FontMetrics fm = g2d.getFontMetrics();
String spaceIsOn = "Space On";
int x = (width - fm.stringWidth(spaceIsOn)) / 2;
int y = ((height - fm.getHeight()) / 2) + fm.getAscent();
g2d.drawString(spaceIsOn, x, y);
}
g2d.dispose();
}
protected class MouseFocusHandler extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e) {
requestFocusInWindow();
}
}
protected class RepaintAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
yPos += direction;
blob.y = yPos;
if (blob.y + blob.height > getHeight() - 1) {
blob.y = getHeight() - 1 - blob.height;
direction = -2;
} else if (blob.y < 0) {
blob.y = 0;
direction = 2;
}
repaint();
}
}
protected class SpaceAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
spaceOn = !spaceOn;
repaint();
}
}
}