为什么JFrame 的update、revalidate 和repaint 不更新window?

Why do JFrame's update, revalidate, and repaint not update the window?

我正在尝试创建一个 window 框架来显示游戏 window。我在我的 GameWindow class 中扩展了 JFrame 并创建了两个方法:drawBackground,它用一个实心矩形填充屏幕,以及 drawGrid,它绘制连续的线条使用 for 循环制作网格。这是我的代码。

public class GameWindow extends JFrame {

    // instance variables, etc.

    public GameWindow(int width, Color bgColor) {
        super();

        // ...

        this.setVisible(true);
    }

    public void drawBackground() {
        Graphics g = this.getGraphics();

        g.setColor(bgColor);
        g.fillRect(0, 0, this.getWidth(), this.getWidth());

        // I suspect that the problem is here...
        this.update(g);
        this.revalidate();
        this.repaint();
        g.dispose();
    }

    public void drawGrid() {
        Graphics g = this.getGraphics();

        g.setColor(Color.BLACK);

        for (int i = tileWidth; i < TILE_COUNT * tileWidth; i += tileWidth) {

            g.drawLine(0, i * tileWidth, this.getWidth(), i * tileWidth);
            g.drawLine(i * tileWidth, 0, i * tileWidth, this.getHeight());

        }

        // ... and here.
        this.update(g);
        this.revalidate();
        this.repaint();
        g.dispose();
    }

}

但是,当我尝试在这样的程序中测试这个 class 时:

public class Main {
    public static void main(String[] args) {
        GameWindow game = new GameWindow(700);

        game.drawBackground();
        game.drawGrid();
    }
}

框架出现在屏幕上但仍然空白;既没有绘制背景也没有绘制网格。我试过 Graphics g = this.getGraphics()this.getContentPane().getGraphics()。我还尝试在 revalidateupdatedrawBackgrounddrawGrid 中使用许多不同的组合和顺序。这些尝试中的 None 似乎有效。我该如何解决这个问题?

嗯,Graphics g = this.getGraphics(); 将是一个很好的起点。由于 repaint 只是安排了与 RepaintManager 一起发生的绘制过程,所有使用 getGraphics 的代码都将被忽略。

这不是自定义绘画的工作方式。 getGraphics 可以 return null 并且充其量只是上一个绘制周期的快照,您在其上绘制的任何内容都将在下一个绘制周期中被清除。

此外,不要 dispose 您未创建的 Graphics 上下文,在某些系统上,这会阻止其他组件使用它

首先查看 Performing Custom Painting and Painting in AWT and Swing 以更好地了解绘画的工作原理以及您应该如何使用它。

您可能还想通读 Concurrency in Swing and How to Use Swing Timers,了解有关创建 "main loop" 以恒定速率更新 UI 的想法,因为 Swing 是单线程且非线程安全