关于双缓冲解决闪烁现象出现的问题,求助!!!

disalong 2011-12-02 02:24:17
前言:刚接触双缓冲机制,有个问题我现在的能力无法解决,所以走上csdn求助,望各位大哥不吝赐教。
问题描述:我所认知的观点是1.repaint()方法能主动调用paint()方法从而使图像重画;2.repaint()方法调用的频率过快会使得paint()方法没来得及执行完毕而被下一个repaint()方法调用的paint()方法冲掉而产生闪烁现象,所以要引进双缓冲机制;3.双缓冲是指repaint()方法在调用paint()方法前先(或者同时)调用update()方法使图像先画在虚拟图像上在与电脑屏幕融合;
问题:当我用Eclipse重写update()方法(自动引入)的时候,出来的update()方法体中会自动执行“super.update();”语句,如下代码。问题就出现在这里,当我按照常规程序在虚拟图像offScreen上画完所需图形,用drawImage()方法把虚拟图像融合到电脑屏幕中后,闪烁现象依然,但是当我注掉“super.update();”这句代码后问题解决,我搞不清楚的是,这句代码为何要出现,我印象中只有子类实例化的时候才会先执行父类的构造方法,那么为什么子类重写父类方法的时候也要先让父类对象调用一下要重写的方法呢?就算是执行了“super.update();”,这句话又是怎样影响到双缓冲的进行的呢?

public void update(Graphics g) {
super.update(g);//自动产生,注掉后,闪烁现象消失。
if (offScreen == null){
offScreen = this.createImage(800,600);
}
Graphics goffScreen = offScreen.getGraphics();
Color c = goffScreen.getColor();
goffScreen.setColor(Color.green);
goffScreen.fillRect(0,0,800,600);
goffScreen.setColor(c);
paint(goffScreen);
g.drawImage(offScreen,0,0,null);

}
...全文
265 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
dracularking 2011-12-05
  • 打赏
  • 举报
回复
The update method of Component calls this component's paint method to redraw this component. This method is commonly overridden by subclasses which need to do additional work in response to a call to repaint. Subclasses of Component that override this method should either call super.update(g), or call paint(g) directly from their update method.

dracularking 2011-12-05
  • 打赏
  • 举报
回复
我想可能是这样的,update最终也还是调用paint来绘制
如果super.update后又有repaint,paint过于频繁导致来不及完整重绘而闪屏

privateTia 2011-12-05
  • 打赏
  • 举报
回复
public void update(Graphics g) {
super.update(g);//自动产生,注掉后,闪烁现象消失。
if(offScreenImage == null) {
offScreenImage = this.createImage(800, 600);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(Color.GREEN);
gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
gOffScreen.setColor(c);
paint(gOffScreen);
g.drawImage(offScreenImage, 0, 0, null);
}

public void paint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.RED);
g.fillOval(x, y, 30, 30);
g.setColor(c);

y += 5;
}

「已注销」 2011-12-04
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 privatetia 的回复:]
我只是想知道update()中的”super.update(g);"这句话干嘛来着···

super.update 就是 调用 父类的update 父类中的 update 就是调用paint (原因 为啥要 委托给 update ? 就是 为了线程安全 与 优化绘制)

还有 就是 J中也要 根据情况 进行 paint复写的 毕竟有些时候 我们不想让 paint 过多干预我们的结果 这……
[/Quote]
大哥,能告诉我为什么注掉“super.update(g);"闪烁现象就消失了呢。
lfp001 2011-12-04
  • 打赏
  • 举报
回复
参考
http://topic.csdn.net/u/20111204/13/85dc66f8-8895-456d-9f00-49e9e119eacd.html?89281
2楼
「已注销」 2011-12-03
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 inhibitory 的回复:]
楼主看的书应该是比较老的,如果使用Swing,绘制图形还是在paintComponent里做好一些
[/Quote]

恩,是老的,在学基础,谢谢这位大哥
Inhibitory 2011-12-03
  • 打赏
  • 举报
回复
楼主看的书应该是比较老的,如果使用Swing,绘制图形还是在paintComponent里做好一些
「已注销」 2011-12-03
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 privatetia 的回复:]
仔细看文档
只是调用 paint(g)。重写此方法,以防止不必要的调用清除背景

注意看!! 以防止 不必要的清除屏幕! 而你 又自己 去 调用 super.update 去清除屏幕 呼``` 当然就会 有闪屏的现象 是你 自己清除 屏幕 然后 又画你的内容
[/Quote]

你好,源码是这样子的:启动一个子线程-》在run()方法里不断repaint()-》重写panint()与update()-》因为我要做一个图片的动态移动,所以必须每次调用update()方法都要重刷背景再画图片,paint()的调用只是想用已重写的paint()方法的画图模式在虚拟画面上作图以减少不必要的操作,这些都不影响虚拟图片draw的过程,我只是想知道update()中的”super.update(g);"这句话干嘛来着···
private class PaintThread implements Runnable {
public void run() {
while(true) {
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


public void paint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.RED);
g.fillOval(x, y, 30, 30);
g.setColor(c);

y += 5;
}

public void update(Graphics g) {
super.update(g);//自动产生,注掉后,闪烁现象消失。
if(offScreenImage == null) {
offScreenImage = this.createImage(800, 600);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(Color.GREEN);
gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
gOffScreen.setColor(c);
paint(gOffScreen);
g.drawImage(offScreenImage, 0, 0, null);
}
privateTia 2011-12-03
  • 打赏
  • 举报
回复


我只是想知道update()中的”super.update(g);"这句话干嘛来着···

super.update 就是 调用 父类的update 父类中的 update 就是调用paint (原因 为啥要 委托给 update ? 就是 为了线程安全 与 优化绘制)

还有 就是 J中也要 根据情况 进行 paint复写的 毕竟有些时候 我们不想让 paint 过多干预我们的结果 这个 跟 新老书没什么关系 应该算常识才对 (写书作者 水平足够高的话 反正 我学 swing 和 awt 也不算新手了 但是 具体实现细节还是不知道的 囧 因为看不懂 源码) 虽然 有些时候 复写那个 结果都一样 但是 还是要知道差别的

privateTia 2011-12-02
  • 打赏
  • 举报
回复
Sorry Sorry
我发那么多边 不是我的本意`!! 靠靠靠 是浏览器 自己的毛病 我郁闷 !!!!
lfp001 2011-12-02
  • 打赏
  • 举报
回复
你对双缓冲的理解不太对。你的代码不能实现双缓冲。

另外,如果需要重载update,那么同时要重载paint。

JDK API 上面有详细的说明。
privateTia 2011-12-02
  • 打赏
  • 举报
回复

仔细看文档
只是调用 paint(g)。重写此方法,以防止不必要的调用清除背景

注意看!! 以防止 不必要的清除屏幕! 而你 又自己 去 调用 super.update 去清除屏幕 呼``` 当然就会 有闪屏的现象 是你 自己清除 屏幕 然后 又画你的内容
privateTia 2011-12-02
  • 打赏
  • 举报
回复

仔细看文档
只是调用 paint(g)。重写此方法,以防止不必要的调用清除背景

注意看!! 以防止 不必要的清除屏幕! 而你 又自己 去 调用 super.update 去清除屏幕 呼``` 当然就会 有闪屏的现象 是你 自己清除 屏幕 然后 又画你的内容
privateTia 2011-12-02
  • 打赏
  • 举报
回复

仔细看文档
只是调用 paint(g)。重写此方法,以防止不必要的调用清除背景

注意看!! 以防止 不必要的清除屏幕! 而你 又自己 去 调用 super.update 去清除屏幕 呼``` 当然就会 有闪屏的现象 是你 自己清除 屏幕 然后 又画你的内容
「已注销」 2011-12-02
  • 打赏
  • 举报
回复
先感谢楼上的回答,关于draw以及如何draw的做法可能会因需求而不同,我只是认为“super.update()”必然影响了虚拟图画draw到电脑屏幕的过程,才会使得闪烁现象依然,不解的是内部是如何影响的
黎某人 2011-12-02
  • 打赏
  • 举报
回复
不好意思没看清楚代码,我都没用过update ,直接用线程定时去draw的,这样可以自己控制绘图帧数
黎某人 2011-12-02
  • 打赏
  • 举报
回复
建立一张空白的image对象,然后这个image获取graphics 然后把所有的东西都画到这个image上面,然后 窗体draw这个image。懂了吗

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧