java - 游戏循环期间无法绘制到 JPanel

标签 java swing jpanel

我试图在游戏循环期间扩展 JPanel 的 MapPanel 上进行绘制,但失败了。但是,如果我在循环之外执行此操作,它会成功绘制。这是我的相关代码:

MenuPanel.java:

public void actionPerformed(ActionEvent e) {

    JButton pushedButton =(JButton) e.getSource();

    if(pushedButton == play)
        guiManager.setGamePanelVisible(true);
    else if(pushedButton == settings)
        guiManager.setSettingsPanelVisible();
    else if(pushedButton == credits)
        guiManager.setCreditsPanelVisible();
    else if(pushedButton == highScores)
        guiManager.setHighScoresPanelVisible();
    else if(pushedButton == help)
        guiManager.setHelpPanelVisible();

}

GUIManager.java:

...
    public void setGamePanelVisible(boolean gameStarted){
        GamePanel gp = new GamePanel(this);
        setContentPane(gp);
        gp.initiate();
    }
...

GamePanel.java

public void initiate(){
   this.gm = new GameManager(this);  // constructs the game manager and triggers the game loop 
}

GameManager.java

public GameManager(GamePanel gp) {
    this.gp = gp;
    this.run();
}

private void run(){
    while(running){
        draw();
        try{
            sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("Interrupted at GameManager.java");
        }
    }

我的预测是,游戏循环在 MenuPanel 仍然可见时开始(在 setGamePanelVisible 方法中),并且由于它永远不会退出该方法,MenuPanel 保持可见,从而导致这种情况。然而,我可能是错的。即使这是问题,我也想不出任何解决办法。也许我应该将按钮监听器移到另一个类?预先感谢您!

最佳答案

您正在阻止事件调度线程,这会阻止 UI 更新。 EDT 负责处理重绘请求等。您的游戏循环正在 EDT 的上下文中运行...

actionPerformed 在 EDT 中执行,它调用 setGamePanelVisible,后者调用 GameManager,后者调用 run,其中 block ...

看看Concurrency in Swing了解更多详情。

Swing 不是线程安全的,因此您不能简单地启动一个新的 Thread 并希望这能解决所有问题,您需要确保对 UI 的所有更新(包括对以下信息的更新) UI 可能需要)并在 EDT 上下文中制作

更简单的解决方案之一是仅使用 Swing Timer,它允许您安排在 EDT 上下文中执行的定期、定时更新。请参阅How to use Swing Timers了解更多详情

关于java - 游戏循环期间无法绘制到 JPanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27593900/

相关文章:

java - Netbeans - 运行特定的 Maven 集成测试

java - FlowLayout添加在之前的组件下

java - Java 运算符 && 和 || 的逻辑

java - 在 alertDialog 中显示 Recyclerview

java - Java中utf8字符串及其字节的编码和解码

java - Swing - 等待渲染完成

java - 如何在 GridLayout 中管理多个菜单?

java - 将 JTable 添加到 LayeredPane

Java Swings 选择选项卡

java - 更改 JPanel 的实例