2016-11-27 7 views
0

so habe ich dieses kleine Spiel Schlange und ich Stackoverflow-Fehler erhalten, die wie so aussieht:Java Stackoverflow in GUI

Exception in thread "main" java.lang.StackOverflowError 
at java.awt.Component.setBackground(Component.java:1835) 
at javax.swing.JComponent.setBackground(JComponent.java:2733) 
at javax.swing.LookAndFeel.installColors(LookAndFeel.java:175) 
at javax.swing.LookAndFeel.installColorsAndFont(LookAndFeel.java:211) 
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(BasicPanelUI.java:66) 
at javax.swing.plaf.basic.BasicPanelUI.installUI(BasicPanelUI.java:56) 
at javax.swing.JComponent.setUI(JComponent.java:666) 
at javax.swing.JPanel.setUI(JPanel.java:153) 
at javax.swing.JPanel.updateUI(JPanel.java:126) 
at javax.swing.JPanel.<init>(JPanel.java:86) 
at javax.swing.JPanel.<init>(JPanel.java:109) 
at javax.swing.JPanel.<init>(JPanel.java:117) 
at SnakeGame.Animation.<init>(Animation.java:36) 
at SnakeGame.Snake.<init>(Snake.java:24) 
at SnakeGame.Animation.<init>(Animation.java:38) 
at SnakeGame.Snake.<init>(Snake.java:24) 

Ich weiß, es gibt einige unendliche Rekursion los ist, aber ich verstehe es nicht. Es scheint nur ein Konstruktor zu sein. so ist hier Code für Animation-Klasse:

//imports are there 
interface Drawable{ 
public void draw(Graphics g); 
} 


public class Animation extends JPanel implements ActionListener, KeyListener{ 

JFrame frame; 
List <Drawable> toDraw; 
Snake snake; 
Food food; 
Timer timer; 

public static boolean gameOver = false; 
public static int UNIT = 20; 
public static int SIZE = 500; 


public static void main(String[] args){ 
    Animation animate = new Animation(); 
    animate.setUpFrame(); 
} 

Animation(){ 

    toDraw = new ArrayList<>(); // this is line 38 from exception 
    snake = new Snake(SIZE/2,SIZE/2); 
    food = new Food(); 
    toDraw.add(snake); 
    toDraw.add(food); 
    initTimer(); 
} 

void initTimer(){ 
    timer = new Timer(200, this); 
    timer.setInitialDelay(1000); 
    timer.start(); 
} 

void setUpFrame(){ 
    frame = new JFrame("Snake"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(SIZE, SIZE); 
    frame.setFocusable(true); 
    frame.setVisible(true); 
    frame.add(this); 
} 

void gameRun() { 
     //haven't written here anything yet. 
} 

    @Override 
public void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    this.setBackground(new Color(70,130,80)); 

    for(Drawable d : toDraw){ 
     d.draw(g); 
    } 

} 

@Override 
public void actionPerformed(ActionEvent e) { 
     gameRun(); 
     repaint(); 
} 


@Override 
public void keyTyped(KeyEvent e) { 

} 

@Override 
public void keyPressed(KeyEvent e) { 
    int c = e.getKeyCode(); 
    switch(c){ 
     case 'L': 
      snake.setDirection('L'); 
      break; 
     case 'R': 
      snake.setDirection('R');   
      break; 
     case 'U': 
      snake.setDirection('U'); 
      break; 
     case 'D': 
      snake.setDirection('D'); 
      break; 
    } 
} 

@Override 
public void keyReleased(KeyEvent e) { 

} 

} 

Und hier Schlange Klasse:

public class Snake extends Animation implements Drawable { 

int x; 
int y; 
char direction = 'N'; 

Snake(int x, int y){ //line 24 from exception 
    this.x = x; 
    this.y = y; 
} 


void setDirection(char way){ 
    direction = way; 
} 
void move(char direction){ 

    if(x < 0){ 
     x = SIZE; 
    } 
    else if(x > SIZE){ 
     x = 0; 
    } 
    if(y < 0){ 
     y= SIZE; 
    }else if (y > SIZE){ 
     y = 0; 
    } 

    switch(direction){ 
     case 'L': 
      x-= UNIT; 
      break; 
     case 'R': 
      x+= UNIT;    
      break; 
     case 'U': 
      y-= UNIT;  
      break; 
     case 'D': 
      y+= UNIT; 
      break; 
    } 
} 

@Override 
public void draw(Graphics g) { 
    g.setColor(new Color(160,2,42)); 
    g.fill3DRect(x, y, UNIT, UNIT, true); 
    } 
} 

Jede Hilfe wäre sehr dankbar!

+0

Ihre Vererbung macht keinen Sinn, warum erweitert 'Snake' 'Animation' überhaupt? – Li357

+0

@AndrewLi Vielen Dank! Vererbung ist meine Schwachstelle. Ich denke, ich werde einfach eine abstrakte Klasse für jedes physische Objekt erstellen und daraus erweitern. –

Antwort

2

Sie unbeabsichtigte Rekursion haben aufgrund Ihres Programms Vererbungsstruktur:

Ihre Schlange erstreckt Animation, , die eine Schlange in seinem Konstruktor erstellt die -Animation erstreckt, die eine Schlange in seinem Konstruktor erstellt, die Animation, erweitert Das erzeugt eine Schlange in seinem Konstruktor, die Animation erweitert, die eine Schlange in seinem Erbauer erzeugt, die Animation ausdehnt, die eine Schlange in seinem Erbauer herstellt ... usw. ...

Lösung: Snake nicht verlängern Animation. Und das ist auch logisch, da Snake nicht als Swing-Komponente wie JPanel fungiert und daher nicht von JPanel erben sollte. Vielmehr ist es eine logische Entity, die von JPanel gezeichnet wird - und Sie möchten also die Komposition hier verwenden (was Sie bereits tun) und nicht Vererbung (was Sie leider auch tun).

+0

Vielen Dank! Ich weiß nicht, wie die Vererbung sehr gut funktioniert, seit ich darüber gelesen habe, als ich nichts in Java machen konnte. Ich muss mein Wissen auffrischen. –