1

I've been reading the java documentation and am trying to understand key listeners and their uses. I managed to make a simple program where 'w' and 's' toggled the background colour, however when I tried to make them move a painted ball they stopped responding. I am fairly sure it isn't a painting issue as I read through the JavaDocs common painting issues. I've set the JFrame as focuseable (or at least I think I have). If anyone could point me In the right direction it would be greatly appreciated.

Here is the main class

import javax.swing.JFrame;
import java.awt.EventQueue;

public class frame {

    public static void main(String[] args){

         EventQueue.invokeLater(new Runnable()
         {                 
            @Override
             public void run()
             {       
                 showGui();                                                   
             }
         });        
    }

    public static void showGui(){
        JFrame f = new JFrame("Testing..");
         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
          f.setFocusable(true);
            f.add(new Gui());
            f.setSize(300,300);
            f.setVisible(true);              
    }
}

and the Gui/KeyListener class

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.BorderFactory;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Gui extends JPanel {

    public Gui(){
        HandlerClass handle = new HandlerClass();
         setBorder(BorderFactory.createLineBorder(Color.black));
         addKeyListener(handle);
    }

    int x = 30;
    int y = 30;

    public void paintComponent(Graphics g){
        super.paintComponents(g);
        g.setColor(Color.BLUE);
        g.fillRect(x, y, 20, 20);   


    }

    private class HandlerClass implements KeyListener{

        public void keyTyped(KeyEvent e) {
            switch (e.getKeyChar()){
            case 'w': 
            repaint(x,y+1, 20,20);
                break;
            case 's': 
                repaint(x,y-1, 20,20);
                System.out.println("testing if this fires");
            break;
            }               
        }

        public void keyPressed(KeyEvent e) {
            //todo
        }
        public void keyReleased(KeyEvent e) {
            //todo

        }

    }

}

Any pointings in the right direction would be very helpful, thank you.

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
Apcragg
  • 133
  • 1
  • 7

3 Answers3

2

If you've searched this site at all, you'll know this solution already: don't use KeyListeners but rather Key Bindings. If you haven't searched this site, well you should have done this before asking the question.

e.g.: a previous answer of mine with example code

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 1
    SO I bit the bullet and learned how to use them and I just now got it working. Thank you for the insight on using them over KeyListeners! – Apcragg Apr 26 '13 at 03:14
2

KeyListener will only respond to key events when the component it is attached to is focusable and has focus.

JPanel by default does not meet either of these requirements (by default, it is not focusable).

For these reasons, it is not recommended that you use KeyListener, but instead use Key Bindings, which has the ability to overcome these issues

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0
repaint(x,y+1, 20,20);

You are painting y slightly higher, however you are not actually changing y. Try:

repaint(x,++y, 20,20);

The same applies (in the other direction) for your other listener.

Aurand
  • 5,487
  • 1
  • 25
  • 35
  • Thank you for pointing that out, it wasn't the issue I was looking to fix but it was an issue, much appreciated! – Apcragg Apr 26 '13 at 01:53