BufferedImage not drawing with g.drawImage()

Okay, so I’ve been looking over this for about 2 hours and I simply cannot find out what’s wrong. Here’s the code for both of my class files:

Skeleton.class

import javax.swing.*;

public class Skeleton {
	
	public static void main(String[] args) {
		JFrame frame = new JFrame("Map Editor");
		frame.setVisible(true);
		frame.setSize(800, 600);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLocationRelativeTo(null);
		Draw object = new Draw();
		frame.add(object);
		object.drawing();
	}
	
}

Draw.class

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class Draw extends JPanel {
	private BufferedImage walkable;
	
	public void drawing() {
		System.out.println("good");
		BufferedImage walkable = null;
		try {
			walkable = ImageIO.read(new File("Sprites/Animated.png"));
		} catch(IOException e) {
			System.out.println("failed");
		}
		System.out.println(walkable.getWidth());
		repaint();
	}
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(walkable, 0, 0, this);
		g.setColor(Color.red);
		g.drawRect(10, 10, 10, 10);
	}
}

As you can see, I have some System.out.println()'s scattered throughout the code. No exception is thrown when the image is loaded with ImageIO.read(), and when I query the width of the image after loading it is 160 which is correct. The red rectangle also draws, but the image just will not. I’m sure I’m missing something silly, but after looking over it so many times, I’m at a dead end. Any suggestions?

Edit: If it helps, here is a screenshot of the program running with the command prompt and debug outputs.

Rename your function to paint(), not paintComponent().

public void paint(Graphics g) {
super.paint(g);
g.drawImage(walkable, 0, 0, this);
g.setColor(Color.red);
g.drawRect(10, 10, 10, 10);
g.dispose();
}

Gave the same output as before. :frowning:

Are you making sure the image is in the directory?

Yes. The image is loaded fine, the catch on ImageIO.read() gives no debug, and when I query the width of the image it returns the correct value. Look in the code and you will see a System.out for the catch on the try event, and another for the width of the image. In the screenshot I linked, you can see the results in the command prompt.

Well, this might also be a problem with the image itself, so try to test with other BMP/PNGs.

Tested with 3 different ones so far. I will try with a plain black image from MS Paint, but I doubt I get results.

Edit: No go. Here’s the results with the plain image. You can see the application, CMD Promt and the image in the screenshot.

Okay, so the problem still persist. I guess I just need to give it a rest for a while, and come at it fresh … unless I get some miracle advice from a fellow user. :frowning:

I strictly use ImageIO only for saving images in other formats. You can use it for pictures, but you have to connect a MediaTracker to it so it can actually load the Image. So, to save you the headache I’ll give you a shorter solution that will help you get the image onto the screen.


import java.awt.*;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class Draw extends JPanel {
   private Image walkable;
   
   public void drawing() {
      System.out.println("good");
      ImageIcon icon = new ImageIcon("Sprites/Animated.png");
      walkable = icon.getImage(); 
      repaint();
   }
   
   public void paint(Graphics g) {
      g.drawImage(walkable, 0, 0, this);
      g.setColor(Color.red);
      g.drawRect(10, 10, 10, 10);
   }
}

Try removing line 13. You’re creating a new local walkable variable and setting that rather than the field you mean!

You should also be creating your UI on the Swing event thread. Might be another cause of issues. Wrap all your code in main() inside a Runnable and pass to EventQueue.invokeLater()

This works. Thanks a lot. :slight_smile: I can now proceed with my project.

This also works! I don’t know how I missed that. Anyways, I will throw the main function in the Swing event thread as well.

Please don’t do this. It will break Swing functionality like double-buffering.

ImageIO is a blocking API, meaning that after load(...) returns, the image will be fully loaded. Using a MediaTracker on it makes no sense.

Jhagor had perfectly fine code to start with (except line 13) and it’s sad to see how the advice here (except from nsigma) made it worse.