我知道在swing中你应该使用重绘来重绘面板,但是我开始制作游戏,并且已经读到重绘在时间上是不可靠的。所以我试着制定一个策略,创建一个bufferedimage,把我需要的所有东西都画到这个objects图形对象上,然后用drawimage方法把这个图像画到我的jpanel上。
我打电话给dispose让面板重新渲染,但它只是工作的一部分时间。下面只是一个例子。如果你继续运行这个程序,BuffereImage只会被绘制3/10次。有人能给我解释一下吗?
public class TestMain {
public static void main(String[] args) throws InterruptedException {
JFrame jf = new JFrame();
MyPanel mp = new MyPanel();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLocation(50, 500);
jf.add(mp);
jf.pack();
jf.setVisible(true);
mp.draw();
}
}
public class MyPanel extends JPanel {
private static final long serialVersionUID = 1L;
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d;
public MyPanel() {
super();
setPreferredSize(new Dimension(300, 300));
}
public void draw() {
System.out.println("In draw");
g2d = (Graphics2D) img.getGraphics();
g2d.drawString("Test", 10, 10);
Graphics g = getGraphics();
g.drawImage(img, 0, 0, this);
g.dispose();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("In paintComponent");
}
}
在幕后,我在和什么抗争,而这些往往阻碍了抽签。我意识到,调整窗口大小等将调用重绘和覆盖我的绘图,但当我不这样做,它应该显示每次,不是吗?
编辑:有趣。。。如果我把draw方法 Package 成一个连续的while循环,它就会“工作”。但这不能回答我的问题。我不需要经常回忆这个方法来给人一种画画正常的错觉。
2条答案
按热度按时间xj3cbfub1#
不应使用getgraphics()方法进行绘制。使用getgraphics所做的任何代码都只是临时的,每当swing确定组件需要重新绘制时,这些代码都将丢失,这很可能发生在这里。
重写类的getpreferredsize()方法并调用super.paintcomponent(),然后添加system.out.println(…)语句。另外,将system.out.println(…)语句添加到draw()方法以查看代码的执行顺序。
我打电话给dispose让面板重新渲染,
这不会导致面板渲染,它只是释放分配给图形对象的资源。您需要调用draw()方法来不断地重新绘制。
这与使用计时器不断地重新绘制()组件基本相同。不同之处在于draw()可能会立即发生,但重新绘制可能需要几毫秒的时间。但是由于repaint()每次间隔保持不变都需要几毫秒的时间,因此repaint不会只绘制一次,下次再等待一秒钟。
z4bn682m2#
我修复了您的代码并获得了以下gui:
在缓冲图像上绘制时,您必须执行所有操作。你必须画背景和前景。
在jpanel的paintcomponent方法中绘制缓冲图像时,所要做的就是绘制图像。
swing paintcomponent方法在java版本6、7和8中足够快,可以在不闪烁的情况下进行绘制。我做过动画片,上万行没有闪烁。
必须通过调用swingutilities invokelater方法在事件调度线程上启动swing应用程序。
这是你修改过的代码。