Reputation:
I'm following a Java course, and the current idea is to draw an image using Java Graphics2D. I'm following the steps one by one, but it seems not to be drawing anything. The panel is shown within the frame and everything is correct, but the image is not drawn. I'm using Java 15 and the course is Java 13.
JPanel class code:
public class MyPanel extends JPanel implements ActionListener {
Image ball;
int x = 0;
int y = 0;
MyPanel(){
this.setPreferredSize(new Dimension(PANEL_WIDTH,PANEL_HEIGHT));
this.setBackground(Color.BLACK);
ball = new ImageIcon("ball.png").getImage();
}
public void paint(Graphics g){
Graphics2D G2D = (Graphics2D) g;
G2D.drawImage(ball,x,y,null);}
JFrame class code:
public class MyFrame extends JFrame{
MyPanel panel;
MyFrame(){
panel = new MyPanel();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(panel);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
Main class code:
new MyFrame();
I picked out most of the relevant code.
Upvotes: 2
Views: 1335
Reputation: 439
It really looks like your image is not loaded.
As @MadProgrammer just told, new ImageIcon("ball.png")
does not raise any error, and getImage()
will always return something (not null
), even if the file is not properly loaded.
To make sure your image is available, you can try ball.getWidth(null)
, and
if it returns -1
, then something went wrong.
You can check the root path used by the JVM ("execution" location) with System.getProperty("user.dir")
, the image file has to be exactly in this folder.
I tried your code with java 1.8 and it works well.
Upvotes: 0
Reputation: 347332
First, I recommend reading through Performing Custom Painting and Painting in AWT and Swing to get a better idea of how painting in Swing should work.
I then suggest reading through Reading/Loading an Image
The "problem" with ImageIcon
is that
ImageIO
on the hand will throw an error if the image can't be loaded, which is much easier to diagnose, and will only return AFTER the image is fully loaded and available.
One concept which can be hard to grasp when your starting is the concept of "embedded" resources. Java allows you to package "resources" along with your code. These resources live within the context of your programs class path and make it MUCH easier to load when compared to having to deal with external files.
Have a look Packaging and accessing run-time resources in a runnable Jar for some basics.
Depending on the IDE you're using, it's usually pretty easy to "copy" these resources into your project/src and allow the IDE to package itself.
The problem with a question like this is it's very, very hard for anyone to truely diagnose, as there are so many reasons why the image might not have loaded and the solution is usual one of trial and error.
Me, I'd start by just drawing some lines/rectangles and make sure that paint
is been called. I'd then look at things like the image's size, to make sure it's not something like 0x0
.
This is a simple runnable example based on comments I made above. I'm using NetBeans and the image was stored in the "Source Package" (so, along with the other source code) under the /images
package
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage beachBall;
public TestPane() {
try {
beachBall = ImageIO.read(getClass().getResource("/images/BeachBall.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (beachBall == null) {
return;
}
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - beachBall.getWidth()) / 2;
int y = (getHeight() - beachBall.getHeight()) / 2;
g2d.drawImage(beachBall, x, y, this);
g2d.dispose();
}
}
}
Upvotes: 1