【问题标题】:Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError线程“AWT-EventQueue-0”中的异常 java.lang.StackOverflowError
【发布时间】:2014-05-23 14:40:53
【问题描述】:

我正在制作一个 Minesweeper 克隆,目的是自学 Swing 并更全面地了解 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 类构建了我的棋盘,调用它会返回我制作的炸弹数组。它是一个 150 个元素长的 Bomb 对象数组。

任何关于如何阻止这种溢出的想法将不胜感激,谢谢。

【问题讨论】:

  • 您必须在进入递归之前在字段上设置“已处理”指示符。目前您imageNumber == 0 时设置isChecked 标志。但是您将enabled 设置为false,因此您可以将方法的第一行更改为if(isFlagged || isChecked || !isEnabled()) return;
  • 感谢您的建议。我只是去做了那个改变,结果就像我以前一样。它停止了无限递归,但它只检查最多 1 个单元格。恐怕我可能不得不再次完全修改我的检查方法。大声笑,我希望第七次是魅力。

标签: java swing recursion stack-overflow


【解决方案1】:

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

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 x 1 网格开始,看看“检查”方法的作用。这可能会让问题变得清晰。

希望这会有所帮助!

【讨论】:

  • 谢谢。这是一个很好的起点。在我最初的几次迭代中,我确实从一个二维数组开始,但我的运气更差。 :S
猜你喜欢
  • 1970-01-01
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
  • 2012-04-06
  • 1970-01-01
  • 2013-04-28
  • 2015-10-23
  • 1970-01-01
相关资源
最近更新 更多