调用方法时Java Swing GUI冻结

调用方法时Java Swing GUI冻结,java,swing,user-interface,event-dispatch-thread,Java,Swing,User Interface,Event Dispatch Thread,我对Swing很陌生,但对Java不熟悉。不管怎样,我有一个象棋程序。下面是游戏循环类中重要的部分: public class game { static Board gameboard = new Board(); public static boolean waitstatus = true; public static char currentfaction = 'w'; public static boolean done = false; pub

我对Swing很陌生,但对Java不熟悉。不管怎样,我有一个象棋程序。下面是游戏循环类中重要的部分:

public class game {
    static Board gameboard = new Board();
    public static boolean waitstatus = true;
    public static char currentfaction = 'w';
    public static boolean done = false;
    public static boolean resigned = false;
    public static boolean wplayern = false;
    public static boolean bplayern = false;
    public static gui boardwindow = new gui();

    public static void main(String[] args) {
        gameboard.init(8, 8);
        gui.startGUI(boardwindow);
        runner();
        while (true) {
            //spin
        }

    }

    public static void runner() {
        done = false;
        resigned = false;
        wplayern = false;
        bplayern = false;
        boolean stalemate = false;

        while (true) {
            //The loop stuff    
        }
    }

    public static void resetGame() {
        if (!done) {
            System.out.println("Game's not finished yet!");
        } else {
            gameboard.restart();
            waitstatus = true;
            currentfaction = 'w';
            done = false;
            resigned = false;
            wplayern = false;
            bplayern = false;
            boardwindow.redraw();
            rerun();
        }
    }

    public static void rerun() {
        runner();
    }
}
这就是问题的代码。顺便说一句,boardwindow是一个gui对象,gameboard是我的内部逻辑gameboard数组,redraw()有gui重画(更新棋子的位置),restart()将内部逻辑板重新启动到原始的开始游戏状态。gui类是一个swing gui,它非常简单,工作也非常好。问题是,在游戏循环中,当它将死时,循环中断,runner()函数结束。然后,用户应该能够按下gui中的“新建游戏”按钮,以便在将死后重新启动游戏。新游戏按钮调用resetGame()。问题是当再次调用runner()时,gui窗口会冻结,我不知道为什么,我想这不需要多个线程。我还有其他按钮,它们调用我没有向您展示的函数,这些函数调用其他函数,比如restart()等等,它们没有问题,只有在调用runner()时才有问题

我知道我的其他代码在格式和惯例方面可能很糟糕,但请尽量把答案集中在主要问题上


谢谢

您应该设置一个条件来控制循环,而不是将其设置为true。在这里,即使从resetGame()重置游戏,循环仍会继续运行;或者使用break

public static void runner() {
    done = false;
    resigned = false;
    wplayern = false;
    bplayern = false;
    boolean stalemate = false;

    while (true) {
        //The loop stuff 
        if(newGameClicked == true){//just to literally make meaning
            break;
        }
    }
}

或者,作为一种快速修复方法,您只需调用boardwindow.dispose();然后创建一个新的gui实例(),并将其设置为visible(),以便在单击“新建游戏”按钮时重新启动游戏

您是否注意到控制台日志中有任何错误?我不确定您的情况,但Java Swing中冻结gui的几乎所有问题都与错误使用EDT有关:不要依赖
静态
,这不是一种跨对象通信机制,它会破坏你的脸控制台日志中没有错误,我意识到Swing中GUI冻结的大多数问题都来自错误处理线程,但我的问题与我见过的大多数其他示例不同。此时,我不想同时运行两个方法,即使在其他情况下,当我同时运行两个方法时,GUI也能很好地处理它。我使用静态是因为我不想为游戏创建单独的对象,因为它确实不需要单独的对象。不要阻止EDT(事件调度线程)。发生这种情况时,GUI将“冻结”。有关详细信息和修复方法,请参阅。while loop、in runner还是main?in runner。或者更好地了解如何将swing worker用于类似的事情。那么,我是否会将我的游戏类设置为swing worker,然后将我的runner()设置为后台do,并通过“新建游戏”按钮执行?听起来对吗?我还可以像现在一样在gui中调用所有其他助手函数吗?yh。runner()方法在后台处理在后台运行的循环时应与do相同。您的其他助手函数会更新变量,这样它们就不必存在,直接更新gui的函数除外。与当前runner()方法中的内容一样,在那里使用一个条件。看到我更新的ansoh了吗,你没看到吗,在while循环中,当它被将死时,我确实会断开。这几乎是如果(将死)打破;resetGame()将仅在runner()函数结束后运行。那么我还应该使用后台运行吗?