1

I'm working through some tutorials but have been stuck on keyEvents for days. I'm sure it's to do with how I'm implementing it as I cant even get a print statement.

Here's my troubling snippet

static class Keyboard extends JPanel {

public Keyboard() {
   addKeyListener(new KeyAdapter() {

       public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            System.out.println("pressed");
            switch (e.getKeyCode()) {
            case KeyEvent.VK_DOWN: 
                y += 10;break;
            case KeyEvent.VK_UP:
                y -= 10;break;
            case KeyEvent.VK_LEFT:
                x -= 10;break;
            case KeyEvent.VK_RIGHT:
                x += 10;break;
            }
            repaint();
        }
    });
}
}

and here's the full code. Its just a simple awt demonstration where you can move and enlarge a circle with existing buttons.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ShapeTest1 extends JFrame {

   private JButton enlarge = new JButton("enlarge"); 
   private JButton up = new JButton("up"); 
   private JButton right = new JButton("right"); 
   private JButton down = new JButton("down"); 
   private JButton left = new JButton("left"); 
   BoardPanel bp;
   public ShapeTest1()
   {
  bp = new BoardPanel();

  // Create a separate panel and add all the buttons 
  JPanel panel = new JPanel();
  panel.add(enlarge); 
  panel.add(up); 
  panel.add(right); 
  panel.add(down); 
  panel.add(left); 

 // add Action listeners to all button events
 enlarge.addActionListener(bp);
  up.addActionListener(bp);
  down.addActionListener(bp);
  left.addActionListener(bp);
  right.addActionListener(bp);

 // add panels to frame
 add (bp, BorderLayout.CENTER);             
  add (panel,BorderLayout.SOUTH);
}      

public static void main(String args[]) throws Exception
{
   ShapeTest1 shape = new ShapeTest1();
   shape.setTitle("Draw Shape");
   shape.setSize(700,700);
   shape.setLocationRelativeTo(null);  // center the frame
   shape.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   shape.setVisible(true);
}
}

class BoardPanel extends JPanel implements ActionListener {

private Graphics gr;
protected static int x;
protected static int y;
protected int radius = 50;

public BoardPanel()
{
  x = 300;
  y = 300;
  radius = 50;

}

/* responds to various button clicked messages */ 
public void actionPerformed(ActionEvent e)
{
 if (e.getActionCommand().compareTo("enlarge") == 0)
    radius += 10;
 else if (e.getActionCommand().compareTo("left") == 0)
    x -= 10;
 else if (e.getActionCommand().compareTo("right") == 0)
    x += 10;
 else if (e.getActionCommand().compareTo("up") == 0)
    y -= 10;
 else if (e.getActionCommand().compareTo("down") == 0)
    y += 10;
  repaint();
}

static class Keyboard extends JPanel {

public Keyboard() {
   addKeyListener(new KeyAdapter() {

       public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            System.out.println("pressed");
            switch (e.getKeyCode()) {
            case KeyEvent.VK_DOWN: 
                y += 10;break;
            case KeyEvent.VK_UP:
                y -= 10;break;
            case KeyEvent.VK_LEFT:
                x -= 10;break;
            case KeyEvent.VK_RIGHT:
                x += 10;break;
            }
            repaint();
        }
    });
}
}

/* Redraws the board and the pieces
 * Called initially and in response to repaint()
 */
protected void paintComponent(Graphics gr)
{
    super.paintComponent(gr);
    gr.fillOval(x-radius, y-radius, 2*radius, 2*radius);
}   
}

Any help would be much appreciated.

Edward
  • 15
  • 5
  • "To fire keyboard events, a component _must_ have the keyboard focus."—[*How to Write a Key Listener*](http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html) – trashgod May 31 '14 at 03:51
  • A JPanel is focusable by default, KeyListener will only respond to key strokes when the component they are registered to is focusable and has focus. Consider using the [key bindings API](http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html) instead – MadProgrammer May 31 '14 at 03:53
  • You can find your answers here: http://stackoverflow.com/questions/286727/java-keylistener-for-jframe-is-being-unresponsive – Mattias F May 31 '14 at 06:12
  • I think @MadProgrammer meant *"A JPanel is **not** focusable by default.."* – Andrew Thompson Jun 01 '14 at 09:33
  • 1
    @AndrewThompson Yes, that's what I meant...thank you iPad :P – MadProgrammer Jun 01 '14 at 09:38
  • @MadProgrammer "It's a poor tradesman who blames his tools." ;) – Andrew Thompson Jun 01 '14 at 09:41
  • @AndrewThompson Have you typed on one of those recently...while a 2 year has decided that what ever your doing is more interesting there what ever they were doing :P – MadProgrammer Jun 01 '14 at 09:43
  • @MadProgrammer No.... But I've been that 2 YO. :) – Andrew Thompson Jun 01 '14 at 09:44

1 Answers1

1

You don't appear to be calling new Keyboard() anywhere in your code, so the listener is never created or registered. From the design I'd imagine you were intending to use this panel with the buttons on it, so change the type of your panel like so:

// Create a separate panel and add all the buttons 
JPanel panel = new Keyboard();
MrLore
  • 3,759
  • 2
  • 28
  • 36
  • To simplify this further is there a way to do this without a keyboard class and just replacing the Action Event logic with the existing Key Event logic? – Edward May 31 '14 at 04:34
  • @Edward I'm not sure about that I'm afraid, but I'd think [codereview.stackexchange.com](http://codereview.stackexchange.com/) can help you with that once you get it working to your satisfaction. – MrLore May 31 '14 at 04:41