在JFrame中闪烁

时间:2018-03-07 17:23:46

标签: java image-loading jcanvas

我正在开发一款小游戏,这将是为了享受我的朋友,如果出现错误。屏幕将闪烁图像。我知道这是从画布每一帧渲染图像。但我不知道如何阻止它渲染每一帧。我在寻求帮助。这是我的main,JFrameBuilder和JCanvas类中的一些代码,用于显示我在做什么。

https://pastebin.com/renyzgXx

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();
    }
}


}

https://pastebin.com/ERisWs6V

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;
}
}

https://pastebin.com/6EGkHj6r

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();
}


}

1 个答案:

答案 0 :(得分:0)

默认情况下,Swing组件(包括JPanel)已经是双缓冲的,因此尝试实现自己的双缓冲不会让您受益匪浅。尝试覆盖paintComponent()而不是覆盖paint()(这是旧的AWT处理方式)。

paint()实际上包含对三种不同方法的调用,其中一种方法是paintComponent(),所以当您覆盖paint()时,您正在绘制边框和所有方法孩子两次,这可能是你的用户界面闪烁的原因。

有关详细信息,请阅读The Java Tutorial,有关详细信息,请阅读此Oracle tech note