I am programming snake for my school and everything works totally fine, except for the keyListener. I don't really know where the problem is, because I think that I called the right way.
Here is the code of my window class:
package GUI;
import Entity.Apple;
import Entity.Schlange;
import Threads.Threads;
import Threads.KeyInput;
import javax.swing.*;
public class Window extends JFrame {
public Window() {
Spielfeld spielfeld = new Spielfeld();
Apple apple = new Apple(0, 0, spielfeld);
KeyInput keyInput = new KeyInput(); // This is the keyListener
Schlange schlange = new Schlange(spielfeld, apple, keyInput);
Threads thread = new Threads(spielfeld, apple, schlange);
this.setTitle("Snake");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setResizable(false);
this.add(spielfeld);
this.pack();
this.addKeyListener(keyInput);
this.setVisible(true);
thread.startThread();
}
}
And from the keyListener:
package Threads;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
public class KeyInput implements KeyListener {
public Queue<String> queue = new ConcurrentLinkedQueue<>();
@Override
public void keyTyped(KeyEvent e) {
String moved = new String();
System.out.println("keyTyped");
if (e.getKeyCode() == KeyEvent.VK_W) {
System.out.println("W gedrückt");
moved = "up";
} else if (e.getKeyCode() == KeyEvent.VK_A) {
System.out.println("W gedrückt");
moved = "left";
} else if (e.getKeyCode() == KeyEvent.VK_S) {
System.out.println("W gedrückt");
moved = "down";
} else if (e.getKeyCode() == KeyEvent.VK_D) {
System.out.println("W gedrückt");
moved = "right";
}
queue.add(moved);
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("keyTyped");
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("keyTyped");
}
}
The keyListener is supposed to be added to the window, and then be given to "Schlange" (Germ.: Snake), where it will be proced.
I have a lot of lines with System.out.println() to debug, but none of them gave out anything and it doesn't matter what I click.
Should I like add it in the JPanel?
Edit: I tried adding it to the JPanel "Spielfeld", which worked
Three points I can hint at:
Do NOT write the same message to sysout for different events, this will confuse you, so instead, for each method write its real name and add the parameter:
System.out.println("KeyInput.keyTyped(e=" + e + ")");
System.out.println("KeyInput.keyPressed(e=" + e + ")");
System.out.println("KeyInput.keyReleased(e=" + e + ")");
).This way you will see WHAT is triggered WHERE.
This is mainly important, because certain keys will not trigger all 3 events (pressed, released, typed).
If you do NOT add the panel spielfeld
, the evets will in fact all get triggered. As I cannot see what your Spielfeld
class is, I bet it catches ('consumes') those events.
Quick fix: instead of adding the keylistener to this
(this.addKeyListener(keyInput);
), better add them to spielfeld
: spielfeld.addKeyListener(keyInput);
, maybe that works then.
(And please, next time, provide ALL relevant code)
Actually, a bunch of small problems: You did not describe your actual problem. Do the events not get triggered at all? What output messages do you get? Maybe there's a swallowed Exception somewhere that is relevant to this problem. Include a runnable example with ALL relevant classes. Usually when dumbing down the problem, you see the solution yourself.
So, I hope this already helped. In any way, please update your question, so if future generations come here looking for the same problem, they'll have better info.