线程中的异常" AWT-EventQueue-0" java.lang.StackOverflowError的

时间:2014-05-23 14:40:53

标签: java swing recursion stack-overflow

我正在制作一个扫雷克隆,目的是教我自己摇摆和更一般地理解java。我几乎完全完成了它,除了我不能让级联方法正常工作。

我理解我的错误在于我的递归,但我似乎无法理解如何阻止它。我能得到的最好的方法是在1次迭代后停止该方法,但它确实需要在整个板上级联。

这是堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at bombSweeper.BombSweeper.getField(BombSweeper.java:1168)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)
at bombSweeper.Bomb.check(Bomb.java:316)

行号总是指代下面代码中的递归调用,它会根据按钮在我的雷区中的位置而改变。

package bombSweeper;

import java.awt.Insets;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;

public class Bomb extends JButton implements MouseListener {

int imageNumber, index, defusedCheck;

boolean isBomb, isChecked, isFlagged;

private ImageIcon bomb = new ImageIcon("./imgs/bomb.png"),
                  flag = new ImageIcon("./imgs/flag.png"),
                  one = new ImageIcon("./imgs/1.png"),
                  two = new ImageIcon("./imgs/2.png"),
                  three = new ImageIcon("./imgs/3.png"),
                  four = new ImageIcon("./imgs/4.png"),
                  five = new ImageIcon("./imgs/5.png"),
                  six = new ImageIcon("./imgs/6.png"),
                  seven = new ImageIcon("./imgs/7.png"),
                  eight = new ImageIcon("./imgs/8.png");

public Bomb(int index) {

    isBomb = false;
    isChecked = false;
    isFlagged = false;

    imageNumber = 0;        
    this.index = index;

    addMouseListener(this);
    setMargin(new Insets(0, 0, 0, 0));
    setFocusPainted(false);

}

public boolean isBomb() {

    return isBomb;

}

public void setBomb() {

    isBomb = true;
    imageNumber = 9;

}

public void setCount(int adjBombs) {

    imageNumber = adjBombs;

}

public void flag() {

    if(!isFlagged) {

        this.setIcon(flag);

    } else {

        this.setIcon(null);
    }

    isFlagged ^= true;

}

public void check() {

    if(isFlagged || isChecked) {

        return;

    }

    if(isBomb) {

        detonate();
        return;

    }

    if(imageNumber != 0) {

        if(imageNumber == 1) {

            this.setIcon(one);

        } else if(imageNumber == 2) {

            this.setIcon(two);

        } else if(imageNumber == 3) {

            this.setIcon(three);

        } else if(imageNumber == 4) {

            this.setIcon(four);

        } else if(imageNumber == 5) {

            this.setIcon(five);

        } else if(imageNumber == 6) {

            this.setIcon(six);

        } else if(imageNumber == 7) {

            this.setIcon(seven);

        } else if(imageNumber == 8) {

            this.setIcon(eight);

        }

        isChecked = true;

    }

    if(imageNumber == 0) {

        this.setEnabled(false);

        if(index == 0) {

            check(BombSweeper.getField()[index + 1]);
            check(BombSweeper.getField()[index + 10]);
            check(BombSweeper.getField()[index + 11]);

        } else if(index > 0 && index < 9) {

            check(BombSweeper.getField()[index - 1]);
            check(BombSweeper.getField()[index + 1]);
            check(BombSweeper.getField()[index + 9]);
            check(BombSweeper.getField()[index + 10]);
            check(BombSweeper.getField()[index + 11]);


        } else if(index == 9) {

            check(BombSweeper.getField()[index - 1]);
            check(BombSweeper.getField()[index + 9]);
            check(BombSweeper.getField()[index + 10]);              

        } else if(index % 10 == 0 && index != 140) {

            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 9]);
            check(BombSweeper.getField()[index + 1]);
            check(BombSweeper.getField()[index + 10]);
            check(BombSweeper.getField()[index + 11]);  

        } else if((index - 9) % 10 == 0 && index != 149) {

            check(BombSweeper.getField()[index - 11]);
            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 1]);
            check(BombSweeper.getField()[index + 9]);
            check(BombSweeper.getField()[index + 10]);

        } else if(index == 140) {

            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 9]);
            check(BombSweeper.getField()[index + 1]);

        } else if (index > 140 && index < 149) { 

            check(BombSweeper.getField()[index - 11]);
            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 9]);
            check(BombSweeper.getField()[index - 1]);
            check(BombSweeper.getField()[index + 1]);

        } else if(index == 149) {

            check(BombSweeper.getField()[index - 11]);
            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 1]);

        } else {

            check(BombSweeper.getField()[index - 11]);
            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 9]);
            check(BombSweeper.getField()[index - 1]);
            check(BombSweeper.getField()[index + 1]);
            check(BombSweeper.getField()[index + 9]);
            check(BombSweeper.getField()[index + 10]);
            check(BombSweeper.getField()[index + 11]);              

        }

    }

}

public void check(Bomb bobomb) {

    if(isFlagged || isChecked) {

        return;

    }

    if(imageNumber != 0) {

        if(imageNumber == 1) {

            this.setIcon(one);

        } else if(imageNumber == 2) {

            this.setIcon(two);

        } else if(imageNumber == 3) {

            this.setIcon(three);

        } else if(imageNumber == 4) {

            this.setIcon(four);

        } else if(imageNumber == 5) {

            this.setIcon(five);

        } else if(imageNumber == 6) {

            this.setIcon(six);

        } else if(imageNumber == 7) {

            this.setIcon(seven);

        } else if(imageNumber == 8) {

            this.setIcon(eight);

        }

        isChecked = true;

    } else if(imageNumber == 0) {

        if(index == 0) {

            check(BombSweeper.getField()[index + 1]);
            check(BombSweeper.getField()[index + 10]);
            check(BombSweeper.getField()[index + 11]);

        } else if(index > 0 && index < 9) {

            check(BombSweeper.getField()[index - 1]);
            check(BombSweeper.getField()[index + 1]);
            check(BombSweeper.getField()[index + 9]);
            check(BombSweeper.getField()[index + 10]);
            check(BombSweeper.getField()[index + 11]);


        } else if(index == 9) {

            check(BombSweeper.getField()[index - 1]);
            check(BombSweeper.getField()[index + 9]);
            check(BombSweeper.getField()[index + 10]);              

        } else if(index % 10 == 0 && index != 140) {

            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 9]);
            check(BombSweeper.getField()[index + 1]);
            check(BombSweeper.getField()[index + 10]);
            check(BombSweeper.getField()[index + 11]);  

        } else if((index - 9) % 10 == 0 && index != 149) {

            check(BombSweeper.getField()[index - 11]);
            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 1]);
            check(BombSweeper.getField()[index + 9]);
            check(BombSweeper.getField()[index + 10]);

        } else if(index == 140) {

            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 9]);
            check(BombSweeper.getField()[index + 1]);

        } else if (index > 140 && index < 149) { 

            check(BombSweeper.getField()[index - 11]);
            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 9]);
            check(BombSweeper.getField()[index - 1]);
            check(BombSweeper.getField()[index + 1]);

        } else if(index == 149) {

            check(BombSweeper.getField()[index - 11]);
            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 1]);

        } else {

            check(BombSweeper.getField()[index - 11]);
            check(BombSweeper.getField()[index - 10]);
            check(BombSweeper.getField()[index - 9]);
            check(BombSweeper.getField()[index - 1]);
            check(BombSweeper.getField()[index + 1]);
            check(BombSweeper.getField()[index + 9]);
            check(BombSweeper.getField()[index + 10]);
            check(BombSweeper.getField()[index + 11]);              

        }

    }       

}

public void detonate() {

    for(int i = 0; i < 150; i++) {

        BombSweeper.getField()[i].isChecked = true;

        if(BombSweeper.getField()[i].isBomb) {

            BombSweeper.getField()[i].setIcon(bomb);

        }

    }

}

@Override
public void mousePressed(MouseEvent e) {

    if(!isChecked) {


        if(e.getButton() == 1) {

            check();

        }

        if(e.getButton() == 3) {

            flag();

        }

    }

}

@Override
public void mouseEntered(MouseEvent e) {

}

@Override
public void mouseExited(MouseEvent arg0) {

}


@Override
public void mouseClicked(MouseEvent arg0) {}

@Override
public void mouseReleased(MouseEvent arg0) {}

}

BombSweeper类构建我的棋盘,对它的调用返回我已经制作的炸弹阵列。它是一个Bomb对象数组,长度为150个元素。

非常感谢任何关于如何阻止这种溢出的想法,谢谢。

1 个答案:

答案 0 :(得分:0)

如果我试图调试这个,我会做一些打印到控制台的实验来弄清楚我的逻辑错误在哪里。我做这样的事情:

public void check() {
    System.out.println("Checking location index = " + index);
    // Some code omitted
    if(imageNumber == 0) {

        System.out.println("Location number " + index + " has no bombs surrounding it.");

        this.setEnabled(false);

        if(index == 0) {

            check(BombSweeper.getField()[index + 1]);
            check(BombSweeper.getField()[index + 10]);
            check(BombSweeper.getField()[index + 11]);

        } else if(index > 0 && index < 9) {
            // Remaining Code omitted
}

正如其他一些想法一样,如果要使用二维数组,代码可能更容易阅读。然后你可以直接索引到x,y位置而不是做巧妙的数组切片。

最后,您可以考虑编写一些探索问题的单元测试。我从没有炸弹的1对1网格开始,看看&#39;检查&#39;方法呢。这可能会使问题变得清晰。

希望这有帮助!