0

So I am in the process of making myself a simple little 2D game engine to learn more about java swing and as something that I can reuse for future projects. I have a class named Canvas which extends JPanel and will contain all the code for rendering sprites, etc. Right now I have a method called paintSprites() that will go through all the drawing steps for every sprite and it will manage the background color and draw it to a BufferedImage object (kind of like double buffering) then, in my paintComponent() method, it simply draws this BufferedImage object onto the screen. Just for testing purposes, in my paintSprites() method, I am simply drawing a green square. However, when I run the program, the window shows up, but it is completely blank. Here is my code:

package gui;

import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Color;

import java.awt.image.BufferedImage;

import game.Game;

public class Canvas extends JPanel implements Runnable{

  private Color background = Color.WHITE;
  private double targetFPS = 60.0;
  private Thread renderer;
  private boolean render = true;
  private Game parent;
  private BufferedImage temp;

  public Canvas(Game parent){
    super();

    this.parent = parent;

    renderer = new Thread(this);
    renderer.start();
  }

  public void setBackgroundColor(Color c){
    background = c;
  }

  public void startRendering(){
    render = true;
  }

  public void stopRendering(){
    render = false;
  }

  public void setTargetFPS(double d){
    targetFPS = d;
  }

  public void paintComponent(Graphics g){
    g.setColor(background);
    g.fillRect(0,0,getWidth(), getHeight());
    g.drawImage(temp,0,0,null);
    System.out.println("Painted Component");
  }

  public BufferedImage paintSprites(){
    BufferedImage out = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);


    out.getGraphics().setColor(Color.WHITE);
    out.getGraphics().fillRect(0, 0, getWidth(), getHeight());
    out.getGraphics().setColor(Color.GREEN);
    out.getGraphics().fillRect(10, 10, 50, 50);

    out.getGraphics().dispose();
    return out;
  }

  public void run(){
    while(true){
      if(!render) continue;

      try{Thread.sleep((long)(1000.0/targetFPS));} catch(InterruptedException ex){}


      BufferedImage dbImage = paintSprites();
      temp = dbImage;
      repaint();
    }
  }
}

(Also I think this may have something to do with the buffered image type, as when I change it to TYPE_INT_RGB, the window has a black background with a white square, but I have tried different image types and none seem to work).

Dmitriy Popov
  • 1,440
  • 2
  • 10
  • 26
smcbot
  • 15
  • 5
  • I tried switching out the methods but from what I have seen, they are somewhat identical, at least in this situation. – smcbot Nov 07 '20 at 19:03
  • 5
    It is, in fact, advised to use `paintComponent()`, see https://stackoverflow.com/questions/9389187/difference-between-paint-paintcomponent-and-paintcomponents-in-swing – MDK Nov 07 '20 at 19:11
  • @D.Sikilai, The proper method to override IS the `paintComponent(...)`. Please read the section from the Swing tutorial on [Custom Painting]() for more information and working examples. – camickr Nov 07 '20 at 19:45

1 Answers1

0

Changing in paintSprites() from getGraphics() to createGraphics() as suggested by the tutorial fixed it for me:

public BufferedImage paintSprites() {
    BufferedImage out =
        new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);

    Graphics2D g = out.createGraphics();
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, getWidth(), getHeight());
    g.setColor(Color.GREEN);
    g.fillRect(100, 100, 50, 50);

    g.dispose();
    return out;
}

I was however unable to find a ressource explaining why.

MDK
  • 451
  • 2
  • 12