Apcragg
Apcragg

Reputation: 133

KeyListeners not responding when added to JFrame

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.

Upvotes: 1

Views: 171

Answers (3)

Aurand
Aurand

Reputation: 5537

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.

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347184

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

Upvotes: 2

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

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

Upvotes: 2

Related Questions