so I have this little snake game and I get StackOverflow error which looks like so:
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)
I know there's some infinite recursion going on but I don't get it. It seems like just a constructor. so Here's code for Animation class:
//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) {
}
}
And here's snake class:
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);
}
}
Any help would be greatly appreciated!
You've got unintended recursion due to your program's inheritance structure:
Your Snake extends Animation which creates a Snake in its constructor which extends Animation which creates a Snake in its constructor which extends Animation which creates a Snake in its constructor which extends Animation which creates a Snake in its constructor which extends Animation which creates a Snake in its constructor ... etc...
Solution: don't have Snake extend Animation. And this also makes logical sense, since your Snake is not acting as a Swing component such as a JPanel, and so shouldn't inherit from JPanel. Rather it's a logical entity that is drawn by the JPanel -- and so you want to use composition here (which you're already doing) and not inheritance (which you're unfortunately doing as well).