[英]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.