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

发布于 2024-10-11 16:08:01 字数 1436 浏览 3 评论 0 原文

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

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

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

现在是序言:

我按下了 JButton,因此我跳转到事件调度线程来执行 actionPerformed 方法。

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

我的问题是:

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

所以我推断,因为在 Java 中,一切都不会按照编写的顺序发生,所以游戏循环在 actionperformed 方法中的其他操作完成之前就开始运行。

这是 actionperformed 方法的相关片段 kortti = 卡 肯塔 = 水平 valikkopaneeli = 有卡片布局的面板 aloitusnappula = 开始游戏的按钮 Peli = 我创建的继承 JFrame CardLayout 的类

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

kortti = (CardLayout)valikkopaneeli.getLayout(); Kentta kentta = new Kentta("testikentta.txt"); kortti.show(valikkopaneeli, "Peli"); Peli.this.pack(); Peli.this.setVisible(true); 阿洛伊塔(肯塔); 这

是 aloita(kentta) 方法的片段:

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

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

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

我试图用谷歌搜索一些答案,我得到的最远的答案是用 SwingWorker 来完成它,但不知怎的,这听起来不像是做我想做的事情的好方法。

有什么建议吗?

I have a program, a game, with GUI made with Swing.

The GUI is comprised of my own class which inherits JFrame and holds a JPanel with CardLayout, which has multiple JPanels as cards.

On one of these panels there is a Button which starts the game and the game view is located on one of the cards (the view object, which has its own class which inherits JPanel, is added to the card in the constructor of the JFrame).

Now the prologue:

I press the JButton, so I jump to the Event Dispatch Thread to execute the actionPerformed method.

In this method I first flip to the card that holds the view panel, then instantiate the level i'm going to play and the game engine (which is instantiated according to the level). Then i call repaint on the view object (which should end up with the game being painted in the apllication window) and THEN I call my game engine object to start the game loop.

My problem is:

When i press the button, the game engine begins to run properly (i see it from the prints in console), but my GUI freezes and won't refresh to show the game view. When i remove the snippet of code that starts the game loop, the game view shows on the screen normally, nothing moves though, because the game loop hasn't been started.

So I have deducted that, because in Java everything doesn't happen in the order it is written, the game loop begins to run BEFORE the other operations in the actionperformed method have been completed.

Here is the relevant snippet from the actionperformed method
kortti = card
kentta = level
valikkopaneeli = the panel that has cardlayout
aloitusnappula = the button that starts the game
Peli = the class i made that inherits JFrame

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

CardLayout kortti = (CardLayout)valikkopaneeli.getLayout();
Kentta kentta = new Kentta("testikentta.txt");
kortti.show(valikkopaneeli, "Peli");
Peli.this.pack();
Peli.this.setVisible(true);
aloita(kentta);
}

and here is a snippet of the aloita(kentta) method:

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

where Pelimoottori = the Game Engine class
nakyma = the view object
peliLooppi() = the method in the Game Engine class that starts the Game Loop

If I'd remove moottori.peliLooppi() call from the aloita method, the game view would show normally.

I tried to google some answers and the farthest I've got is somehow doing it with SwingWorker, but somehow it doesn't sound like a good way of doing what i want.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

可是我不能没有你 2024-10-18 16:08:01

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

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

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

When i remove the snippet of code that starts the game loop, the game view shows on the screen normally

Sounds like you are probably using a while loop with a Thread.sleep.

A better approach is to use a Swing Timer to schedule the "looping" of your game.

夜深人未静 2024-10-18 16:08:01

我想你在 edt 内启动你的引擎循环。如果是这样,那就糟糕了。

从 edt 调用另一个线程,并从这个新线程管理您的引擎。对于 GUI 更新,请使用 SwingUtilities.invokeLater

或者最好使用 SwingWorker

要阅读一些有关 swing 中长期工作的优秀英语文档,请参阅 Concurrency in摇摆。不要使用 Thread.sleep。

I suppose you start your engine loop inside the edt. If so, it's BAD.

From the edt call another thread, and manage your engine from this new thread. For gui update, recall edt with SwingUtilities.invokeLater.

Or best, use a SwingWorker.

To read some good english language documentation about long term job in swing, see Concurrency in Swing. Don't use Thread.sleep.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文