-2

I have problem with reursive floodfilling in my minesweeper based on Swing JTable.

Here's my floodfill function:

        public void floodfill(MouseEvent e, int row, int column) {
            JTable target = (JTable)e.getSource();
            if (target.getValueAt(row, column) == this.getIconForValue(DataTable.getDataTableCellValue(row, column))) return;
            target.setValueAt(this.getIconForValue(DataTable.getDataTableCellValue(row, column)), row, column);

            if (row>0   &&  (DataTable.getDataTableCellValue(row-1, column)==0   || DataTable.getDataTableCellValue(row, column)==0))
                floodfill(e,row-1,column);

            if (row>0   &&  column>0    &&  (DataTable.getDataTableCellValue(row-1, column-1)!=0 && DataTable.getDataTableCellValue(row, column)==0))
                floodfill(e,row-1,column-1);

            if (column>0    &&      (DataTable.getDataTableCellValue(row, column-1)==0   || DataTable.getDataTableCellValue(row, column)==0))
                floodfill(e,row,column-1);

            if (row<DataTable.getNumberOfRows()-1       &&  column>0    &&  (DataTable.getDataTableCellValue(row+1, column-1)!=0   || DataTable.getDataTableCellValue(row, column)==0))
                floodfill(e,row+1,column-1);

            if (row<DataTable.getNumberOfRows()-1       &&      (DataTable.getDataTableCellValue(row+1, column)==0   || DataTable.getDataTableCellValue(row, column)==0))
                floodfill(e,row+1,column);

            if (row<DataTable.getNumberOfRows()-1       &&  column<DataTable.getNumberOfCols()-1 && (DataTable.getDataTableCellValue(row+1, column+1)!=0   || DataTable.getDataTableCellValue(row, column)==0))
                floodfill(e,row+1,column+1);

            if (column<DataTable.getNumberOfCols()-1    &&      (DataTable.getDataTableCellValue(row, column+1)==0   || DataTable.getDataTableCellValue(row, column)==0))
                floodfill(e,row,column+1);

            if (row>0       &&      column<DataTable.getNumberOfCols()-1 && (DataTable.getDataTableCellValue(row-1, column+1)!=0   || DataTable.getDataTableCellValue(row, column)==0))
                floodfill(e,row-1,column+1);

        }

getIconForValue function:

    public ImageIcon getIconForValue(int value) {
        ImageIcon icon = new ImageIcon("2.png");
        switch (value) {
            case 0:
                icon = new ImageIcon("0.png");
                break;
            case 1:
                icon = new ImageIcon("1.png");
                break;
            case 2:
                icon = new ImageIcon("2.png");
                break;
            case 3:
                icon = new ImageIcon("3.png");
                break;
            case 4:
                icon = new ImageIcon("4.png");
                break;
            case 5:
                icon = new ImageIcon("5.png");
                break;
            case 6:
                icon = new ImageIcon("6.png");
                break;
            case 7:
                icon = new ImageIcon("7.png");
                break;
            case 8:
                icon = new ImageIcon("8.png");
                break;
            case 9:
                icon = new ImageIcon("mine.png");
                break;
        }
        return icon;
    }

DataTable.java:

import java.util.Random;
import javax.swing.ImageIcon;

public class DataTable {

private static int numberOfRows;
private static int numberOfCols;
private static int numberOfMines;
private static Cell[][] dataTable;

public static void createDataTable(int numberOfRowsX, int numberOfColsX, int numberOfMinesX) {
    numberOfRows = numberOfRowsX;
    numberOfCols = numberOfColsX;
    numberOfMines = numberOfMinesX;
    dataTable = new Cell[numberOfRows][numberOfCols];
    for (int i = 0;i < numberOfRows;i++) {
        for (int j = 0; j < numberOfCols;j++) {
            dataTable[i][j] = new NumberCell();
        }
    }
}

public static void scatterMines () {
    int rowCoordOfMine, colCoordOfMine;
    Random randY = new Random();
    Random randX = new Random();

    for (int i = 1;i < numberOfMines+1;i++){
        do {
            rowCoordOfMine = randY.nextInt(10)+0;
            colCoordOfMine = randX.nextInt(15)+0;
        } while(dataTable[rowCoordOfMine][colCoordOfMine].getValue() == 9);
        dataTable[rowCoordOfMine][colCoordOfMine] = new MineCell(); 
    }
}

public static void increaseFieldValues() {
    for (int i = 0;i < numberOfRows;i++) {
        for (int j = 0;j < numberOfCols;j++) {
            if (dataTable[i][j].getValue() == 9) {
                if (i>0) {
                    if (dataTable[i-1][j].getValue() != 9) dataTable[i-1][j].increase();
                }
                if ((i>0) && (j>0)) {
                    if (dataTable[i-1][j-1].getValue() != 9) dataTable[i-1][j-1].increase();
                }
                if (j>0) {
                    if (dataTable[i][j-1].getValue() != 9) dataTable[i][j-1].increase();
                }
                if ((i<9) && (j>0)) {
                    if (dataTable[i+1][j-1].getValue() != 9) dataTable[i+1][j-1].increase();
                }
                if (i<9) {
                    if (dataTable[i+1][j].getValue() != 9) dataTable[i+1][j].increase();
                }
                if ((i<9) && (j<9)) {
                    if (dataTable[i+1][j+1].getValue() != 9) dataTable[i+1][j+1].increase();
                }
                if (j<9) {
                    if (dataTable[i][j+1].getValue() != 9) dataTable[i][j+1].increase();
                }
                if ((i>0) && (j<9)) {
                    if (dataTable[i-1][j+1].getValue() != 9) dataTable[i-1][j+1].increase();
                }
            }
        }
    }
}

public static int getDataTableCellValue(int rowCoord, int colCoord) {
    return dataTable[rowCoord][colCoord].getValue();
}

public static int getNumberOfRows() {
    return numberOfRows;
}

public static int getNumberOfCols() {
    return numberOfCols;
}

}

UserTable.java:

package java_hf;
import java.util.Random;
import javax.swing.ImageIcon;

public class UserTable {

    private static int numberOfRows;
    private static int numberOfCols;
    private static ImageIcon[][] userTable;

    public static void createUserTable(int numberOfRowsX, int numberOfColsX) {
        numberOfRows = numberOfRowsX;
        numberOfCols = numberOfColsX;
        userTable = new ImageIcon[numberOfRows][numberOfCols];
        for (int i = 0;i < numberOfRows;i++) {
            for (int j = 0; j < numberOfCols;j++) {
                userTable[i][j] = new ImageIcon("empty.png");
            }
        }
    }

    public static ImageIcon[][] getUserTable() {
        return userTable;
    }
}

The JTable is based on DefaultTableModel with 2D array, which contains ImageIcons. The DataTable is a class, which contains an static integer 2D array, which contains the data of the minefield (0-8 -> the number of mines on adjacent cells, 9 -> mine). The DataTable.getNumberOfCols() and DataTable.getNumberOfRows() functions returns the amount of columns and rows in the DataTable's array. getIconForValue() function returns the ImageIcon for the given number. Finally, the DataTable.getDataTableCellValue() returns the value of the given cell in the DataTable's array.

The both arrays are filled with content from [0][0].

The problem is stackoverflowing. The weird thing is, that the same function in my C code works without problems.

Sorry for the little chaotic code, but i hope someone can help me. Thanks!

Update: i added getIconValue function and the DataTable and UserTable classes.

andrew1515
  • 87
  • 7

1 Answers1

0

Do not create a new ImageIcon each time. == between different objects with same value will always return false. ImageIcon does not implement equals so using that will do the same.

either use static instances of the Image or do a map lookup.

private static ImageIcon _0 = new ImageIcon("0.png");

public ImageIcon getIconForValue(int value) {
    ImageIcon icon;
    switch (value) {
        case 0:
            icon = _0;
            break;
         ...
        default:
            icon = _2;
            break;
    }
    return icon;
}

or

public ImageIcon getIconForValue(int value) {
    ImageIcon icon = iconMap.get(value);
    if(icon == null){
        icon = new ImageIcon(value+".png");
        iconMap.put(value,icon);
    }
    return icon;
}
BevynQ
  • 8,089
  • 4
  • 25
  • 37