为什么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()
。我还尝试在 revalidate
、update
的 drawBackground
和 drawGrid
中使用许多不同的组合和顺序。这些尝试中的 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 是单线程且非线程安全
我正在尝试创建一个 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()
。我还尝试在 revalidate
、update
的 drawBackground
和 drawGrid
中使用许多不同的组合和顺序。这些尝试中的 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 是单线程且非线程安全