Java GUI中的递归错误

Java GUI中的递归错误,java,swing,recursion,methods,minesweeper,Java,Swing,Recursion,Methods,Minesweeper,我正在为扫雷舰创建一个简单的9x9网格。这个游戏的一个主要功能是当点击的瓷砖周围没有炸弹时,有一个递归来检查所有的边。在下面附带的代码中,我已经能够创建一个函数来检查瓷砖的上部和左侧。如果我添加更多的方向,例如下方和右侧,程序将崩溃,并且无法正确显示瓷砖。(检查//我的主要问题行下的方法countBorders) //显示主GUI 包装扫雷机4 public class mainFrame { public static void main(String[] args) { new G

我正在为扫雷舰创建一个简单的9x9网格。这个游戏的一个主要功能是当点击的瓷砖周围没有炸弹时,有一个递归来检查所有的边。在下面附带的代码中,我已经能够创建一个函数来检查瓷砖的上部和左侧。如果我添加更多的方向,例如下方和右侧,程序将崩溃,并且无法正确显示瓷砖。(检查
//我的主要问题
行下的方法
countBorders

//显示主GUI 包装扫雷机4

public class mainFrame {

public static void main(String[] args) {
    new Grid().setVisible(true);
}

}
//主代码

package Minesweeper4;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;

public class Grid extends JFrame implements ActionListener {

    private JPanel mainGrid;
    private JButton button1, button2;
    private JButton[][] buttons = new JButton[9][9];
    private String[][] mines = new String[9][9];
    private ArrayList<ParentSquare> parentSquare = new ArrayList<ParentSquare>();

    Random rand = new Random();

    NumberSquare numberSquare = new NumberSquare();
    MineSquare mineSquare = new MineSquare();

    public void addMines() {
        for (int j = 0; j < 9; j++) {
            for (int k = 0; k < 9; k++) {
                mines[j][k] = ".";
            }
        }
        for (int i = 0; i < 3; i++) {
            int temp_x = rand.nextInt(9);
            int temp_y = rand.nextInt(9);
            mines[temp_x][temp_y] = "x";
        }
    }

    public void showMines() {
        for (int x = 0; x < 9; x++) {
            for (int y = 0; y < 9; y++) {
                String temp = mines[x][y];
                if (temp.equals("x")) {
                    System.out.println("X: " + (x + 1) + " Y: " + (y + 1) + " Value: " + temp);
                }
            }
        }
    }

    public Grid() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(500, 500);
        this.setTitle("Minesweeper 1.0");

        mainGrid = new JPanel();
        mainGrid.setLayout(new GridLayout(9, 9));
        this.add(mainGrid);

        button1 = new JButton("Boop");
        button2 = new JButton("Poop");

        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                buttons[i][j] = new JButton("");
                buttons[i][j].addActionListener(this);
                buttons[i][j].setBackground(Color.GRAY);
            }
        }

        for (int k = 0; k < 9; k++) {
            for (int l = 0; l < 9; l++) {
                mainGrid.add(buttons[k][l]);
            }
        }

        addMines();
        showMines();

    }

    public void countBorders(int x, int y) {
        int UL = 0, UU = 0, UR = 0, LL = 0, RR = 0, DL = 0, DD = 0, DR = 0, SUM = 0;

        if (x > 0) {
            UU = checkTile(x - 1, y);
        }
        if (y > 0) {
            LL = checkTile(x, y - 1);
        }
        if (y < 8) {
            RR = checkTile(x, y + 1);
        }
        if (x < 8) {
            DD = checkTile(x + 1, y);
        }
        if ((x > 0) && (y > 0)) {
            UL = checkTile(x - 1, y - 1);
        }

        if ((x > 0) && (y < 8)) {
            UR = checkTile(x - 1, y + 1);
        }

        if ((x < 8) && (y > 0)) {
            DL = checkTile(x + 1, y - 1);
        }

        if ((x < 8) && (y < 8)) {
            DR = checkTile(x + 1, y + 1);
        }

        SUM = UL + UU + UR + LL + RR + DL + DD + DR;

        printTile(x, y, SUM);

        if (SUM == 0) { //MY MAIN PROBLEM

//            if ((x > 0) && (y > 0)) {countBorders(x-1, y-1);}               //Upper left
            if (x > 0) {
                countBorders(x - 1, y);
            }                 //Upper 
//            if ((x > 0) && (y < 8)) {countBorders(x-1, y+1);}               //Upper right
            if (y > 0) {
                countBorders(x, y - 1);
            }                 //Left
//            if (y < 8)              {countBorders(x, y+1);}                 //Right
//            if ((x < 8) && (y > 0)) {countBorders(x+1, y-1);}               //Down Left
//            if (x < 8)              {countBorders(x+1, y);}                 //Down
//            if ((x < 8) && (y < 8)) {countBorders(x+1, y+1);}               //Down Right
        }

    }

    public void printTile(int x, int y, int SUM) {
        String text = Integer.toString(SUM);
        buttons[x][y].setText(text);
        buttons[x][y].setBackground(Color.CYAN);
    }

    public int checkTile(int x, int y) {
        String c = mines[x][y];
        if (c.equals("x")) {
            return 1;
        } else {
            return 0;
        }
    }

    public void click(int x, int y) {
        String mine = mines[x][y];
        if (mine.equals("x")) {
            System.out.println("Bomb!!!");
            buttons[x][y].setText("!");
            buttons[x][y].setBackground(Color.RED);
        } else {
            countBorders(x, y);
            System.out.println("Safe!!!");
//            buttons[x][y].setText("√");
//            buttons[x][y].setBackground(Color.WHITE);
        }

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (e.getSource() == buttons[i][j]) {
                    System.out.println("Clicked Tile X: " + (i + 1) + " Y: " + (j + 1));
                    //buttons[i][j].setText("!");
                    click(i, j);
                }
            }
        }
    }

}
package扫雷机4;
导入java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入java.util.Random;
导入javax.swing.*;
公共类网格扩展JFrame实现ActionListener{
私有JPanel主电网;
私有JButton按钮1、按钮2;
私有JButton[][]按钮=新JButton[9][9];
私有字符串[][]mines=新字符串[9][9];
private ArrayList parentSquare=new ArrayList();
Random rand=新的Random();
NumberSquare NumberSquare=新的NumberSquare();
MineSquare MineSquare=新MineSquare();
公共资源管理({
对于(int j=0;j<9;j++){
对于(int k=0;k<9;k++){
地雷[j][k]=”;
}
}
对于(int i=0;i<3;i++){
int temp_x=兰德公司下一个季度(9);
int temp_y=下一次随机数(9);
矿山[temp_x][temp_y]=“x”;
}
}
公共矿山{
对于(int x=0;x<9;x++){
对于(int y=0;y<9;y++){
字符串温度=矿[x][y];
如果(温度等于(“x”)){
系统输出打印项次(“X:”+(X+1)+“Y:”+(Y+1)+“值:”+temp);
}
}
}
}
公共电网(){
此.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
这个。设置大小(500500);
这是setTitle(“扫雷舰1.0”);
mainGrid=newjpanel();
setLayout(新的GridLayout(9,9));
添加(主网格);
button1=新的JButton(“Boop”);
按钮2=新的按钮(“Poop”);
对于(int i=0;i<9;i++){
对于(int j=0;j<9;j++){
按钮[i][j]=新的JButton(“”);
按钮[i][j].addActionListener(此);
按钮[i][j].背景(颜色.灰色);
}
}
对于(int k=0;k<9;k++){
对于(int l=0;l<9;l++){
添加(按钮[k][l]);
}
}
addMines();
showMines();
}
公共边界(整数x,整数y){
int-UL=0,UU=0,UR=0,LL=0,RR=0,DL=0,DD=0,DR=0,SUM=0;
如果(x>0){
UU=方格图(x-1,y);
}
如果(y>0){
LL=方格图(x,y-1);
}
if(y<8){
RR=方格(x,y+1);
}
if(x<8){
DD=方格瓦(x+1,y);
}
如果((x>0)和&(y>0)){
UL=方格瓦(x-1,y-1);
}
如果((x>0)和&(y<8)){
UR=方格图(x-1,y+1);
}
如果((x<8)和&(y>0)){
DL=方格图(x+1,y-1);
}
如果((x<8)和&(y<8)){
DR=方格(x+1,y+1);
}
总和=UL+UU+UR+LL+RR+DL+DD+DR;
打印瓷砖(x,y,总和);
如果(SUM==0){//我的主要问题
//if((x>0)&(y>0)){countBorders(x-1,y-1);}//左上角
如果(x>0){
国家边界(x-1,y);
}//上
//如果((x>0)&(y<8)){countBorders(x-1,y+1);}//右上角
如果(y>0){
国家边界(x,y-1);
}//左
//如果(y<8){countBorders(x,y+1);}//右
//如果((x<8)&(y>0)){countBorders(x+1,y-1);}//左下
//如果(x<8){countBorders(x+1,y);}//Down
//如果((x<8)&(y<8)){countBorders(x+1,y+1);}//右下
}
}
公共无效打印分幅(整数x、整数y、整数和){
字符串文本=整数。toString(总和);
按钮[x][y].setText(文本);
按钮[x][y]。背景色(颜色为青色);
}
公共整数校验分幅(整数x,整数y){
字符串c=地雷[x][y];
如果(c等于(“x”)){
返回1;
}否则{
返回0;
}
}
公共无效单击(整数x,整数y){
字符串mine=mines[x][y];
如果(我的值等于(“x”)){
System.out.println(“Bomb!!!”;
按钮[x][y].setText(!”;
按钮[x][y]。收进背景(颜色。红色);
}否则{
国家边界(x,y);
System.out.println(“安全!!!”);
//按钮[x][y].setText(“√");
//按钮[x][y]。背景(颜色.白色);
}
}
@凌驾
已执行的公共无效操作(操作事件e){
对于(int i=0;i<9;i++){
对于(int j=0;j<9;j++){
如果(例如getSource()==按钮[i][j]){
System.out.println(“单击的磁贴X:+(i+1)+“Y:+(j+1));
//按钮[i][j].setText(!”;
点击(i,j);
}
}
}
}
}
有没有办法解决这个递归问题?
提前感谢您,我正在努力学习Java。祝您愉快!

您导致递归的错误没有我能找到的停止逻辑,您需要做的是以某种方式检查以确保在重新计数之前单元格尚未被计数或按下。否则代码可能会抛出stackoverflow错误。这将
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import javax.swing.event.SwingPropertyChangeSupport;

@SuppressWarnings("serial")
public class MineSweeper {
    private JPanel mainPanel = new JPanel();
    private MineCellGrid mineCellGrid;
    private JButton resetButton = new JButton("Reset");

    public MineSweeper(int rows, int cols, int mineTotal) {
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
        mineCellGrid = new MineCellGrid(rows, cols, mineTotal);

        resetButton.setMnemonic(KeyEvent.VK_R);
        resetButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                mineCellGrid.reset();
            }
        });

        mainPanel.add(mineCellGrid);
        mainPanel.add(new JSeparator());
        mainPanel.add(new JPanel() {
            {
                add(resetButton);
            }
        });
    }

    private JPanel getMainPanel() {
        return mainPanel;
    }

    private static void createAndShowUI() {
        JFrame frame = new JFrame("MineSweeper");
        // frame.getContentPane().add(new MineSweeper(20, 20,
        // 44).getMainPanel());
        frame.getContentPane().add(new MineSweeper(12, 12, 13).getMainPanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                createAndShowUI();
            }
        });
    }
}

@SuppressWarnings("serial")
class MineCellGrid extends JPanel {
    private MineCellGridModel model;
    private List<MineCell> mineCells = new ArrayList<MineCell>();

    public MineCellGrid(final int maxRows, final int maxCols, int mineNumber) {
        model = new MineCellGridModel(maxRows, maxCols, mineNumber);
        setLayout(new GridLayout(maxRows, maxCols));

        for (int row = 0; row < maxRows; row++) {
            for (int col = 0; col < maxCols; col++) {
                MineCell mineCell = new MineCell(row, col);
                add(mineCell);
                mineCells.add(mineCell);
                model.add(mineCell.getModel(), row, col);
            }
        }

        reset();
    }

    public void reset() {
        model.reset();
        for (MineCell mineCell : mineCells) {
            mineCell.reset();
        }
    }
}

class MineCellGridModel {
    private MineCellModel[][] cellModelGrid;
    private List<Boolean> mineList = new ArrayList<Boolean>();
    private CellModelPropertyChangeListener cellModelPropChangeListener = new CellModelPropertyChangeListener();
    private int maxRows;
    private int maxCols;
    private int mineNumber;
    private int buttonsRemaining;

    public MineCellGridModel(final int maxRows, final int maxCols, int mineNumber) {
        this.maxRows = maxRows;
        this.maxCols = maxCols;
        this.mineNumber = mineNumber;
        for (int i = 0; i < maxRows * maxCols; i++) {
            mineList.add((i < mineNumber) ? true : false);
        }
        cellModelGrid = new MineCellModel[maxRows][maxCols];
        buttonsRemaining = (maxRows * maxCols) - mineNumber;
    }

    public void add(MineCellModel model, int row, int col) {
        cellModelGrid[row][col] = model;
        model.addPropertyChangeListener(cellModelPropChangeListener);
    }

    public void reset() {
        buttonsRemaining = (maxRows * maxCols) - mineNumber;

        // randomize the mine location
        Collections.shuffle(mineList);
        // reset the model grid and set mines
        for (int r = 0; r < cellModelGrid.length; r++) {
            for (int c = 0; c < cellModelGrid[r].length; c++) {
                cellModelGrid[r][c].reset();
                cellModelGrid[r][c].setMined(mineList.get(r * cellModelGrid[r].length + c));
            }
        }
        // advance value property of all neighbors of a mined cell
        for (int r = 0; r < cellModelGrid.length; r++) {
            for (int c = 0; c < cellModelGrid[r].length; c++) {
                if (cellModelGrid[r][c].isMined()) {
                    int rMin = Math.max(r - 1, 0);
                    int cMin = Math.max(c - 1, 0);
                    int rMax = Math.min(r + 1, cellModelGrid.length - 1);
                    int cMax = Math.min(c + 1, cellModelGrid[r].length - 1);
                    for (int row2 = rMin; row2 <= rMax; row2++) {
                        for (int col2 = cMin; col2 <= cMax; col2++) {
                            cellModelGrid[row2][col2].incrementValue();
                        }
                    }
                }
            }
        }
    }

    private class CellModelPropertyChangeListener implements PropertyChangeListener {

        public void propertyChange(PropertyChangeEvent evt) {
            MineCellModel model = (MineCellModel) evt.getSource();
            int row = model.getRow();
            int col = model.getCol();

            if (evt.getPropertyName().equals(MineCellModel.BUTTON_PRESSED)) {
                if (cellModelGrid[row][col].isMineBlown()) {
                    mineBlown();
                } else {
                    buttonsRemaining--;
                    if (buttonsRemaining <= 0) {
                        JOptionPane.showMessageDialog(null, "You've Won!!!", "Congratulations",
                                JOptionPane.PLAIN_MESSAGE);
                    }
                    if (cellModelGrid[row][col].getValue() == 0) {
                        zeroValuePress(row, col);
                    }
                }
            }
        }

        private void mineBlown() {
            for (int r = 0; r < cellModelGrid.length; r++) {
                for (int c = 0; c < cellModelGrid[r].length; c++) {
                    MineCellModel model = cellModelGrid[r][c];
                    if (model.isMined()) {
                        model.setMineBlown(true);
                    }
                }
            }

        }

        private void zeroValuePress(int row, int col) {
            int rMin = Math.max(row - 1, 0);
            int cMin = Math.max(col - 1, 0);
            int rMax = Math.min(row + 1, cellModelGrid.length - 1);
            int cMax = Math.min(col + 1, cellModelGrid[row].length - 1);
            for (int row2 = rMin; row2 <= rMax; row2++) {
                for (int col2 = cMin; col2 <= cMax; col2++) {
                    cellModelGrid[row2][col2].pressedAction();
                }
            }
        }
    }
}

@SuppressWarnings("serial")
class MineCell extends JPanel {
    private static final String LABEL = "label";
    private static final String BUTTON = "button";
    private static final int PS_WIDTH = 24;
    private static final int PS_HEIGHT = PS_WIDTH;
    private static final float LABEL_FONT_SIZE = (float) (24 * PS_WIDTH) / 30f;
    private static final float BUTTON_FONT_SIZE = (float) (14 * PS_WIDTH) / 30f;
    private JButton button = new JButton();
    private JLabel label = new JLabel(" ", SwingConstants.CENTER);
    private CardLayout cardLayout = new CardLayout();
    private MineCellModel model;

    public MineCell(final boolean mined, int row, int col) {
        model = new MineCellModel(mined, row, col);
        model.addPropertyChangeListener(new MyPCListener());
        label.setFont(label.getFont().deriveFont(Font.BOLD, LABEL_FONT_SIZE));
        button.setFont(button.getFont().deriveFont(Font.PLAIN, BUTTON_FONT_SIZE));
        button.setMargin(new Insets(1, 1, 1, 1));
        setLayout(cardLayout);

        add(button, BUTTON);
        add(label, LABEL);

        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                pressedAction();
            }
        });
        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON3) {
                    model.upDateButtonFlag();
                }
            }
        });
    }

    public MineCell(int row, int col) {
        this(false, row, col);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(PS_WIDTH, PS_HEIGHT);
    }

    public void pressedAction() {
        if (model.isFlagged()) {
            return;
        }
        model.pressedAction();
    }

    public void showCard(String cardConstant) {
        cardLayout.show(this, cardConstant);
    }

    // TODO: have this change the button's icon
    public void setFlag(boolean flag) {
        if (flag) {
            button.setBackground(Color.yellow);
            button.setForeground(Color.red);
            button.setText("f");
        } else {
            button.setBackground(null);
            button.setForeground(null);
            button.setText("");
        }
    }

    private void setMineBlown(boolean mineBlown) {
        if (mineBlown) {
            label.setBackground(Color.red);
            label.setOpaque(true);
            showCard(LABEL);
        } else {
            label.setBackground(null);
        }
    }

    public MineCellModel getModel() {
        return model;
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        model.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        model.removePropertyChangeListener(listener);
    }

    private class MyPCListener implements PropertyChangeListener {
        public void propertyChange(PropertyChangeEvent evt) {
            String propName = evt.getPropertyName();
            if (propName.equals(MineCellModel.MINE_BLOWN)) {
                setMineBlown(true);
            } else if (propName.equals(MineCellModel.FLAG_CHANGE)) {
                setFlag(model.isFlagged());
            } else if (propName.equals(MineCellModel.BUTTON_PRESSED)) {
                if (model.isMineBlown()) {
                    setMineBlown(true);
                } else {
                    String labelText = (model.getValue() == 0) ? "" : String.valueOf(model
                            .getValue());
                    label.setText(labelText);
                }
                showCard(LABEL);
            }
        }
    }

    public void reset() {
        setFlag(false);
        setMineBlown(false);
        showCard(BUTTON);
        label.setText("");
    }

}

class MineCellModel {
    public static final String FLAG_CHANGE = "Flag Change";
    public static final String BUTTON_PRESSED = "Button Pressed";
    public static final String MINE_BLOWN = "Mine Blown";
    private int row;
    private int col;
    private int value = 0;
    private boolean mined = false;;
    private boolean flagged = false;
    private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
    private boolean pressed = false;
    private boolean mineBlown = false;

    public MineCellModel(boolean mined, int row, int col) {
        this.mined = mined;
        this.row = row;
        this.col = col;
    }

    public void incrementValue() {
        int temp = value + 1;
        setValue(temp);
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setMineBlown(boolean mineBlown) {
        this.mineBlown = mineBlown;
        PropertyChangeEvent evt = new PropertyChangeEvent(this, MINE_BLOWN, false, true);
        pcSupport.firePropertyChange(evt);
    }

    public boolean isMineBlown() {
        return mineBlown;
    }

    public void setMined(boolean mined) {
        this.mined = mined;
    }

    public void setFlagged(boolean flagged) {
        this.flagged = flagged;
    }

    public int getRow() {
        return row;
    }

    public int getCol() {
        return col;
    }

    public boolean isMined() {
        return mined;
    }

    public boolean isFlagged() {
        return flagged;
    }

    public void pressedAction() {
        if (pressed) {
            return;
        }
        pressed = true;
        if (mined) {
            setMineBlown(true);
        }

        PropertyChangeEvent evt = new PropertyChangeEvent(this, BUTTON_PRESSED, -1, value);
        pcSupport.firePropertyChange(evt);
    }

    public void upDateButtonFlag() {
        boolean oldValue = flagged;
        setFlagged(!flagged);
        PropertyChangeEvent evt = new PropertyChangeEvent(this, FLAG_CHANGE, oldValue, flagged);
        pcSupport.firePropertyChange(evt);
    }

    public void reset() {
        mined = false;
        flagged = false;
        pressed = false;
        mineBlown = false;
        value = 0;
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        pcSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        pcSupport.removePropertyChangeListener(listener);
    }
}
button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        pressedAction();
    }
});
public void pressedAction() {
    if (model.isFlagged()) {
        return;
    }
    model.pressedAction();
}
// within MineCellModel
public void pressedAction() {
    if (pressed) {
        // if the button's already been pressed -- return, do nothing
        return;
    }

    // otherwise make pressed true
    pressed = true;

    // if we've hit a mine -- blow it!
    if (mined) {
        setMineBlown(true);
    }

    // *** Here's the key *** notify all listeners that this button has been pressed
    PropertyChangeEvent evt = new PropertyChangeEvent(this, BUTTON_PRESSED, -1, value);
    pcSupport.firePropertyChange(evt);
}
private class CellModelPropertyChangeListener implements PropertyChangeListener {

    public void propertyChange(PropertyChangeEvent evt) {
        // first get the MineCellModel for the cell that triggered this notification
        MineCellModel model = (MineCellModel) evt.getSource();
        int row = model.getRow();
        int col = model.getCol();

        // if the event is a button pressed event
        if (evt.getPropertyName().equals(MineCellModel.BUTTON_PRESSED)) {
            // first check if a mine was hit, and if so, call mineBlown()
            if (cellModelGrid[row][col].isMineBlown()) {
                mineBlown(); // this method iterates through all cells and blows all mines
            } else {
                // here we check for a winner
                buttonsRemaining--;
                if (buttonsRemaining <= 0) {
                    JOptionPane.showMessageDialog(null, "You've Won!!!", "Congratulations",
                            JOptionPane.PLAIN_MESSAGE);
                }

                // here is the key spot -- if cell's value is 0, call the zeroValuePress method
                if (cellModelGrid[row][col].getValue() == 0) {
                    zeroValuePress(row, col);
                }
            }
        }
    }

    private void mineBlown() {
        // ... code to blow all the un-blown mines
    }

    // this code is called if a button pressed has 0 value -- no mine neighbors
    private void zeroValuePress(int row, int col) {

        // find the boundaries of the neighbors
        int rMin = Math.max(row - 1, 0);  // check for the top edge
        int cMin = Math.max(col - 1, 0);  // check for the left edge
        int rMax = Math.min(row + 1, cellModelGrid.length - 1);  // check for the bottom edge
        int cMax = Math.min(col + 1, cellModelGrid[row].length - 1);  // check for right edge

        // iterate through the neighbors
        for (int row2 = rMin; row2 <= rMax; row2++) {
            for (int col2 = cMin; col2 <= cMax; col2++) {
                // *** Here's the recursion ***
                // call pressedAction on all the neighbors
                cellModelGrid[row2][col2].pressedAction();
            }
        }
    }
}
for(int x=(coordX-1); x<=(coordX+1); x++)
    for(int y=(coordY-1); y<=(coordY+1); y++)
        if(x!=-1 && y!= -1 && x! = ROWS && y! = COLS && map[x][y] != 'B')
            if(map[x][y] == '.')
                map[x][y] = '1';
            else
                map[x][y] += 1;