In my first game I'm trying to code, the image won't display in the JFrame and I haven't been able to find out why

Viewed 23

I'm pretty sure it's not a file location issue since the image file is in the resource folder and I don't get a missing input file error when I run the code. I have been trying to teach myself how to code a very simple 2D game using tutorials online and I haven't found the answer as to why the image won't show up.

Main class

import javax.swing.JFrame;


public class main 
{
    public static void main(String[]args)
    {
        JFrame frame = new JFrame("First Game");
        
        BlockBreakerPanel panel = new BlockBreakerPanel();
        frame.getContentPane().add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(800, 800);
        frame.setResizable(false);
    }
}

Block.java

import java.awt.Image;
import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.Graphics;
import java.awt.Component;

public class Block extends Rectangle
{
    Image pic;
    boolean destroyed = false;
    int posX,posY;
    int width,height;
    Block(int x, int y, int w, int h, String s)
    {
        this.posX = x;
        this.posY = y;
        this.width = w;
        this.height = h;
        try
        {
            pic = ImageIO.read(new File("Resources/"+s));
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
    public void draw(Graphics g, Component c)
    {
        g.drawImage(pic, posX, posY, width, height, c);
    }
}

BlockBreakerPanel.java

import javax.swing.JPanel;
import java.util.ArrayList;


public class BlockBreakerPanel extends JPanel 
{
    ArrayList<Block> blocks = new ArrayList<Block>();
    Block cobble = new Block(1,1, 160, 160, "Cobble.png");
    BlockBreakerPanel()
    {
        
    }
}
1 Answers

The draw method from the Block class is never called/referenced in your code so it never knows to draw the image. You can solve this by overriding the paintComponent method of the JPanel as shown below to automatically draw the image whenever the panel is painted/updated. Note that a Rectangle is just a geometry object and does not have any associated Graphics or Painting, that is why why you cant override paint methods of the Rectangle itself, but you can override a paint method of a custom JPanel component like your BlockBreakerPanel:

import javax.swing.JPanel;
import java.util.ArrayList;

public class BlockBreakerPanel extends JPanel 
{
    ArrayList<Block> blocks = new ArrayList<Block>();
    Block cobble = new Block(1,1, 160, 160, "Cobble.png");
    BlockBreakerPanel()
    {
        
    }
    
    //Override the paint component method
    @Override
    public void paintComponent(Graphics g) {
        //Always perform default/super painting first
        super.paintComponent(g);       

        //Now do your custom painting, for example
        cobble.draw(g);
    }  
}

Note that you don't need to add Component to your draw method public void draw(Graphics g, Component c) unless you want te deal with observers (Not applicable to you?), you should change the method to only take a Graphics input public void draw(Graphics g) and the line to draw the image can simply have a null observer as the last argument:

public void draw(Graphics g)
{
    g.drawImage(pic, posX, posY, width, height, null);
}
Related