简体   繁体   English

JFrame中的闪烁

[英]Flickering in JFrame

Im working on a small game that will be for the enjoyment of my freinds and if come into an error. 我正在开发一款小型游戏,它将使我的朋友们开心,如果遇到错误也可以。 The Screen will flicker the images. 屏幕将闪烁图像。 I know this is from the canvas rendering the image every single frame. 我知道这是从画布上每帧渲染图像开始的。 But I dont know how to stop it from rendering every frame. 但是我不知道如何阻止它渲染每一帧。 I was looking for help. 我一直在寻求帮助。 This is a bit of code in my main, JFrameBuilder, and JCanvas class to show what im doing. 这是我的主框架JFrameBuilder和JCanvas类中的一些代码,以显示我在做什么。

https://pastebin.com/renyzgXx 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 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 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();
}


}

Swing components (including JPanel) are already double buffered by default, so you won't benefit by trying to implement your own double buffering. 默认情况下,Swing组件(包括JPanel)已经进行了双缓冲,因此,尝试实现自己的双缓冲不会从中受益。 Try overriding paintComponent() instead of overriding paint() (which is the old AWT way to do things). 尝试覆盖paintComponent()而不是覆盖paint() (这是做事的旧AWT方法)。

paint() actually includes a call to three different methods, one of which is paintComponent() , so when you're overriding paint() , you're painting borders and all children twice, which is probably why your UI is flickering. paint()实际上包括对三个不同方法的调用,其中之一是paintComponent() ,因此,当您覆盖paint() ,您要绘制边框和所有子对象两次,这可能就是UI闪烁的原因。

For more details, read The Java Tutorial and for even more details, read this Oracle tech note . 有关更多详细信息,请阅读The Java Tutorial ;有关更多详细信息,请阅读此Oracle 技术说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM