Java swing InvokeLater 不会立即重新绘制

问题描述 投票:0回答:1

我正在开发一款游戏。当尝试在“主”线程中使用游戏循环进行可视化时,仅很少调用

paintComponent
方法。我读过许多其他类似的问题,但似乎没有一个对我有帮助。可能是我仍然没有正确理解一切。 我知道这仍然是 EDT 的一个问题,因为当我移动鼠标或按下按键时,游戏会流畅地呈现。 谢谢!

这是我的缩短代码:

public class Game implements Runnable {
    
    private GamePanel  gamePanel;
    private Thread gameThread;
    private final int FPS_SET = 120;

    
    public Game() {
        gamePanel  = new GamePanel();
        gamePanel.requestFocus();
        
        gameThread = new Thread(this);
        gameThread.start();
    }

    @Override
    public void run() {
        
        double timePerFrame = 1000000000.0 / FPS_SET ; 
        long lastFrame = System.nanoTime();
        long now       = lastFrame;
        
        
        while(true) {
            
            now = System.nanoTime();
            if (now - lastFrame >= timePerFrame) {
                // Updates Scenery
                _reDraw();
                lastFrame = now;
            }
            
        }
    }
    
    private void _reDraw() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                gamePanel.repaint();
            }
        });
    }
    
}

public class GamePanel extends JPanel {
    // ...
    public void paintComponent(Graphics g) {
    // draw
    }
}
java swing paintcomponent invokelater
1个回答
0
投票

来自

repaint()
文档:

如果该组件是轻量级组件,则此方法会导致 尽快调用该组件的

paint
方法。否则, 此方法会立即调用该组件的 update
 方法 
可能

尽快并不意味着每次你打电话repaint()

paint
都会被叫到。您拨打 
repaint()
 的速度可能比工具包能够回答您的请求的速度还要快。

再次来自文档:

应用程序触发绘画

在应用程序触发的绘画操作中,组件决定 它需要更新其内容,因为其内部状态已 改变了。 (例如,按钮检测到鼠标按钮已被按下 按下并确定需要绘制一个“按下”的按钮 视觉)。

和:

绘画方法

无论如何触发绘制请求,AWT 都会使用 绘画的“回调”机制,这个机制是一样的 重量级和轻量级组件。这意味着一个程序 应该将组件的渲染代码放在特定的 重写的方法,并且工具包将在它被覆盖时调用此方法 是时候画画了

.

工具包会在绘制时调用此方法

是重要的部分。 和:

应用程序触发绘画

应用程序触发的绘画操作如下:

程序确定组件的一部分或全部需要 重新绘制以响应某些内部状态变化。

程序在组件上调用 repaint(),该组件注册了一个 该组件需要向 AWT 发出异步请求 重新粉刷了。

AWT 导致事件调度线程调用 update() 组件。

注意:如果在组件上多次调用 repaint() 初始重绘请求已处理,多个请求可能是 折叠成对 update() 的单个调用。算法为 确定何时应该折叠多个请求是 取决于实施。如果多个请求被折叠, 生成的更新矩形将等于 折叠请求中包含的矩形。

真正的绘画不在你这边,而是在主机UI上 边。可能有很多事件不允许这幅画被拍摄 地点(你的窗户不可见,有更紧急的事情要做, 等)。

至少,我们知道对于

repaint

中将会有

paint
未来,但多个
repaint
可能会导致单个
paint
    

© www.soinside.com 2019 - 2024. All rights reserved.