Corey
Corey

Reputation: 152

Java: help using KeyAdapter

I'm using java trying to make a basic game but am having some trouble with a KeyAdapter. I've used a very similar format before and thought I understood it, but this has me stumped.

Any help would be appreciated, here is the main code I'm working with

public class Board extends JPanel implements ActionListener{

Timer timer;
Tank tank = new Tank();

boolean boardset;

public Board(){
setBackground(Color.BLACK);

ImageIcon alien1ii = new ImageIcon(this.getClass().getResource("si_Alien1.png"));
Image alien1 = alien1ii.getImage();
ImageIcon alien2ii = new ImageIcon(this.getClass().getResource("si_Alien2.png"));
Image alien2 = alien2ii.getImage();
ImageIcon alien3ii = new ImageIcon(this.getClass().getResource("si_Alien3.png"));
Image alien3 = alien3ii.getImage();

timer = new Timer(5, this);
timer.start();

addKeyListener(new TAdapter());

JButton button = new JButton(new AbstractAction("hello2"){
    @Override
    public void actionPerformed(ActionEvent e){
        boardset = false;
    }
}); 
this.add(button);

//actual game
setFocusable(true);
setDoubleBuffered(true);
}

public void paint(Graphics g){
    super.paint(g);
    g.setColor(Color.WHITE);

    Graphics2D g2d = (Graphics2D) g;
    g2d.drawImage(tank.getTank(), tank.getx(), tank.getY(), this);

    g2d.drawLine(0, (tank.getY()+25), 400, (tank.getY()+25));

    Toolkit.getDefaultToolkit().sync();     
    g.dispose();
}

public class TAdapter extends KeyAdapter{
    public void keyPressed(KeyEvent e){
        tank.keyPressed(e);
        System.out.println("pressedddddddddddddddddd");
    }
    public void keyReleased(KeyEvent e){
        tank.keyReleased(e);
    }
}

public void setBoardset(boolean x){
    boardset = x;
}

public boolean getBoardset(){
    return boardset;
}

@Override
public void actionPerformed(ActionEvent e) {
        repaint();
        tank.move();
    }

}

Seems to me like this should be pretty straightforward, right now I'm using this print statement to see if the class is actually recognizing key strokes at all: public class TAdapter extends KeyAdapter{ public void keyPressed(KeyEvent e){ tank.keyPressed(e); System.out.println("pressedddddddddddddddddd"); }

However, there is no output. So I suspect it is not recognizing any keystrokes at all. But I can't figure out why. If anybody has any suggestions I would appreciate it. Obviously I have more code I can share if anybody thinks it would be useful in figuring out this bug.

Upvotes: 1

Views: 439

Answers (2)

nachokk
nachokk

Reputation: 14413

1)Use KeyBindings KeyListener has 2 big issues,first you listen to all keys and second you have to have focus and be focusable. Instead KeyBinding you bind for a key and you don't have to be in focus.

Simple Example:

AbstractAction escapeAction = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
         //code here example
         ((JComponent)e.getSource()).setVisible(Boolean.FALSE);
    }};
 String key = "ESCAPE";
 KeyStroke keyStroke = KeyStroke.getKeyStroke(key);
 component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, key);
 component.getActionMap().put(key, escapeAction);

You can use these JComponent constants

WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 
WHEN_FOCUSED 
WHEN_IN_FOCUSED_WINDOW 

2) Don't use concrete inheritance if it isn't necessary at all.

3) Don't implement ActionListener in top classes, see Single Responsability Principle Example Change this:

public class Board extends JPanel implements ActionListener{

to:

 public class Board{
   private JPanel panel;

    private class MyActionListener implements ActionListener{
       //code here
    }
  }

4) Don't use inheritance if it's just the same for example in your KeyAdapter , you don't add nothing to it, just use KeyAdapter (Now you are gonna to use keybinding so this is useless but to know :) ).

5) Add @Override annotation when you do overriding , also you should override paintComponent(..) instead of paint(..) in swing.

Upvotes: 2

MadProgrammer
MadProgrammer

Reputation: 347214

KeyListener suffers from focus issues. The component needs to be both focusable and have focus in order for the listener to be notified of key events.

A better solution would be to use Key Bindings which don't suffer from these constraints.

Upvotes: 1

Related Questions