Key-Listener in Java

javaman1

Mitglied
Hallo Leute,

ich programmiere zurzeit das Videospiel Snake. Ich bekomme es jedoch nicht hin, dass der KeyListener funktioniert. Hier ist die hauptklasse und im voraus schon einmal sorry für den Code Salat. Ich habe jetzt noch die Buttons zum steuern mit eingebunden, die waren jedoch nur zum Testen. ganz unten sind meine KeyEvents. Es passiert jedoch garnichts,wenn ich die Tasten drücke.
Was muss ich an meinem Code verändern, dass die KeyPressed Methode aufgerufen wird, sobald ich eine Taste drücke?


[CODE lang="java" title="Die Main Klasse"]
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class Snake extends JFrame implements KeyListener,EventListener{
static int last_direction=0;
static int height=20;
static int width=20;
static JTextArea displayArea;
static Graphics_array graph_ar = new Graphics_array(height,width);
static JFrame f = new JFrame("Snake");
static BorderLayout bl= new BorderLayout();
static boolean started_game=true;
static Graf_thread t1 = new Graf_thread();
static JPanel game_graf = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 =(Graphics2D)g;

int x = (game_graf.getSize().width);
int y = (game_graf.getSize().height);
for (int i1 = 0; i1 < height; i1++) {
for (int i2 = 0; i2 < width; i2++) {
g2.setColor(graph_ar.get_part(i1,i2).get_Color());
g2.fillRect((x/width)*i1,y-((y/height)*(i2+1)),x/width,y/height);
}
}

}
};
static JPanel north_pan = new JPanel();
static GridLayout gl_north = new GridLayout(0,4);

static JButton but_down = new JButton("down");
static JButton but_up = new JButton("up");
static JButton but_right = new JButton("right");
static JButton but_left = new JButton("left");

public static void reset(){
graph_ar = null;
graph_ar = new Graphics_array(height,width);
game_graf.repaint();
started_game= true;
}
public static void main(String[] args){
f.setSize(600,600);
f.setVisible(true);
f.add(game_graf, bl.CENTER);
but_left.addActionListener(ear_left);
but_right.addActionListener(ear_right);
but_up.addActionListener(ear_up);
but_down.addActionListener(ear_down);
north_pan.setLayout(gl_north);
north_pan.add(but_left);
north_pan.add(but_right);
north_pan.add(but_up);
north_pan.add(but_down);
f.add(north_pan,bl.NORTH);



try{
t1.start();
} catch(Exception e) {
System.out.println(e);
}
}


static ActionListener ear_left = new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=0){
graph_ar.chng_direction(2);
last_direction=2;
}
}
};
static ActionListener ear_right = new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=2){
graph_ar.chng_direction(0);
last_direction=0;
}
}
};
static ActionListener ear_up = new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=1){
graph_ar.chng_direction(3);
last_direction=3;
}
}
};
static ActionListener ear_down = new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=3){
graph_ar.chng_direction(1);
last_direction=1;
}
}
};
public void keyTyped(KeyEvent e) {

}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch( keyCode ) {
case KeyEvent.VK_UP:
if(last_direction!=1){
graph_ar.chng_direction(3);
last_direction=3;
}
break;
case KeyEvent.VK_DOWN:
graph_ar.chng_direction(1);
break;
case KeyEvent.VK_LEFT:
graph_ar.chng_direction(2);
break;
case KeyEvent.VK_RIGHT :
graph_ar.chng_direction(0);
break;
}
}

public void keyReleased(KeyEvent e) {
System.out.println("pressed");
}

}[/CODE]
Java:
 

javaman1

Mitglied
Wo registrierst Du denn den Listener?
Das hatte ich schon versucht mit:

Java:
f.addKeyListener(new KeyListener());

in das Frame zu integrieren jedoch gab es da immer eine Fehlermeldung.
Oder muss der KeyListener anders hinzugefügt werden?
Ich hatte es auch schon (So hab ich es im Internet gefunden) mit:

Java:
f.addKeyListener(this);

versucht, jedoch hat das auch immer eine Fehlermeldung gegeben.
 
K

kneitzel

Gast
Also das was Du da machst, ist alles extrem wild durcheinander:

Snake erbt von JFrame, aber dann wird das JFrame doch in einer Variable gehalten? Aber alles static?

Prinzipiell wäre das mit dem addKeyListener(this) schon korrekt - wenn es ein this gäbe. Aber von der Klasse erstellst Du ja nie eine Instanz!

Lösche als aller erstes bitte alle static aus Deinem Code - bis auf das eine bei public static void main! Und dann überlege Dir genau, was Du für Objekte haben willst und wo diese hin gehören. Main könnte eine Instanz von Snake erzeugen. Der Konstruktor erzeugt dann die Elemente, die dann Instanzvariablen (statt Klassenvariablen) sind. Und dann hast Du auch die Instanz von Snake, in der Du du bist und kannst daher dann auch das addKeyListener(this) machen.
 

javaman1

Mitglied
Ich habe das jetzt alles abgeändert, jedoch haben sich dadurch in allen anderen Klassen Fehler gebildet. Wie könnte ich denn den KeyListener in das JPanel integrieren um mir all den Aufwand zu sparen? Ich konnte die Fehler in den anderen Klassen nur beheben, indem ich einige Sachen wieder auf static stellte.
 

mihe7

Top Contributor
Nein, static ist der falsche Weg. Wenn Du uns den neuen Code zeigst und schreibst, wo es Probleme gibt, kann man da helfen.
 

javaman1

Mitglied
OK:

[CODE lang="java" title="Graf_thread"]public class Graf_thread extends Thread {
public void run() {
while (Snake.started_game) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {

}
if (Snake.started_game) {
Snake.game_graf.repaint();
}
Snake.graph_ar.step();

}
}
}[/CODE]

[CODE lang="java" title="Graphics_array"]import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

public class Graphics_array {
Part[][] gr_array; // gr_array[width][height]
int direction = 0; // 0=rechts; 1=unten; 2=links; 3=oben
Dimension head;
Dimension tail;
int height;
int width;
boolean apple_col;

public Graphics_array(int height, int width) {
this.height = height;
this.width = width;
gr_array = new Part[height][width];
for (int i = 0; i <= height - 1; i++) {
for (int x = 0; x <= width - 1; x++) {
gr_array[x] = new Part(0);
}
}

gr_array[8][10] = new Part(3);
gr_array[9][10] = new Part(3);
tail = new Dimension(7, 10);
gr_array[10][10] = new Part(2);
head = new Dimension(10, 10);
new_apple();
}

public Part get_part(int height, int width) {
return gr_array[height][width];
}

public void step() {
if (wall_collision() || self_collision()) {
Snake.reset();
} else {
if (direction == 0) {
apple_col = apple_collision();
gr_array[head.width + 1][head.height] = new Part(2);
gr_array[head.width][head.height] = new Part(3);
gr_array[head.width][head.height].set_direction(direction);
head = new Dimension(head.width + 1, head.height);
if (!apple_col) {
if (gr_array[tail.width][tail.height].direction == 0) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width + 1, tail.height);

} else if (gr_array[tail.width][tail.height].direction == 2) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width - 1, tail.height);

} else if (gr_array[tail.width][tail.height].direction == 1) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width, tail.height - 1);

} else if (gr_array[tail.width][tail.height].direction == 3) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width, tail.height + 1);

}
} else {
new_apple();
}
} else if (direction == 1) {
apple_col = apple_collision();
gr_array[head.width][head.height - 1] = new Part(2); // moving head
gr_array[head.width][head.height] = new Part(3);
gr_array[head.width][head.height].set_direction(direction);
head = new Dimension(head.width, head.height - 1); // movin dimension of head
if (!apple_col) {
if (gr_array[tail.width][tail.height].direction == 0) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width + 1, tail.height);

} else if (gr_array[tail.width][tail.height].direction == 2) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width - 1, tail.height);

} else if (gr_array[tail.width][tail.height].direction == 1) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width, tail.height - 1);

} else if (gr_array[tail.width][tail.height].direction == 3) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width, tail.height + 1);

}
} else {
new_apple();
}
} else if (direction == 2) {
apple_col = apple_collision();
gr_array[head.width - 1][head.height] = new Part(2); // moving head
gr_array[head.width][head.height] = new Part(3);
gr_array[head.width][head.height].set_direction(direction);
head = new Dimension(head.width - 1, head.height); // movin dimension of head
if (!apple_col) {
if (gr_array[tail.width][tail.height].direction == 0) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width + 1, tail.height);

} else if (gr_array[tail.width][tail.height].direction == 2) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width - 1, tail.height);

} else if (gr_array[tail.width][tail.height].direction == 1) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width, tail.height - 1);

} else if (gr_array[tail.width][tail.height].direction == 3) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width, tail.height + 1);

}
} else {
new_apple();
}
} else if (direction == 3) {
apple_col = apple_collision();
gr_array[head.width][head.height + 1] = new Part(2); // moving head
gr_array[head.width][head.height] = new Part(3);
gr_array[head.width][head.height].set_direction(direction);
head = new Dimension(head.width, head.height + 1); // movin dimension of head
if (!apple_col) {
if (gr_array[tail.width][tail.height].direction == 0) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width + 1, tail.height);

} else if (gr_array[tail.width][tail.height].direction == 2) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width - 1, tail.height);

} else if (gr_array[tail.width][tail.height].direction == 1) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width, tail.height - 1);

} else if (gr_array[tail.width][tail.height].direction == 3) {
gr_array[tail.width][tail.height] = new Part(0);
tail = new Dimension(tail.width, tail.height + 1);

}
} else {
new_apple();
}

}

}

}

public boolean apple_collision() {
if (gr_array[head.width][head.height - 1].status == 1 && direction == 1) {
return true;
} else if (gr_array[head.width][head.height + 1].status == 1 && direction == 3) {
return true;
} else if (gr_array[head.width + 1][head.height].status == 1 && direction == 0) {
return true;
} else if (gr_array[head.width - 1][head.height].status == 1 && direction == 2) {
return true;
} else {
return false;
}
}

public boolean wall_collision() {
if (head.height == height - 1 && direction == 3 || head.height == 0 && direction == 1) {
return true;
} else if (head.width == 0 && direction == 2 || head.width == width - 1 && direction == 0) {
return true;
} else {
return false;
}
}

public boolean self_collision() {
if (gr_array[head.width][head.height - 1].status == 3 && direction == 1) {
return true;
} else if (gr_array[head.width][head.height + 1].status == 3 && direction == 3) {
return true;
} else if (gr_array[head.width + 1][head.height].status == 3 && direction == 0) {
return true;
} else if (gr_array[head.width - 1][head.height].status == 3 && direction == 2) {
return true;
} else {
return false;
}
}

public void chng_direction(int i) {
this.direction = i;
}

public void new_apple() {
int x;
int y;
x = (int) (Math.random() * height - 1) + 0;
y = (int) (Math.random() * height - 1) + 0;

if (gr_array[x][y].status != 0) {
new_apple();
} else {
gr_array[x][y].set_status(1);
}
}
}[/CODE]

[CODE lang="java" title="Snake"]import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

public class Snake extends JFrame implements KeyListener, EventListener {
int last_direction = 0;
int height = 20;
int width = 20;
Graphics_array graph_ar = new Graphics_array(height, width);
JFrame f = new JFrame("Snake");
BorderLayout bl = new BorderLayout();
boolean started_game = true;
Graf_thread t1 = new Graf_thread();
JPanel game_graf=new JPanel(){
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
int x=(game_graf.getSize().width);
int y=(game_graf.getSize().height);
for(int i1=0;i1<height;i1++){
for(int i2=0;i2<width;i2++){
g2.setColor(graph_ar.get_part(i1,i2).get_Color());
g2.fillRect((x/width)*i1,y-((y/height)*(i2+1)),x/width,y/height);
}
}
}};
JPanel north_pan = new JPanel();
GridLayout gl_north = new GridLayout(0, 4);

JButton but_down = new JButton("down");
JButton but_up = new JButton("up");
JButton but_right = new JButton("right");
JButton but_left = new JButton("left");

public Snake() {
f.setSize(600, 600);
f.setVisible(true);
f.add(game_graf, bl.CENTER);
but_left.addActionListener(ear_left);
but_right.addActionListener(ear_right);
but_up.addActionListener(ear_up);
but_down.addActionListener(ear_down);
north_pan.setLayout(gl_north);
north_pan.add(but_left);
north_pan.add(but_right);
north_pan.add(but_up);
north_pan.add(but_down);
f.add(north_pan, bl.NORTH);
f.addKeyListener(this);

try {
t1.start();
} catch (Exception e) {
System.out.println(e);
}
}

public void reset(){
graph_ar = null;
graph_ar=new Graphics_array(height,width);
game_graf.repaint();
started_game=true;
}

public static void main(String[] args) {
Snake snake = new Snake();
}

ActionListener ear_left=new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=0){
graph_ar.chng_direction(2);
last_direction=2;
}
}
};
ActionListener ear_right=new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=2){
graph_ar.chng_direction(0);
last_direction=0;
}
}
};
ActionListener ear_up=new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=1){graph_ar.chng_direction(3);
last_direction=3;
}
}
};
ActionListener ear_down=new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=3){
graph_ar.chng_direction(1);
last_direction=1;
}
}
};

public void keyTyped(KeyEvent e) {

}

public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_UP:
if (last_direction != 1) {
graph_ar.chng_direction(3);
last_direction = 3;
}
break;
case KeyEvent.VK_DOWN:
graph_ar.chng_direction(1);
break;
case KeyEvent.VK_LEFT:
graph_ar.chng_direction(2);
break;
case KeyEvent.VK_RIGHT:
graph_ar.chng_direction(0);
break;
}
}

public void keyReleased(KeyEvent e) {
System.out.println("pressed");
}


}[/CODE]

[CODE lang="java" title="Part"]import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class Part{
int status;
int direction;
Color col;
public Part(int status){
this.status=status;
if(status == 0){ //background
col = new Color(11,11,11);
} else if(status == 1){ //apple
col= new Color(11,255,11);
} else if(status==2){ //head
col = new Color(255,11,11);
} else if (status==3){ //body
col = new Color(255,50,50);
}else{
System.out.println("wrong status of Part");
}
}
public Color get_Color(){
return col;
}
public void set_status(int status){
if(status>=0 && status<=3){
this.status = status;
} else{
System.out.println(status+ " is an illegal status");
}
if(status == 0){ //background
col = new Color(11,11,11);
} else if(status == 1){ //apple
col= new Color(11,255,11);
} else if(status==2){ //head
col = new Color(255,11,11);
} else if (status==3){ //body
col = new Color(255,50,50);
}
}
public int get_direction(){
return direction;
}
public void set_direction(int x){
direction = x;
}
}[/CODE]

Bei jeder Referenz (von Graf_thread und Graphics_array auf Snake) wird ein Fehler angezeigt mit der Meldung:

non_static method reset() cannot be referenced from a static context.

z.B Z.40 Graphics Array

Ich kann mir die Fehlermeldung allerdings nicht erklären, da immer von einem nicht statischen Kontext referenziert wird. (z.b public void run() in der Klasse Graf_thread)
 

mihe7

Top Contributor
Bitte in Java kein lisp-case (Graf_thread). Um bei dieser Klasse zu bleiben: Du brauchst eine Referenz auf das Snake-Objekt -> Instanzvariable in Graf_thread und einen Konstruktor, der diese initialisiert (Snake-Objekt wird übergeben).

Dann hast Du irgendwo z. B. stehen:
Java:
Snake snake = new Snake();
GrafThread th = new GrafThread(snake);
 

Jw456

Top Contributor
in der zeile 40
Snake.reset();
greifst du auf die Klasse zu nicht auf eine Instanz.

PS. unsere Post haben sich überschnitten.
 

Jw456

Top Contributor
Tipp Übergebe der Methode step() die Instanz von der du die methode reset ausfüren willst.

auch in deiner Graf_thread Klasse hast du nur die Klasse aber nicht die Instanz von Snake. Benutze einen Konstruktor und übergebe die Instaznt.
 
Zuletzt bearbeitet:

javaman1

Mitglied
Erstmal danke für die Hilfe.

Ich habe das jetzt nochmal so umgeschrieben wie vorgelagen.

GrafThread th = new GrafThread(snake);
Leider hat das nicht funktioniert, da die run() Methode keine argumente nehmen kann. Das habe ich mit einer extra Methode gelöst. das sieht jetzt etwa so aus:

[CODE lang="java" title="Graf_thread" highlight="7"]public class Graf_thread extends Thread {
Snake snake_in;
public void set_snake_in(Snake in){
snake_in = in;
}
public void run() {
while (snake_in.started_game) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {

}
if (snake_in.started_game) {
snake_in.game_graf.repaint();
}
snake_in.graph_ar.step(snake_in);

}
}
}[/CODE]

Der ganze Code wird auch fehlerlos kompiliert, allerdings wenn ich das Programm starte , kommt eine NullPointer Exception in Zeile 7 von Graf_Thread. Ich ann mir die allerdings nicht erklären, da vor dem Aufruf der run Methode die set_snake_in() Methode aufgerufen wird, um die Instanz von snake (snake_in) zu übergeben.

Könnte das daran liegen, dass der start des threads (aufruf der run() Methode) noch zur Initialisierung der Snake Instanz gehört, und daher diese null ist?
 

mihe7

Top Contributor
Leider hat das nicht funktioniert, da die run() Methode keine argumente nehmen kann.
Hier wird auch nicht die run-Methode aufgerufen, sondern der Konstruktor.

Wenn Du public void set_snake_in nach public Graf_thread änderst, dann kannst Du mit new Graf_thread(snake) arbeiten.

Ich ann mir die allerdings nicht erklären, da vor dem Aufruf der run Methode die set_snake_in() Methode aufgerufen wird, um die Instanz von snake (snake_in) zu übergeben.
Zeig mal die Stelle.
 

Jw456

Top Contributor
Java:
public class Graf_thread extends Thread {
  Snake snake_in;
  
  public  Graf_thread(Snake in){
        snake_in = in;
  }
  public void run() {
    while (snake_in.started_game) {
      try {
        Thread.sleep(300);
      } catch (InterruptedException e) {

      }
      if (snake_in.started_game) {
        snake_in.game_graf.repaint();
      }
      snake_in.graph_ar.step(snake_in);

    }
  }
}

was du hast ist ein setter und kein Konstruktor
Konstruktor ist der gleiche Bezeichner wie die Klasse.
 

Jw456

Top Contributor
In der Klasse Snake im Konstruktor Zeile 54 startest du den Thread.
t1.start();
wenn du hier deinen setter aufrufst.


ob du im Konstruktor vom Snake schon auf die Instanz von Snake zugreifen kannst bin ich mir nicht sicher.
Wo genau rufst du deinen setter auf?

PS das starten des Spiels würde ich nicht im Konstruktor machen.
ich würde eine Startmethode erstellen und die in der main mit der Instanz von Snake aufrufen.


Java:
void startSpiel(Snake in)){
   try {
       // das erstellen des Threds würde ich auch hier machen nicht im Klassenrumpf
       t1 = new Graf_thread();
       t1.set_snake_in(in);
       t1.start();
    } catch (Exception e) {
      System.out.println(e);
    }
  }
  public static void main(String[] args) {
    Snake snake = new Snake();
    snake.startSpiel(snake);
   
  }
 
Zuletzt bearbeitet:

javaman1

Mitglied
Hier wird auch nicht die run-Methode aufgerufen, sondern der Konstruktor.
Ok das habe ich jetzt korrigiert, das funktioniert.
Zeig mal die Stelle.
Das hat sich ja jetzt mit dem Konstrukter sowieso geklärt. Die Null Pointer Exception bleibt aber komischerweise.
Wo genau rufst du deinen setter auf?
Den hab ich nun im Konstrukter vom Thread integriert.

Jetzt klappt auch das Starten wieder. Nur der KeyListener reagiert noch nicht, obwohl ich ihn integriert habe. Auch meine Methoden sind da.
In Z.51 wird der KeyListener integriert in Frame. Ich habe auch schon versucht, es auf die Panel zu setzten, was auch nicht funktioniert hat.
Z. 106 ff. sind die Methoden für den KeyListener.
Wieso reagiert der KeyListener nicht?

Mein Code jetzt:

[CODE lang="java" highlight="51, 106, 110, 132"]import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

public class Snake extends JFrame implements KeyListener, EventListener {
int last_direction = 0;
int height = 20;
int width = 20;
Graphics_array graph_ar = new Graphics_array(height, width);
JFrame f = new JFrame("Snake");
BorderLayout bl = new BorderLayout();
boolean started_game = true;
Graf_thread t1;
JPanel game_graf=new JPanel(){
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
int x=(game_graf.getSize().width);
int y=(game_graf.getSize().height);
for(int i1=0;i1<height;i1++){
for(int i2=0;i2<width;i2++){
g2.setColor(graph_ar.get_part(i1,i2).get_Color());
g2.fillRect((x/width)*i1,y-((y/height)*(i2+1)),x/width,y/height);
}
}
}};
JPanel north_pan = new JPanel();
GridLayout gl_north = new GridLayout(0, 4);
static Snake snake_in;
JButton but_down = new JButton("down");
JButton but_up = new JButton("up");
JButton but_right = new JButton("right");
JButton but_left = new JButton("left");

public Snake() {
f.setSize(600, 600);
f.setVisible(true);
f.add(game_graf, bl.CENTER);
but_left.addActionListener(ear_left);
but_right.addActionListener(ear_right);
but_up.addActionListener(ear_up);
but_down.addActionListener(ear_down);
north_pan.setLayout(gl_north);
north_pan.add(but_left);
north_pan.add(but_right);
north_pan.add(but_up);
north_pan.add(but_down);
f.add(north_pan, bl.NORTH);
f.addKeyListener(this);
}

public void reset(){
graph_ar = null;
graph_ar=new Graphics_array(height,width);
game_graf.repaint();
started_game=true;
}

public static void main(String[] args) {
snake_in = new Snake();
snake_in.startSpiel();
}
public void startSpiel(){
try {
t1 = new Graf_thread(snake_in);
t1.start();
} catch (Exception e) {
System.out.println(e);
}
}

ActionListener ear_left=new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=0){
graph_ar.chng_direction(2);
last_direction=2;
}
}
};
ActionListener ear_right=new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=2){
graph_ar.chng_direction(0);
last_direction=0;
}
}
};
ActionListener ear_up=new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=1){graph_ar.chng_direction(3);
last_direction=3;
}
}
};
ActionListener ear_down=new ActionListener(){
public void actionPerformed(ActionEvent e){
if(last_direction!=3){
graph_ar.chng_direction(1);
last_direction=1;
}
}
};

public void keyTyped(KeyEvent e) {

}

public void keyPressed(KeyEvent e) {
System.out.println("Es funktioniert!");
int keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_UP:
if (last_direction != 1) {
graph_ar.chng_direction(3);
last_direction = 3;
}
break;
case KeyEvent.VK_DOWN:
graph_ar.chng_direction(1);
break;
case KeyEvent.VK_LEFT:
graph_ar.chng_direction(2);
break;
case KeyEvent.VK_RIGHT:
graph_ar.chng_direction(0);
break;
}
}

public void keyReleased(KeyEvent e) {
System.out.println("pressed");
}


}[/CODE]


Vielen Danke für eure Hilfe!🙏
 

mihe7

Top Contributor
Wenn ich es richtig sehe, ist game_graf die Spielfläche? Dann solltest Du
Java:
game_graf.setFocusable(true);
game_graf.addKeyListener(this);
benötigen. Evtl. muss game_graf auch noch den Fokus anfordern, müsste man sehen.
 

Jw456

Top Contributor
Ich sagte doch das du im Konstruktor noch nicht auf die Instanz der selben Klasse zurückgreifen und somit weitergeben kannst.

Das im Konstruktor wird nicht gehn.
f.addKeyListener(this)
Denn this zeigt noch nicht auf die eigene Instanz.
Mache das in der Start Methode.
 
K

kneitzel

Gast
Ich sagte doch das du im Konstruktor noch nicht auf die Instanz der selben Klasse zurückgreifen und somit weitergeben kannst.

Das im Konstruktor wird nicht gehn.
f.addKeyListener(this)
Denn this zeigt noch nicht auf die eigene Instanz.
Mache das in der Start Methode.
Natürlich geht das. Im Konstruktor existiert die Instanz schon und this kann verwendet werden. Das hatten wir doch schon einmal in einem anderen Thread.
 
K

kneitzel

Gast
Genau und du warst dir da auch nicht sicher jetzt wohl doch.
Also ich werde das jetzt nicht raussuchen und ich weiss nicht, womit ich evtl. diesen Eindruck hinterlassen haben könnte ... Aber nein, da war ich auch letztes Mal absolut sicher. Das kann ja auch gar nicht anders funktionieren!

Vielleicht habe ich erwähnt, dass man aufpassen muss, da ggf. Teile noch nicht initialisiert sind. Aber das ändert nichts an der Funktionalität von der this Referenz.
 

Jw456

Top Contributor
Die Listener sind die die Methoden die du mit erstellen musst weil du das Interfase KeyListener implementiert hast.
Was du hast sind die default Methoden.
Die auch auf das default JFrame wirken denn du erbst ja von JFrame.

Wieso du überhaut ein neues JFrame erstellt obwohl du vom JFrame erbst erschliesst sich mir nicht.

f.addKeyListener(this)
Ob du hiermit die Lisetner auf das eigen erstellte JFrame setzt?
Glaube nicht, ich würde das geerbte JFrame benutzen und auch die default listener vom Interface.

Für mich müsstest du eigene listener (Klasse) erstellen und die statt this übergeben.
Oder gleich an Ort und Stelle als anonyme Klasse.




also lasse das JFrame f = new JFrame("Snake");
benuze das geerbte. und addKeyListener bauchst du duch das implement auch nicht .

Java:
f.addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {
              
            }

            @Override
            public void keyPressed(KeyEvent e) {

            }

            @Override
            public void keyReleased(KeyEvent e) {

            }
        });

// das Interfase brauchst du hier nicht zu importiren in der Klasse
// auch die default Listner kannst du löschen.
 
Zuletzt bearbeitet:

Jw456

Top Contributor
Also ich werde das jetzt nicht raussuchen und ich weiss nicht, womit ich evtl. diesen Eindruck hinterlassen haben könnte ... Aber nein, da war ich auch letztes Mal absolut sicher. Das kann ja auch gar nicht anders funktionieren!

Vielleicht habe ich erwähnt, dass man aufpassen muss, da ggf. Teile noch nicht initialisiert sind. Aber das ändert nichts an der Funktionalität von der this Referenz.
gut mit dem this hat es auch nichts zu tun
 
Zuletzt bearbeitet:

Jw456

Top Contributor
Eines noch ob der Compiler deine Listener ohne die Annotation @Override richt erkennt bin ich mir nicht sicher.
Du Überschreibst etwas da gehört das auch dazu wenn du dir die Methoden mit der IDE erstellen lässt werden die auch erstellt.

In Kotlin musst du sie benutzen würde einen Fehler geben.
 

Jw456

Top Contributor
Ich sagte doch das du im Konstruktor noch nicht auf die Instanz der selben Klasse zurückgreifen und somit weitergeben kannst.

Das im Konstruktor wird nicht gehn.
f.addKeyListener(this)
Denn this zeigt noch nicht auf die eigene Instanz.
Mache das in der Start Methode.
das war eine falsche antwort von mir sorry.
"this" gibst es nur die Instanz Variable ist hier moch nicht gesetzt. Deshalb auch das mit der StartMethode in der Main.
 

Jw456

Top Contributor
Die vom importierten interface.
Er erbt von JFrame nutzt er nicht macht ein neues. Und auf das neue will er die listener haben.
This zeigt auf das geerbte Frame was er nicht benutzt und auch nicht sichtbar ist.
 
Zuletzt bearbeitet:
K

kneitzel

Gast
also lasse das JFrame f = new JFrame("Snake");
benuze das geerbte. und addKeyListener bauchst du duch das implement auch nicht .
Da würde ich eher empfehlen, einfach das "extends JFrame" zu löschen. Composition over Inheritance - das ist also so wie er es macht schon richtig. Nur eben das Erben von JFrame ist unnötig und das nutzt er auch nicht was ich so gesehen habe, d.h. das extends JFrame zu löschen dürfte zu keinen weiteren Problemen führen.

Die vom importierten interface.
Das geerbt JFrame nutzt er nicht macht ein neues. Und auf das neue will er die listener haben.
Snake implementiert den KeyListener. Damit ist eine Snake Instanz auch eine KeyListener Instanz. Und die kann er - in Instanzmethoden und im Konstruktor - beliebigen Elementen zuweisen.

Und ob nun Snake auch ein JFrame ist oder nicht, spielt keine Rolle. Die Snake Instanz kann er beliebigen Elementen als KeyListener zuweisen.
 
K

kneitzel

Gast
Nur einmal auf die Schnelle zur Demonstration ein minimales Beispiel:
Java:
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyListenerTest implements KeyListener {
    public static void main(String[] args) {
        new KeyListenerTest();
    }

    public KeyListenerTest() {
        JFrame frame = new JFrame("Test");
        frame.addKeyListener(this);
        frame.setSize(800, 600);
        frame.setVisible(true);
    }

    @Override
    public void keyTyped(KeyEvent e) {
        System.out.println("Key Typed: " + e.getKeyChar());
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("Key Pressed: " + e.getKeyChar());
    }

    @Override
    public void keyReleased(KeyEvent e) {
        System.out.println("Key Released: " + e.getKeyChar());
    }
}

Und natürlich funktioniert es, den KeyListener so in dem Code zu setzen.
Und man kann auch ein extends JFrame hinzufügen - das verändert auch nichts.
 

Jw456

Top Contributor
Ja der Haupt Grund ist das er von JFrame erbt das Fenster nicht benutzt auch nicht sichtbar ist. Somit die Tasten Klicks ins leere gehen.
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Ja der Haupt Grund ist das er von JFrame erbt das Fenster nicht benutzt auch nicht sichtbar ist. Somit die Tasten Klicks ins leere gehen.
Nein, denn er fügt den KeyListener ja nicht der Snake Instanz zu sondern dem erstellten und sichtbaren JFrame.

Das Problem ist eher - wie es @mihe7 schon angedeutet hat. Die Events kommen nicht bis zum Frame, da diese bei anderen Elementen landen.

Ich habe ein Beispielcode gebracht - den kannst Du ja mal erweitern: pack einfach ein Button mit rein. Der Button bekommt dann den Fokus und der verarbeitet dann die Key Events.
Java:
    public KeyListenerTest() {
        JFrame frame = new JFrame("Test");
        frame.addKeyListener(this);
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton button = new JButton("down");
        frame.add(button);

        frame.setVisible(true);
    }

Ich finde es super, dass Du helfen willst. Aber hier ist es extrem kontraproduktiv, denn Du bringst Dinge, die so nicht stimmig sind. Und dann spammen wir den Thread voll mit Berichtigungen und Diskussionen dazu.
 
K

kneitzel

Gast
Wenn ich es richtig sehe, ist game_graf die Spielfläche? Dann solltest Du
Java:
game_graf.setFocusable(true);
game_graf.addKeyListener(this);
benötigen. Evtl. muss game_graf auch noch den Fokus anfordern, müsste man sehen.
Auf Grund der ganzen Diskussion fürchte ich, dass diese Antwort von @mihe7 unter gegangen ist.

Aber das dürfte die Lösung sein!

@javaman1 Sollte es damit nicht gehen, dann zeige uns bitte noch einmal den genauen Code und ggf. die genauen Fehlermeldungen, die Du bekommst!

Und zur Demonstration (und um weitere Diskussionen zu unterbinden) auch einmal die Lösung in einem kleinen Beispiel gezeigt (Das hatte ich ja jetzt parat durch die Diskussion mit @Jw456:
Java:
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyListenerTest implements KeyListener {
    public static void main(String[] args) {
        new KeyListenerTest();
    }

    public KeyListenerTest() {
        JFrame frame = new JFrame("Test");
//        frame.addKeyListener(this);
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.setFocusable(true);
        panel.addKeyListener(this);
        JButton button = new JButton("down");
        panel.add(button);
        frame.add(panel);

        frame.setVisible(true);
    }

    @Override
    public void keyTyped(KeyEvent e) {
        System.out.println("Key Typed: " + e.getKeyChar());
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("Key Pressed: " + e.getKeyChar());
    }

    @Override
    public void keyReleased(KeyEvent e) {
        System.out.println("Key Released: " + e.getKeyChar());
    }
}
 

javaman1

Mitglied
JAAA. Es funktioniert jetzt alles. Danke an alle für die Hilfe! Ich habe jetzt das wie vorgeschlagen mit Button geschafft.

Danke Danke Danke

Hier nochmal zum Schluss mein Code:
Java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

public class Snake implements KeyListener{
    int last_direction = 0;
    int height = 20;
    int width = 20;
    int point = 0;
    Graphics_array graph_ar = new Graphics_array(height, width);
    JFrame f = new JFrame("Snake");
    BorderLayout bl = new BorderLayout();
    boolean started_game = true;
    Graf_thread t1;
    JPanel game_graf=new JPanel(){
      public void paintComponent(Graphics g){
         super.paintComponent(g);
         Graphics2D g2=(Graphics2D)g;
         int x=(game_graf.getSize().width);
         int y=(game_graf.getSize().height);
         for(int i1=0;i1<height;i1++){
             for(int i2=0;i2<width;i2++){
                 g2.setColor(graph_ar.get_part(i1,i2).get_Color());
                 g2.fillRect((x/width)*i1,y-((y/height)*(i2+1)),x/width,y/height);
             }
         }
    } };
    JButton but_key = new JButton();
    static Snake snake_in;

    public Snake() {
      f.addKeyListener(this);
      f.setSize(600, 600);
      f.setVisible(true);
      f.add(game_graf, bl.CENTER);
      but_key.setFocusable(true);
      but_key.addKeyListener(this);
      but_key.requestFocus();
      
    }

    public  void reset(){ 
      graph_ar = null;
      graph_ar=new Graphics_array(height,width);
      game_graf.repaint();
      started_game=true;
    }

    public static void main(String[] args) {
      snake_in = new Snake();
      snake_in.startSpiel();
    }
    public void startSpiel(){
      try {
        t1 = new Graf_thread(snake_in);
        t1.start();
      } catch (Exception e) {
        System.out.println(e);
      }
    }

    @Override
    public void keyTyped(KeyEvent e) {
      
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        switch (keyCode) {
            case 38:
              if (last_direction != 1) {
                graph_ar.chng_direction(3);
                last_direction = 3;
              }
              break;
            case 40:
              if (last_direction != 3) {
                  graph_ar.chng_direction(1);
                  last_direction = 1;
              }
              break;
            case 37:
              if (last_direction != 0) {
                  graph_ar.chng_direction(2);
                  last_direction = 2;
              }
              break;
            case 39:
              if (last_direction != 2) {
                  graph_ar.chng_direction(0);
                  last_direction = 0;
              }
              break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Java -8 Action Listener für mehrere Buttons AWT, Swing, JavaFX & SWT 9
padde479 MenuItem MouseEvent/-Listener AWT, Swing, JavaFX & SWT 5
W Gibt es einen "automatischen Listener" in Swing oder JTable oder der ATM-Klasse? AWT, Swing, JavaFX & SWT 14
G listener repaint() - verschiedene Darstellung AWT, Swing, JavaFX & SWT 24
P JTable Listener für die Änderung einzelner Zellen oder Rows AWT, Swing, JavaFX & SWT 2
K Warum genau hat man einen Listener, dann ein Event und was ist ein Adapter AWT, Swing, JavaFX & SWT 2
S JavaFX - mit Listener Veränderungen in einer TableView abhören AWT, Swing, JavaFX & SWT 3
N JavaFX 1 Listener für mehrere ChoiceBoxen AWT, Swing, JavaFX & SWT 3
B Probleme Action Listener Taschenrechner AWT, Swing, JavaFX & SWT 27
M List Listener AWT, Swing, JavaFX & SWT 37
I AWT Listener während man in anderem Fenster ist AWT, Swing, JavaFX & SWT 4
U Funktionsweise Listener AWT, Swing, JavaFX & SWT 1
L TextField Listener AWT, Swing, JavaFX & SWT 13
K Nullpointer Combobox Listener AWT, Swing, JavaFX & SWT 2
L JavaFX Image im ImageView auf Scroll Listener reagieren AWT, Swing, JavaFX & SWT 5
Salo JTabel Selection listener Bsp. AWT, Swing, JavaFX & SWT 5
J JTable Selection Listener funktioniert nicht AWT, Swing, JavaFX & SWT 4
J Action Listener Rückgabewert AWT, Swing, JavaFX & SWT 14
MaxG. Swing JMenu einen Listener Hinzufügen AWT, Swing, JavaFX & SWT 25
L JavaFX Verbindung zwischen Beschreibung und Listener (Codebehind Klasse) AWT, Swing, JavaFX & SWT 4
T Swing Methode in Listener aufrufen AWT, Swing, JavaFX & SWT 3
S Swing Tabellen - Listener & richtige Row AWT, Swing, JavaFX & SWT 3
S Erste Schritte mit GUI - Fileverarbeitung, Listener,... AWT, Swing, JavaFX & SWT 10
M JButton - Listener AWT, Swing, JavaFX & SWT 1
R Swing Mehrere JTextFields mit einem Document Listener AWT, Swing, JavaFX & SWT 2
K JavaFX Focus Listener für gesamte Scene AWT, Swing, JavaFX & SWT 1
M Key Listener reagiert nicht AWT, Swing, JavaFX & SWT 4
F In Action Listener TextFields einlesen und prüfen. Abbruch bei falschen Eingaben. Wie mache ich das? AWT, Swing, JavaFX & SWT 2
M Listener funktioniert nicht AWT, Swing, JavaFX & SWT 7
S Swing JComboBox mit Listener aktualisieren AWT, Swing, JavaFX & SWT 13
elischa JFrame über mehrere JPanel und Listener AWT, Swing, JavaFX & SWT 17
llabusch Event Handling Listener spielt verrückt AWT, Swing, JavaFX & SWT 8
kaoZ Swing Architektonisches Problem / Listener / MVC AWT, Swing, JavaFX & SWT 14
H org.eclipse.swt.widgets.Scale MouseRelease listener AWT, Swing, JavaFX & SWT 1
MaDDin-94 Swing Listener reagiert nicht immer AWT, Swing, JavaFX & SWT 2
A JLabel im Listener färben AWT, Swing, JavaFX & SWT 11
M Key-,... Listener funktioniert nicht immer AWT, Swing, JavaFX & SWT 2
P Event Handling Listener beim öffnen von einem JPopupMenu AWT, Swing, JavaFX & SWT 3
A Listener für JGTextField AWT, Swing, JavaFX & SWT 2
J Programmierstil: Kommunikation Listener und GUI AWT, Swing, JavaFX & SWT 3
B JTable Renderer / Listener AWT, Swing, JavaFX & SWT 7
M Swing JList Listener AWT, Swing, JavaFX & SWT 20
K Action Listener implementieren über Objekt AWT, Swing, JavaFX & SWT 14
E Listener AWT, Swing, JavaFX & SWT 3
M SWING Listener ohne Wirkung AWT, Swing, JavaFX & SWT 2
P Listener Auswahl Tabelle AWT, Swing, JavaFX & SWT 6
P JPanel- Listener durch JTextArea aktivieren AWT, Swing, JavaFX & SWT 8
J Swing dragging listener AWT, Swing, JavaFX & SWT 5
H Problem mit dem Action listener.... AWT, Swing, JavaFX & SWT 2
J Frame mit Button erstellen - Warum ist es nötig, Frame über Unterklasse zu erstellen? (Reg Listener) AWT, Swing, JavaFX & SWT 2
M Fenster schließen - Listener AWT, Swing, JavaFX & SWT 5
G SWT TreeViewer - drop listener austauschen AWT, Swing, JavaFX & SWT 2
S Action Listener in innerer Klasse ausführen. AWT, Swing, JavaFX & SWT 8
J Sinn eines Selection Listener AWT, Swing, JavaFX & SWT 5
M JList mit DefaultListModel und listener AWT, Swing, JavaFX & SWT 4
M comboBox Listener? AWT, Swing, JavaFX & SWT 2
T Listener in anderen Panel deaktivieren AWT, Swing, JavaFX & SWT 3
A Swing Suche Listener für beliebige Änderung an GUI Items/Controls AWT, Swing, JavaFX & SWT 8
T SWT: Listener auf einem Button reagiert nicht AWT, Swing, JavaFX & SWT 2
L Swing JTextField Content-Listener AWT, Swing, JavaFX & SWT 4
P AWT Wie kann mein listener den Inhalt eines anderen Textfelds ändern? AWT, Swing, JavaFX & SWT 10
M Ansätze zur Kombination mehrerer Listener für Interaktion AWT, Swing, JavaFX & SWT 19
C JLabel Listener auf Textänderung? AWT, Swing, JavaFX & SWT 5
M Mouse Wheel Listener reagiert mehrmals AWT, Swing, JavaFX & SWT 5
F SWT Button listener richtig erstellen AWT, Swing, JavaFX & SWT 2
El_Lobo Swing Problem bei Methodenaufruf in innerer Klasse bei Listener AWT, Swing, JavaFX & SWT 3
S Wem füge ich welchen Listener hinzu? AWT, Swing, JavaFX & SWT 4
R Durch Listener lässt sich Programm nicht mehr ausführen AWT, Swing, JavaFX & SWT 4
T Callback vs. Event listener AWT, Swing, JavaFX & SWT 7
S Swing JTree und seine Listener... AWT, Swing, JavaFX & SWT 4
E JComboBox Listener AWT, Swing, JavaFX & SWT 2
AyKay SWT (alle) Listener bzw. ModifyEventListener entfernen AWT, Swing, JavaFX & SWT 2
S jTextField Listener AWT, Swing, JavaFX & SWT 7
E Listener, werte in andere Klasse übernehmen AWT, Swing, JavaFX & SWT 11
L Action listener in bestimmter spalte AWT, Swing, JavaFX & SWT 2
J AWT Action Listener etc. AWT, Swing, JavaFX & SWT 7
xehpuk Swing Listener für JPopupMenu AWT, Swing, JavaFX & SWT 3
F JCalendar mouseclick listener AWT, Swing, JavaFX & SWT 2
W AWT Listener bei TrayIcon AWT, Swing, JavaFX & SWT 2
K Swing Listener bei JPopupMenu AWT, Swing, JavaFX & SWT 9
E Swing JTextField Listener nach Update?! AWT, Swing, JavaFX & SWT 2
T TransformGroup Listener AWT, Swing, JavaFX & SWT 8
O Swing JTable Listener AWT, Swing, JavaFX & SWT 2
O Collection Listener AWT, Swing, JavaFX & SWT 6
L AWT Paint(g) im Listener aufrufen AWT, Swing, JavaFX & SWT 2
G JTree - Observer oder Listener? AWT, Swing, JavaFX & SWT 6
Avalarion SWT Listener auf Label oder Text Teile AWT, Swing, JavaFX & SWT 10
C Ermitteln ob JComponent einen Listener besitzt AWT, Swing, JavaFX & SWT 2
L JTextfield Listener AWT, Swing, JavaFX & SWT 3
C Listener Probleme AWT, Swing, JavaFX & SWT 6
N Listener für Variable AWT, Swing, JavaFX & SWT 4
C Swing Listener für TabPanel AWT, Swing, JavaFX & SWT 8
B Line aus Listener? AWT, Swing, JavaFX & SWT 11
G Model,Listener und background jobs AWT, Swing, JavaFX & SWT 4
1 JList - clearSelection nicht berücksichtigen im Listener AWT, Swing, JavaFX & SWT 7
I Swing Listener auf JPanel AWT, Swing, JavaFX & SWT 9
Dit_ MutableComboBoxModel | Listener fehlt ? AWT, Swing, JavaFX & SWT 6
T Swing JSlider und Adjustment-Listener wollen nicht so recht AWT, Swing, JavaFX & SWT 2
N Swing Textfield listener AWT, Swing, JavaFX & SWT 2
S Combo Box action listener AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben