[英]Flickering in JFrame
我正在開發一款小型游戲,它將使我的朋友們開心,如果遇到錯誤也可以。 屏幕將閃爍圖像。 我知道這是從畫布上每幀渲染圖像開始的。 但是我不知道如何阻止它渲染每一幀。 我一直在尋求幫助。 這是我的主框架JFrameBuilder和JCanvas類中的一些代碼,以顯示我在做什么。
package main;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import entity.Dragon;
import imageBuilders.Image;
public class Main {
public static JFrameBuilder jf ;
public static void main(String[] args){
jf = new JFrameBuilder("Tutorial");
try {
JCanvas.addImage(new Image(ImageIO.read(new File("C:/Users/Eddie/Desktop/testprog2/Tutorial game/src/imgs/Dragon.png")), null,100,100));
JCanvas.addImage(new Image(ImageIO.read(new File("C:/Users/Eddie/Desktop/testprog2/Tutorial game/src/imgs/rocket.png")), null,100,100));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int x = 0;
Dragon d = new Dragon(jf,x);
while(jf.isActive()){
jf.update(jf.getGraphics());
JCanvas.changeImageXandY(d.calculateX(), d.calculateY(), 0);
System.out.println(d.calculateX());
delay(16);
}
}
public static void delay(long ms){
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package main;
import java.awt.BorderLayout;
import javax.swing.JFrame;
public class JFrameBuilder extends JFrame{
/**
* Author: Kingmo100
*/
private static final long serialVersionUID = -8535971463237805125L;
private static final int WIDTH = 1000;
private static final int HEIGHT = 500;
private static JCanvas jp;
public JFrameBuilder(String title){
super(title);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(WIDTH, HEIGHT);
this.setLayout(new BorderLayout());
jp = new JCanvas();
jp.setSize(WIDTH, HEIGHT);
jp.setLocation(10, HEIGHT + 10);
jp.setAlignmentX(10);
jp.setAlignmentY(10);
jp.paintComponents(this.getGraphics());
jp.setVisible(true);
System.out.println(jp);
this.add(jp, BorderLayout.CENTER);
this.getContentPane();
}
public static JCanvas getJCanvas(){
return jp;
}
public JFrame getFrame(){
return this;
}
}
package main;
import java.awt.Graphics;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import imageBuilders.Image;
public class JCanvas extends JPanel {
private static List<Image> li = new ArrayList<Image>();
/**
*
*/
private static final long serialVersionUID = -4456984789525563682L;
public JCanvas(){
super();
}
@Override
public void paint(Graphics g){
super.paint(g);
for(Image i: li){
try{
g.drawImage(i.getImage(), i.getX(), i.getY(), i.getImageObserver());
}catch(NullPointerException e){
}
}
}
public static void addImage(Image i){
li.add(i);
}
public static void removeImageinIndice(int i){
li.remove(i);
}
public static void changeImageInIndice(int i, Image i2){
li.add(i, i2);
}
public static void clearImages(){
li.clear();
}
public static Image getImageinIndice(int i){
return li.get(i);
}
public static boolean changeImageXandY(int x, int y, int ii){
Image im = li.get(ii);
im.setX(x);
System.out.println(im.getX());
im.setY(y);
li.set(ii, im);
return true;
}
public KeyListener getKeyListener(){
return this.getKeyListener();
}
}
默認情況下,Swing組件(包括JPanel)已經進行了雙緩沖,因此,嘗試實現自己的雙緩沖不會從中受益。 嘗試覆蓋paintComponent()
而不是覆蓋paint()
(這是做事的舊AWT方法)。
paint()
實際上包括對三個不同方法的調用,其中之一是paintComponent()
,因此,當您覆蓋paint()
,您要繪制邊框和所有子對象兩次,這可能就是UI閃爍的原因。
有關更多詳細信息,請閱讀The Java Tutorial ;有關更多詳細信息,請閱讀此Oracle 技術說明 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.