为什么JFrame的更新,重新验证和重新绘制不会更新窗口?

时间:2019-01-24 06:00:00

标签: java swing graphics jframe

我正在尝试创建一个窗口框架以显示游戏窗口。我在JFrame类中扩展了GameWindow,并创建了两个方法: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();
    }

}

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

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()。我还尝试在drawBackgrounddrawGrid等的revalidateupdate中使用许多不同的组合和顺序。这些尝试似乎都不起作用。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

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

这不是定制绘画的工作方式。 getGraphics可以返回null,充其量不过是上一个绘制周期的快照,您对其绘制的任何内容都将在下一个绘制周期被擦除。

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

首先查看Performing Custom PaintingPainting in AWT and Swing,以更好地了解绘画的工作方式以及应该如何使用它。

您也可能希望通读Concurrency in SwingHow to Use Swing Timers,以获取有关创建“主循环”以恒定速率更新UI的想法,因为Swing是单个的线程且线程不安全