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); // 然後一次性顯示出來
}
於是我又繼續查文章,我發現沒什麼人用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);
}
}
}
接下來我繼續說說我是怎麼解決這個問題的,在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);
}
對,我呼叫了一個什麼東西都沒有的update()方法,就解決了閃爍的問題。。。但是如果我呼叫系統的update()
public void update(Graphics g) {
paint(g);
}
就會更閃爍然後報錯
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)
相關文章
- vue渲染時閃爍{{}}的問題及解決方法Vue
- vuejs在解析時出現閃爍的原因及防止閃爍的方法VueJS
- SceneKit-解決模型重疊時渲染畫面閃爍的問題模型
- 討論TableLayoutPanel載入緩慢和閃爍問題解決方案
- 解決Java中Swing的JFrame的setTitle方法輸入中文圖形介面亂碼辦法Java
- win10 1511更新後螢幕出現閃爍最佳解決方法Win10
- RecyclerView使用,優化,條目閃爍問題View優化
- pyinstaller閃退問題解決方法
- Flutter——實現閃爍效果Flutter
- 解決Ubuntu配置nginx出現的問題UbuntuNginx
- JAVA程式設計題-用java解決兔子問題Java程式設計
- WinForm 載入自定義控制元件閃爍問題ORM控制元件
- pyinstaller 生成 exe 的閃退問題解決方案
- kafka監聽出現的問題,解決和剖析Kafka
- iOS 解決tableHeaderView新增searchBar後出現的問題iOSHeaderView
- Android 解析包時出現問題 的解決方案(應用檢查更新)Android
- Flutter 混合開發實戰問題記錄(一)FlutterView閃爍FlutterView
- Java操作hdfs出現的問題Java
- js閃爍效果JS
- win10 mysql閃退怎麼解決_解決win10 mysql閃退問題Win10MySql
- xbox手柄閃爍但是連不上電腦怎麼解決
- 快速解決mongodb出現id重複問題MongoDB
- 換IP經常出現的問題及其解決方案
- 解決出現This system is not registered to Red Hat Subscription Management的問題
- JAVA | Java 解決跨域問題Java跨域
- 解決JUnit單元測試時出現的Java.lang.Exception: No runnable methods問題JavaException
- 簡單CSS實現閃爍動畫(+1白話講解)CSS動畫
- Java解決跨域問題Java跨域
- Win10系統中桌面圖示閃爍怎麼解決Win10
- 使用雙快取解決 Canvas clearRect 引起的閃屏問題快取Canvas
- [已解決]Mac下Anaconda-Navigator閃退問題Mac
- css3實現動畫閃爍效果CSSS3動畫
- [譯] 在 Flutter 中實現微光閃爍效果Flutter
- 協程實現canvas影像隨機閃爍Canvas隨機
- win10系統下Xbox應用出現閃退怎麼解決Win10
- unity 3D音 釋出PICO後出現問題的解決方法Unity3D
- Win10系統下Chrome瀏覽器螢幕閃爍的解決方法Win10Chrome瀏覽器
- 如何解決app閃退問題APP