Java JFrame将不会关闭

Java JFrame将不会关闭,java,swing,jframe,Java,Swing,Jframe,目前,我正在制作康威的《生活游戏》的一个版本,以供自己娱乐。到目前为止,一切都进展顺利,但就在我测试一些最终部件时,我注意到了一个令人恼火的错误。代码的主体发生在while循环中,该循环由用户希望看到的游戏的“代数”控制。当这个循环执行时,JFrame的红色X拒绝响应,我不知道为什么会这样 我遇到这个问题的领域: public void run(int steps) throws InterruptedException{ int a = 0; do{ s

目前,我正在制作康威的《生活游戏》的一个版本,以供自己娱乐。到目前为止,一切都进展顺利,但就在我测试一些最终部件时,我注意到了一个令人恼火的错误。代码的主体发生在while循环中,该循环由用户希望看到的游戏的“代数”控制。当这个循环执行时,JFrame的红色X拒绝响应,我不知道为什么会这样

我遇到这个问题的领域:

public void run(int steps) throws InterruptedException{
    int a = 0;    
    do{
        step();
        myDisp.update(myDisp.getGraphics());
        Thread.sleep(delay);
        a++;
    }while(a < steps);
}    
public void run(int steps)抛出InterruptedException{
int a=0;
做{
步骤();
更新(myDisp.getGraphics());
睡眠(延迟);
a++;
}while(a
我建议您将此类处理放在单独的线程中。 只要将其保留在代码的主体中,只要循环在运行,Swing组件就不会响应任何用户交互

在中,您可以找到一些关于Swing应用程序中异步操作的良好实践。我想强调其中一个主题:

规则2:不要在事件线程上运行耗时的操作

我将不断重复这一点:Swing对所有GUI事件使用单个线程。如果您的事件处理程序正在通过网络上载一个多兆字节的文件,那么这些事件将被延迟,直到您完成为止。这条规则涉及到一个平衡行为:某些操作(例如获取文件大小)非常快,不会中断用户。然而,这并不是你漫不经心的理由,因为总有一天你的用户会得到一个文件的大小,这个文件驻留在一个有间歇性网络连接的文件服务器上


还显示了如何在Swing应用程序中处理长时间运行的任务的示例。您可能还想看看这个类。

我建议您将这种处理放在单独的线程中。 只要将其保留在代码的主体中,只要循环在运行,Swing组件就不会响应任何用户交互

在中,您可以找到一些关于Swing应用程序中异步操作的良好实践。我想强调其中一个主题:

规则2:不要在事件线程上运行耗时的操作

我将不断重复这一点:Swing对所有GUI事件使用单个线程。如果您的事件处理程序正在通过网络上载一个多兆字节的文件,那么这些事件将被延迟,直到您完成为止。这条规则涉及到一个平衡行为:某些操作(例如获取文件大小)非常快,不会中断用户。然而,这并不是你漫不经心的理由,因为总有一天你的用户会得到一个文件的大小,这个文件驻留在一个有间歇性网络连接的文件服务器上


还显示了如何在Swing应用程序中处理长时间运行的任务的示例。您可能还想看看这个类。

您的长时间运行的while循环在Swing事件调度线程或EDT上运行,键入它,并阻止所有Swing图形和用户交互。解决方案:为长时间运行的任务使用后台线程

请阅读:

有关此操作以及如何使用SwingWorker的更多详细信息。

您的长时间运行的while循环正在Swing事件调度线程或EDT上运行,键入它,并阻止所有Swing图形和用户交互。解决方案:为长时间运行的任务使用后台线程

请阅读:

有关此操作以及如何使用SwingWorker的更多详细信息。

默认情况下,while循环将在处理所有GUI操作的事件调度线程(EDT)上执行。由于这个原因,您不应该在EDT上执行长时间运行的任务-GUI将被锁定,因为您没有给它任何空闲时间来处理用户输入!但是,您必须执行与EDT上的GUI接触的任何代码。有一个特殊的方法,
SwingUtilities.invokeLater()
,可以实现这一点(获取Runnable并在EDT上调用它)


因此,在您的示例中,您将创建一个新线程并执行它,该线程将包含while循环,并且
myDisp.update()
调用将包装在上述方法中,以确保它仍然在EDT上。另一种(更简洁的)解决方案是使用,它为完成相同的任务提供了更好的界面。

默认情况下,while循环将在处理所有GUI操作的事件调度线程(EDT)上执行。由于这个原因,您不应该在EDT上执行长时间运行的任务-GUI将被锁定,因为您没有给它任何空闲时间来处理用户输入!但是,您必须执行与EDT上的GUI接触的任何代码。有一个特殊的方法,
SwingUtilities.invokeLater()
,可以实现这一点(获取Runnable并在EDT上调用它)


因此,在您的示例中,您将创建一个新线程并执行它,该线程将包含while循环,并且
myDisp.update()
调用将包装在上述方法中,以确保它仍然在EDT上。另一种(更简洁的)解决方案是使用a,它为完成相同的任务提供了更好的界面。

使用G.o.L.中所示的
定时器。
使用G.o.L.中所示的
定时器。