如何在事件发送线程中等待任务完成然后继续?

时间:2011-01-11 21:53:16

标签: java events swing swingworker

我有一个程序,一个游戏,用Swing制作GUI。

GUI由我自己的类组成,该类继承JFrame并持有带有CardLayout的JPanel,其中有多个JPanel作为卡片。

在其中一个面板上有一个Button,它启动游戏,游戏视图位于其中一个卡片上(视图对象有自己的继承JPanel的类,被添加到卡片的构造函数中) JFrame)。

现在是序幕:

我按下JButton,所以我跳转到Event Dispatch Thread来执行actionPerformed方法。

在这种方法中,我首先翻转到保存视图面板的卡片,然后实例化我将要玩的关卡和游戏引擎(根据关卡进行实例化)。然后我在视图对象上调用重绘(最终应该在应用程序窗口中绘制游戏)然后我调用我的游戏引擎对象来启动游戏循环。

我的问题是:

当我按下按钮时,游戏引擎开始正常运行(我从控制台中的打印件中看到它),但我的GUI冻结并且不会刷新以显示游戏视图。当我删除启动游戏循环的代码片段时,游戏视图正常显示在屏幕上,但没有任何动作,因为游戏循环尚未启动。

所以我已经扣除了这一点,因为在Java中,一切都不会按照它的编写顺序发生,游戏循环开始运行之前,已经完成了actionperformed方法中的其他操作。

以下是actionperformed方法的相关摘录 kortti =卡 kentta =等级 valikkopaneeli =具有cardlayout的面板 aloitusnappula =启动游戏的按钮 Peli =我继承JFrame

的类
if (e.getSource() == aloitusnappula) {

CardLayout kortti =(CardLayout)valikkopaneeli.getLayout();   Kentta kentta =新肯塔(“testikentta.txt”);   kortti.show(valikkopaneeli,“Peli”);   Peli.this.pack();   Peli.this.setVisible(真);   aloita(kentta);     }

以下是aloita(kentta)方法的片段:

public void aloita(Kentta kentta) {
 moottori = new Pelimoottori(Peli.this, kentta);
 nakyma.repaint();
 moottori.peliLooppi();
}

Pelimoottori = Game Engine类 nakyma =视图对象 peliLooppi()=游戏引擎类中启动游戏循环的方法

如果我从aloita方法删除moottori.peliLooppi()调用,游戏视图将正常显示。

我试图谷歌一些答案,我得到的最远的东西是以某种方式用SwingWorker做的,但不知怎的,它听起来不像是一个做我想要的好方法。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

我想你在edt里面开始你的引擎循环。如果是这样,那就太糟糕了。

从edt调用另一个线程,并从这个新线程管理你的引擎。对于gui更新,请回忆edt SwingUtilities.invokeLater

或者最好使用SwingWorker

要阅读一些关于秋季长期工作的优秀英语文档,请参阅Concurrency in Swing。不要使用Thread.sleep。

答案 1 :(得分:1)

  

当我删除启动游戏循环的代码片段时,游戏视图通常显示在屏幕上

听起来你可能正在使用带有Thread.sleep的while循环。

更好的方法是使用Swing Timer来安排游戏的“循环”。