I'm working on a rendering loop using my own double buffering, I don't have a JPanel but a JFrame (as I understand JPanel automatically double buffers). My problem is that when I call super.paint(g) it causes my screen to flicker. When I comment this out it goes away.
ATM I create a BufferedImage and grab it's Graphics2D, then every render loop I flush the image with a solid color and call repaint(). In the paint method I call super and use the paint() method's graphic to draw the image. This causes my screen to flicker even when rendering 1 fps.
public void run()
{
long startTime;
long runTime;
double residualTime = 0;
while(isRunning)
{
startTime = System.nanoTime();
**update.update();**
render.render();
runTime = System.nanoTime() - startTime;
if(runTime < 1e9/fpsTarget)
{
Double sleepTime = (1e9/fpsTarget - runTime) / 1e6;
residualTime += sleepTime % 1;
sleepTime -= sleepTime % 1;
if(residualTime > 1)
{
sleepTime++;
residualTime--;
}
try
{
sleep(sleepTime.longValue());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally
{
/*
System.out.println("\n Run time: " + runTime / 1e6);
System.out.println(" Sleep time: " + sleepTime);
System.out.println("Residual Time: " + residualTime);
*/
}
}
//fps(startTime);
}
}
public class Render
{
private Screen screen;
Graphics2D graphics;
BufferedImage image;
public Render()
{
screen = new Screen();
image = new BufferedImage(screen.getWidth(), screen.getHeight(), BufferedImage.TYPE_INT_RGB);
graphics = image.createGraphics();
}
public void render()
{
flush();
screen.setImage(image);
screen.repaint();
}
private void flush()
{
graphics.setPaint(Color.BLUE);
graphics.fillRect(0, 0, image.getWidth(), image.getHeight());
}
}
public class Screen extends JFrame
{
private BufferedImage image;
public Screen()
{
super(TITLE);
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setLocation(300, 150);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void paint(Graphics g)
{
super.paint(g);
g.drawImage(image, 0, 0, null);
}
public void setImage(BufferedImage image)
{
this.image = image;
}
I've tried adding a JPanel before and rendering through paintComponent() but had the same issue. Any ideas advice would be helpful!
EDIT - Solved
When setting my image in the Render.render() method repaint() was likely automatically called. I then called repaint() immediately after cause a double refresh. Removing my own repaint() call solved the issue.
Curiously before when I called repaint(), removing super.paint() also solved the issue. Any ideas why?
Well I'm not sure if this was the answer or not, but I was trying to show Andrew what my code looked like when I had a Panel rendering instead of the Frame but wasn't having any success. I deleted everything I changed and tried pursuing Ashwinee's thread theory. I ran my code once before changing anything and it was running perfectly.
Comparing my current code to when I submitted I think the difference is that I deleted my repaint() statement in the Render.render() method. My only guess is that JFrame recognized something that it had previously drawn changed so it automatically repainted, so I was effectively repainting twice every loop.
If I add the repaint() call back in the flashing returns.