Java swing JFrame用repaint()出现闪烁的问题解决
本文最后更新于:2023年3月23日 上午
这几天用swing写登录页面背景动图的时候发现一直会有闪烁(我的类是继承JFrame),就来搜原因后发现好像是因为repaint会调用update()方法中的清屏操作导致闪烁。
我当时看的是这个文章
于是按照他的方法重写了update方法,却发现问题没解决
1 |
|
于是我又继续查文章,我发现没什么人用JFrame出现闪烁现象(我上次写飞机大战都没闪烁的说!),所以我查文章的时候放大范围,只要是Java swing编程出现闪烁的文章我都看一遍过去,终于让我看到这个大佬的文章
ydcun-双缓冲原理在awt和swing中实现消除闪烁的方法
就是他做的测试,让我知道原来在JFrame中repaint()的时候update()方法就没被调用到,JFrame消除闪烁是在update()中“直接调用了paint()函数而没有clearRect(),也就是清屏的方法,这里他试图不通过清屏来阻止闪烁的发生。”
所以到底是哪一步出问题了。。paint()方法已经被我重写了是不会有清屏操作的,问题感觉只能出在repaint()上,看了repaint()的代码好像也没发现类似清屏的代码,我能力有限,还在学习中,有大佬知道咋回事就求赐教一下QWQ,为了方便大家找repaint()有没有问题我就把代码贴上来吧
1 |
|
接下来我继续说说我是怎么解决这个问题的,在ydcun大佬那边是有讲他的解决方案的,我还没试过(因为凌晨3点了都!我写完立马睡觉!),我当时(凌晨2点)就想着既然不会去调用update(),那我手动调用不就好了?
于是
1 |
|
对,我调用了一个什么东西都没有的update()方法,就解决了闪烁的问题。。。但是如果我调用系统的update()
1 |
|
就会更闪烁然后报错
`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)
窗口也关不掉,只能从控制台强制停止运行。。。
等日后有大佬评论教我了或者我自己学习到了再补充一下这个原因,碎觉,溜了||ヽ( ̄▽ ̄)ノミ|Ю,狗命要紧
如果文章有帮到你或者给你提供了思路,那就送我个赞呗(◦˙▽˙◦),不然我就默认每个浏览的都是想点然后忘了(自欺欺人,bushi)