Java swing JFrame用repaint出现闪烁的问题解决
这几天用swing写登录页面背景动图的时候发现一直会有闪烁(我的类是继承JFrame),就来搜原因后发现好像是因为repaint会调用update()方法中的清屏操作导致闪烁。
我当时看的是这个文章
于是按照他的方法重写了update方法,却发现问题没解决
public void paint(Graphics g) {
g.drawImage(skyImag.getImage(), skyX, skyY, null);
g.drawImage(groundImag, groundX, groundY, null);
g.drawImage(dinosaurImag.getImage(), dinoX, dinoY, null);
}
public void update(Graphics g) {
System.out.println("==1==");//这个是我拿来测试会不会调用的输出信息
if (groundImag == null) {
System.out.println("==2==");
//这句话从没输出过,说明了JFrame不会执行清屏操作,即groundImag != null,而Frame跟JPanel好像会执行清屏操作
groundImag = this.createImage(500, 500); // 新建一个图像缓存空间,这里图像大小为800*600,为了使这句话没问题,我把我的对象从ImagIcon对象改成Imag对象
}
Graphics gImage = groundImag.getGraphics(); // 把它的画笔拿过来,给gImage保存着
paint(gImage); // 将要画的东西画到图像缓存空间去
g.drawImage(groundImag, 0, 0, null); // 然后一次性显示出来
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
于是我又继续查文章,我发现没什么人用JFrame出现闪烁现象(我上次写飞机大战都没闪烁的说!),所以我查文章的时候放大范围,只要是Java swing编程出现闪烁的文章我都看一遍过去,终于让我看到这个大佬的文章
ydcun-双缓冲原理在awt和swing中实现消除闪烁的方法
就是他做的测试,让我知道原来在JFrame中repaint()的时候update()方法就没被调用到,JFrame消除闪烁是在update()中“直接调用了paint()函数而没有clearRect(),也就是清屏的方法,这里他试图不通过清屏来阻止闪烁的发生。”
所以到底是哪一步出问题了。。paint()方法已经被我重写了是不会有清屏操作的,问题感觉只能出在repaint()上,看了repaint()的代码好像也没发现类似清屏的代码,我能力有限,还在学习中,有大佬知道咋回事就求赐教一下QWQ,为了方便大家找repaint()有没有问题我就把代码贴上来吧
public void repaint(long tm, int x, int y, int width, int height) {
if (this.peer instanceof LightweightPeer) {
// Needs to be translated to parent coordinates since
// a parent native container provides the actual repaint
// services. Additionally, the request is restricted to
// the bounds of the component.
if (parent != null) {
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}
int pwidth = (width > this.width) ? this.width : width;
int pheight = (height > this.height) ? this.height : height;
if (pwidth <= 0 || pheight <= 0) {
return;
}
int px = this.x + x;
int py = this.y + y;
parent.repaint(tm, px, py, pwidth, pheight);
}
} else {
if (isVisible() && (this.peer != null) &&
(width > 0) && (height > 0)) {
PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE,
new Rectangle(x, y, width, height));
SunToolkit.postEvent(SunToolkit.targetToAppContext(this), e);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
接下来我继续说说我是怎么解决这个问题的,在ydcun大佬那边是有讲他的解决方案的,我还没试过(因为凌晨3点了都!我写完立马睡觉!),我当时(凌晨2点)就想着既然不会去调用update(),那我手动调用不就好了?
于是
public void paint(Graphics g) {
g.drawImage(skyImag.getImage(), skyX, skyY, null);
g.drawImage(groundImag, groundX, groundY, null);
g.drawImage(dinosaurImag.getImage(), dinoX, dinoY, null);
update(getGraphics());//跟JPanel不同,JFrame的repaint方法不会自动调用update方法。所以我这边直接让它调用了。
//而且参数不能用g得用getGraphics()
}
public void update(Graphics g) {
// System.out.println("==1==");
// if (groundImag == null) {
// //System.out.println("==2==");
// groundImag = this.createImage(500, 500); }// 新建一个图像缓存空间,这里图像大小为800*600
//Image对象在这边也会出问题
//报getGraphics() not valid for images created with createImage(producer)
//得改成BufferedImage,但是我懒得改,所以我直接全注释了
// Graphics gImage = groundImag.getGraphics(); // 把它的画笔拿过来,给gImage保存着
// paint(gImage); // 将要画的东西画到图像缓存空间去
// g.drawImage(groundImag, 0, 0, null); // 然后一次性显示出来
}
//为了实现动画效果我写了个计时器来repaint()
public void startTimeTask() {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
skyMove();
groundMove();
dinoMove();
repaint();
}
};
timer.schedule(task, 10, 20);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
对,我调用了一个什么东西都没有的update()方法,就解决了闪烁的问题。。。但是如果我调用系统的update()
public void update(Graphics g) {
paint(g);
}
- 1
- 2
- 3
就会更闪烁然后报错Java HotSpot(TM) 64-Bit Server VM warning: Potentially dangerous stack overflow in ReservedStackAccess annotated method sun.java2d.d3d.D3DBlitLoops.IsoBlit(Lsun/java2d/SurfaceData;Lsun/java2d/SurfaceData;Ljava/awt/image/BufferedImage;Ljava/awt/image/BufferedImageOp;Ljava/awt/Composite;Lsun/java2d/pipe/Region;Ljava/awt/geom/AffineTransform;IIIIIDDDDZ)V [1] Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError at java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:714) at java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:937) at java.base/java.util.concurrent.locks.ReentrantLock$Sync.lock(ReentrantLock.java:153) at java.base/java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:322) at java.desktop/sun.awt.SunToolkit.awtLock(SunToolkit.java:195) at java.desktop/sun.java2d.pipe.RenderQueue.lock(RenderQueue.java:112) at java.desktop/sun.java2d.d3d.D3DBlitLoops.IsoBlit(D3DBlitLoops.java:313) at java.desktop/sun.java2d.d3d.D3DTextureToSurfaceScale.Scale(D3DBlitLoops.java:768) at java.desktop/sun.java2d.pipe.DrawImage.scaleSurfaceData(DrawImage.java:1001) at java.desktop/sun.java2d.pipe.DrawImage.renderImageScale(DrawImage.java:647) at java.desktop/sun.java2d.pipe.DrawImage.tryCopyOrScale(DrawImage.java:319) at java.desktop/sun.java2d.pipe.DrawImage.transformImage(DrawImage.java:258) at java.desktop/sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:76) at java.desktop/sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:1027) at java.desktop/sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:3425) at java.desktop/sun.awt.image.ImageRepresentation.drawToBufImage(ImageRepresentation.java:813) at java.desktop/sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:1034) at java.desktop/sun.java2d.pipe.ValidatePipe.copyImage(ValidatePipe.java:186) at java.desktop/sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:3425) at java.desktop/sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:3401) at cn.zhetech.BackImag.paint(UserLogin2.java:276) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283) at java.desktop/javax.swing.JFrame.update(JFrame.java:469) at cn.zhetech.BackImag.paint(UserLogin2.java:283)
窗口也关不掉,只能从控制台强制停止运行。。。
等日后有大佬评论教我了或者我自己学习到了再补充一下这个原因,碎觉,溜了||ヽ( ̄▽ ̄)ノミ|Ю,狗命要紧
如果文章有帮到你或者给你提供了思路,那就送我个赞呗(◦˙▽˙◦),不然我就默认每个浏览的都是想点然后忘了(自欺欺人,bushi)
原文章:https://blog.csdn.net/qq_38677092/article/details/112092928
Java swing JFrame用repaint出现闪烁的问题解决的更多相关文章
- Java Swing JFrame实现全屏--无标题,无边框
实现方式一: import java.awt.Dimension; import java.awt.Toolkit; import javax.swing.JFrame; public class T ...
- Java Swing 托盘闪烁Demo实例
桌面程序当中,托盘显示是一个常用的功能. C#的WinForm程序要实现托盘是挺轻松的,而Java Swing要实现这个功能虽然也不难, 但是由于Java Swing开发者或许没有C#多,所以看到很多 ...
- Java Swing paint repaint update 方法的关系
Java Swing paint repaint update 方法的关系: 参考:http://blog.csdn.net/xiaoliangmeiny/article/details/691665 ...
- Java Swing类 例子代码:将子类继承JFrame 并且接口按键监听ActionLisetener (将内容直接添加到JFrame不创建Contaniner)
package rom; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import ...
- Java Swing学习笔记——创建JFrame
创建显示一个空JFrame import javax.swing.JFrame; public class JFrameDemo extends JFrame{ public JFrameDemo() ...
- java swing 双人五子棋源代码
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Toolkit; impo ...
- java swing模仿随机频谱
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Grap ...
- Java Swing jpanel paint方法执行两次的问题
Java Swing jpanel paint方法执行两次的问题: 在其他环境下执行了两次,自己测试怎么都是执行了一次,记录一下这个问题:需要后继工作: 可能是进行各种参数设置的时候导致了paint方 ...
- java Swing 图片缓冲机制
java Swing 图片缓冲机制: 参考:http://jorneyr.iteye.com/blog/868858#comments package util; import java.awt.ge ...
随机推荐
- web php wrong nginx config
web php wrong nginx config 目录 web php wrong nginx config 题目描述 解题过程 信息收集 robots.txt hint.php Hack.php ...
- Day007 数组的声明与创建
数组 数组的定义 数组是相同类型数据的有序集合. 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成. 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们. 数组声 ...
- No input file specified.问题的解决
问题描述:apache配置网站出现问题"No input file specified." 解决1: 打开.htaccess 在RewriteRule 后面的index.php教程 ...
- Java筑基 - JNI到底是个啥
在前面介绍Unsafe的文章中,简单的提到了java中的本地方法(Native Method),它可以通过JNI(Java Native Interface)调用其他语言中的函数来实现一些相对底层的功 ...
- 如何利用CRM系统打通营销全渠道?
企业经常通过不同渠道组织各种形式的营销推广,可惜,这些营销推广的效果往往差强人意. 相关研究表明,很多营销推广不理想的主要原因是不同营销渠道之间没有打通数据,不清楚每个营销渠道或营销策划的投入产出.推 ...
- Zoho:SaaS行业的“紫色奶牛”
以下文章来源于:中国软件网,作者王锦宝 蓝天白云的映衬下,一群黑白相间的奶牛在绿草场自由玩耍,这种田园牧歌场景看久了,总会引起审美疲劳.假如突然出现一头紫色奶牛,你肯定会眼前一亮,把所有注意力集中到紫 ...
- [DB] CDH集群规划
配置 三台机器:node01.node02.node03 node01:6G+60G node02:2G+40G node03:2G+40G 组件 Cloudera Managerment Servi ...
- QT windows 应用程序 exe ,设置详细信息并解决中文乱码问题
原博主:https://blog.csdn.net/xiezhongyuan07/article/details/87691490 1.新创建一个.rc文件,随意命名,例如叫app.rc 并编辑 1 ...
- Linux ll查看文件属性详解-软硬链接详解
Linux文件属性及类型 [root@localhost ~]# ll anaconda-ks.cfg 文件类型 权限 硬连接数 文件的大小 文件的创建,修改时间 - rw-------. 1 roo ...
- python基础之psutil模块和发邮件(smtplib和yagmail)
除了内建的模块外,Python还有大量的第三方模块. 基本上,所有的第三方模块都会在PyPI - the Python Package Index上注册,只要找到对应的模块名字,即可用pip安装. 此 ...