找不到错误(StackOverflowError)

时间:2014-04-10 19:04:11

标签: java windows swing sudoku stack-overflow

我正在写一个数独求解程序,但我遇到了以下错误:

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.util.HashMap.hash(Unknown Source)
at java.util.HashMap.getEntry(Unknown Source)
at java.util.HashMap.get(Unknown Source)
at sun.awt.AppContext.get(Unknown Source)
at sun.awt.SunToolkit.flushPendingEvents(Unknown Source)
at java.awt.EventQueue.postEvent(Unknown Source)
at java.awt.EventQueue.invokeLater(Unknown Source)
at javax.swing.SwingUtilities.invokeLater(Unknown Source)
at javax.swing.text.DefaultCaret.changeCaretPosition(Unknown Source)
at javax.swing.text.DefaultCaret.handleSetDot(Unknown Source)
at javax.swing.text.DefaultCaret.setDot(Unknown Source)
at javax.swing.text.DefaultCaret$Handler.insertUpdate(Unknown Source)
at javax.swing.text.AbstractDocument.fireInsertUpdate(Unknown Source)
at javax.swing.text.AbstractDocument.handleInsertString(Unknown Source)
at javax.swing.text.AbstractDocument.insertString(Unknown Source)
at javax.swing.text.PlainDocument.insertString(Unknown Source)
at javax.swing.text.AbstractDocument.replace(Unknown Source)
at javax.swing.text.JTextComponent.setText(Unknown Source)

我无法找到此错误的原因。我的程序代码如下:

package code;

import java.awt.Color;                                         //Import nötiger Klassen
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; 




public class SOLVE implements ActionListener{

private int[][] matrix;                         //Eingelesenes Sudokufeld
private boolean[][]input;                       //Überfrüfungsfeld zur bestimmung von eingegebenen Zahlen

private JFrame fenster;                         //GUI Fenster
private JTextArea field[][];                    //GUI Text Sudoku Feld
private JButton start;                          //Start Button
private JButton reset;


public void gui(){                                            //Erstellt die Grafische Oberfläche
    Border b1 = BorderFactory.createLineBorder( Color.black );

    //Erstellt Fenster
    fenster = new JFrame();
    fenster.setLocation(100, 100);
    fenster.setSize(500, 320);
    fenster.getContentPane().setLayout(null);
    fenster.setTitle("Sudoku Solver");

    //Erstellt Sudoku TextFelder
    field = new JTextArea[9][9];
    int x = 0;      //x-Koordinate
    for(int i=0;i<9;i++){
        int y = 0;     //y-Koordinate
        for(int j=0;j<9;j++){
            field[i][j] = new JTextArea();
            field[i][j].setLocation((200+x),(30+y));
            field[i][j].setSize(20, 20);
            field[i][j].setText("0");
            field[i][j].setBorder(b1);
            field[i][j].setVisible(true);
            fenster.add(field[i][j]);
            if(j==2||j==5){
                y=y+32;
            }
            else{
                y=y+25;
            }
        }
        if(i==2||i==5){
            x=x+32;
        }
        else{
            x=x+25;
        }
    }

    //Erstellt Start Button
    start = new JButton();
    start.setText("Solve");
    start.setSize(150,50);
    start.setLocation(30,30);
    start.addActionListener(this);

    //Erstellt Reset Button
    reset = new JButton();
    reset.setText("Reset");
    reset.setSize(150,50);
    reset.setLocation(30,100);
    reset.addActionListener(this);


    //Fügt Komponenten zum Fenster hinzu
    fenster.add(reset);
    fenster.add(start);
    fenster.setVisible(true);
}

public SOLVE(){                                               //Startet Klasse
    gui();
    matrix = new int[9][9];
    input = new boolean[9][9];
}

public void copy(){                                           //Einlesen der TextFelder in die Matrix une Überprüfungs Matrix
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            matrix[i][j]=Integer.parseInt(field[i][j].getText());
            if(matrix[i][j]!=0){
                input[i][j]=false;
            }
            else{
                input[i][j] = true;
            }
        }
    }   
}

public boolean check(int x,int y, int solution){              //Überprüfung ob Lösung möglich ist für eine bestimmte Zahl bei einem bestimmten Feld
    boolean moeglich = false; //Insgesammt möglich
    boolean wmoeglich = true; //Waagrecht möglich
    boolean smoeglich = true; //Senkrecht möglich
    boolean fmoeglich = true; //Feld möglich

    //Überprüft waagrecht und senkrecht ob möglich
    for(int i=0;i<9;i++){
        if(matrix[x][i]==solution){
            wmoeglich = false;
        }
        if(matrix[i][y]==solution){
            smoeglich = false;
        }
    }
    //Sucht nötiges Feld und überprüft dieses

    //Oberste Reihe
    if(x<3){
        //linkes Feld
        if(y<3){
            for(int i=0;i<3;i++){
                for(int j=0;j<3;j++){
                    if(matrix[i][j]==solution){
                        fmoeglich = false;
                    }
                }
            }
        }
        //mittleres Feld
        else if(y<6&& y>2){
            for(int i=0;i<3;i++){
                for(int j=3;j<6;j++){
                    if(matrix[i][j]==solution){
                        fmoeglich = false;
                    }
                }
            }
        }
        //rechtes Feld
        else if(y<9 && y>5){
            for(int i=0;i<3;i++){
                for(int j=6;j<9;j++){
                    if(matrix[i][j]==solution){
                        fmoeglich = false;
                    }
                }
            }
        }
    }
    //mittlere Reihe
    else if(x<6 && x>2){
        //linkes Feld
        if(y<3){
            for(int i=3;i<6;i++){
                for(int j=0;j<3;j++){
                    if(matrix[i][j]==solution){
                        fmoeglich = false;
                    }
                }
            }
        }
        //mittleres Feld
        else if(y<6 && y>2){
            for(int i=3;i<6;i++){
                for(int j=3;j<6;j++){
                    if(matrix[i][j]==solution){
                        fmoeglich = false;
                    }
                }
            }
        }
        //rechtes Feld
        else if(y<9 && y>5){
            for(int i=3;i<6;i++){
                for(int j=6;j<9;j++){
                    if(matrix[i][j]==solution){
                        fmoeglich = false;
                    }
                }
            }
        }
    }
    //unterste Reihe
    else if(x<9 && x>5){
        //linkes Feld
        if(y<3){
            for(int i=6;i<9;i++){
                for(int j=0;j<3;j++){
                    if(matrix[i][j]==solution){
                        fmoeglich = false;
                    }
                }
            }
        }
        //mittleres Feld
        else if(y<6 && y>2){
            for(int i=6;i<9;i++){
                for(int j=3;j<6;j++){
                    if(matrix[i][j]==solution){
                        fmoeglich = false;
                    }
                }
            }
        }
        //rechtes Feld
        else if(y<9 && y>5){
            for(int i=6;i<9;i++){
                for(int j=6;j<9;j++){
                    if(matrix[i][j]==solution){
                        fmoeglich = false;
                    }
                }
            }
        }
    }

    //wenn eine Überprüfung fehlgeschlagen Lösung nicht möglich
    if(smoeglich == true && wmoeglich == true && fmoeglich == true){
        moeglich = true;
    }
    return moeglich;
}

public void search(int i, int j){                             //Lösen des Sudokus (Eigentlich Rekursiv)
    if(input[i][j]==true){  //Wenn keine menschliche eingabe
        int l = 1;
        for(l=1;l<10;l++){
            if(check(i,j,l)==true){  //Wenn Überprüfung erfolgreich war
                  matrix[i][j]=l;    //Schreibt Lösung in Matrix
                  field[i][j].setText(""+l); //Und Schreibt Lösung in TextFeld

                  //Nachfolger suchen
                    if(i<=7){
                       search(i+1,j);   
                    }
                    else if(i==8 && j<=7){
                        search(i-8,j+1);
                    }
                    else{
                        break;
                    }
            }
            //Da Rekursion nicht funktionierte hier den Schritt zurück 
            else if(check(i,j,l)==false && l==9){
                matrix[i][j]=0;
                if(i>0){
                    search(i-1,j);
                }
                else if(i==0 && j>0){
                    search(i+8,j-1);
                }
                else{
                    break;
                }
            }
        }
    }
    else{
        //Nachfolger suchen
        if(i<=7){
             search(i+1,j);      
        }
        else if(i==8 && j<=7){
            search(i-8,j+1);
        }
        else{}
    }
}

public void reset(){                                          //Resettet Fenster und Matrix
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            field[i][j].setText("0");
            matrix[i][j]=0;
            input[i][j]=true;
        }
    }
}

public void master(){                                         //Master Methode (Führt die nötigen Methoden nacheinander aus)
    System.gc();
    copy();
    search(0,0);    
}

public static void main(String[] args) {                      //Main Methode (Start Methode)
    new SOLVE();
}

public void actionPerformed(ActionEvent evt){                 //Button Abfrage
    Object source = evt.getSource();

    if(source==start){  //Wenn Button 'start' keklckt wird Methode main ausführen
        master();
    }
    else if(source == reset){
        reset();
    }
}
}

导致此错误的原因是什么?对于德语代码中的注释感到抱歉,但如果您愿意,我可以将它们翻译成英语。

1 个答案:

答案 0 :(得分:0)

据我所知,&#34; AWT-EventQueue-0&#34;异常来自于您使用HashMap执行异步操作时。我会高度建议您将视图与模型分开!如有必要,还可以将控制器分开:

http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

你从执行停止的哪一行获得一个数字?因为这确实有助于确定问题从何处开始。你也可以对代码进行调试。我推荐Eclipse(Indigo),因为它内置了一个很好的调试器和许多其他整洁的东西。它生长在你身上!


TIPS

请尝试以下问题表单:

https://stackoverflow.com/questions/how-to-ask

因为当你留下3页根本不相关的代码时,它真的很难! (关于语言;我认为,germen中的注释和变量名称并不是那么难理解。我的意思是,我知道 你实例化了所以名字可能是&#34 ; asdf&#34;或&#34; foobar&#34;我所关心的一切。)

另外,请在类变量减速后将类的构造函数作为第一个方法;因为这样可以更容易地快速识别它。