函数调用阻止GUI在java中更新

函数调用阻止GUI在java中更新,java,multithreading,swing,loops,Java,Multithreading,Swing,Loops,我目前正在用java实现一个quoridor游戏,使用AI游戏玩算法。在“人类”点击进行移动后,gui需要更新,AI开始思考。 我在面板里有这样的东西: public void mouseClicked(MouseEvent e) { gameBoard.executeMove( movePawn ); repaint(); gameboard.callAi(); } 调用funtcion callAi()后,我进入了一个耗费太多时间来

我目前正在用java实现一个quoridor游戏,使用AI游戏玩算法。在“人类”点击进行移动后,gui需要更新,AI开始思考。 我在面板里有这样的东西:

public void mouseClicked(MouseEvent e)
    {
       gameBoard.executeMove( movePawn );
       repaint();
       gameboard.callAi();
    }
调用funtcion callAi()后,我进入了一个耗费太多时间来完成的循环。另一方面,gui冻结,它不更新,甚至在AI“开始思考”之前调用了重新绘制方法。在我给人工智能打电话之前,我试着延迟一下,但它不起作用。我写了这封信:

try
{ TimeUnit.MILLISECONDS.sleep(5);}
catch{}

我能做些什么来解决这个问题?也许这与线程有关,但我对Java中的线程不太友好

我强烈建议阅读EDT(事件调度线程)是什么

其中一个答案很好地解释了这一点。Quick TLDR:基本上,GUI冻结的原因之一是因为EDT中包含的AI方法(我不能肯定gameBoard.executeMove(…)方法)。EDT用于更新GUi,而不是运行占用大量计算时间的方法

将游戏逻辑代码从GUI中取出,放入主线程/新线程(而不是EDT)。如果您确实需要EDT中的游戏逻辑,那么在EDT中创建一个新线程,让它进行游戏计算,最后使用Swing.Utilties.invokeLater(…)方法更新GUI

也许这与线程有关,但我对Java中的线程不太友好


在制作游戏时,一定要熟悉线程,特别是EDT。

我强烈建议您阅读EDT(事件调度线程)是什么

其中一个答案很好地解释了这一点。Quick TLDR:基本上,GUI冻结的原因之一是因为EDT中包含的AI方法(我不能肯定gameBoard.executeMove(…)方法)。EDT用于更新GUi,而不是运行占用大量计算时间的方法

将游戏逻辑代码从GUI中取出,放入主线程/新线程(而不是EDT)。如果您确实需要EDT中的游戏逻辑,那么在EDT中创建一个新线程,让它进行游戏计算,最后使用Swing.Utilties.invokeLater(…)方法更新GUI

也许这与线程有关,但我对Java中的线程不太友好


在制作游戏时,一定要熟悉线程,特别是EDT。

你应该使用
SwingWorker
来完成这方面的人工智能工作。所有的更新和处理都发生在Swing中的一个线程上,因此如果您阻止它,那么您将冻结UI


您应该使用
SwingWorker
来完成此操作的AI工作。所有的更新和处理都发生在Swing中的一个线程上,因此如果您阻止它,那么您将冻结UI


@VasylLyashkevych
updateUI
不用于生成UI状态已更改且应更新的通知,而是,若要指示组件Look and Feel委托已更改,并且组件应重新安装更新,则永远不需要调用此方法,除非您试图在运行时更改Look and Feel,否则它甚至无法解决OP所面临的问题—您已被单线程绊倒Swing的本质,基本上是阻塞负责处理绘制事件的线程。有关更多详细信息和可能的错误,请参阅solutions@JoanPlepi当阻止负责处理绘制请求的线程时,GUI如何更新?假设
repaint
执行实际的绘制,当它不执行时,它只向
RepaintManager
发出请求,然后该管理器确定需要绘制的内容,并将绘制事件安排到事件队列中,然后由事件调度线程处理,您就是blocking@JoanPlepi我认为你需要去看看,以更好地了解如何画实际工程。。。加上前面的链接Imentioned@JoanPlepi按照Swing中并发链接中的建议,使用
SwingWorker
执行长时间运行的操作,使用它的功能更新UI安全-因为Swing也不是线程safe@VasylLyashkevych
updateUI
不用于生成UI状态已更改且应更新的通知,而是,若要指示组件Look and Feel委托已更改,并且组件应重新安装更新,则永远不需要调用此方法,除非您试图在运行时更改Look and Feel,否则它甚至无法解决OP所面临的问题—您已被单线程绊倒Swing的本质,基本上是阻塞负责处理绘制事件的线程。有关更多详细信息和可能的错误,请参阅solutions@JoanPlepi当阻止负责处理绘制请求的线程时,GUI如何更新?假设
repaint
执行实际的绘制,当它不执行时,它只向
RepaintManager
发出请求,然后该管理器确定需要绘制的内容,并将绘制事件安排到事件队列中,然后由事件调度线程处理,您就是blocking@JoanPlepi我认为你需要去看看,以更好地了解如何画实际工程。。。加上前面的链接Imentioned@JoanPlepi按照Swing中并发链接中的建议,使用
SwingWorker
执行长时间运行的操作,然后使用其功能更新UI safey,因为Swing也不是线程安全的