0

I have been learning Java from a YouTube tutorial and when it came to carrying components in a frame, things got a bit complicated for me. There are several things in this lesson for me, such as super keyword, Graphics class and paint method. I setup a frame and added this JPanel to that frame. I wrote this practice as much as I understood but it doesn't paint the ImageIcon and opens a completely empty frame instead. Thanks to anyone who can help in advance.

public class DragPanel extends JPanel{

ImageIcon image=new ImageIcon("walle.png");
Point imageCorner;
Point prevPt;

DragPanel(){
    imageCorner=new Point(0,0);
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    image.paintIcon(this, g, (int)imageCorner.getX(), (int)imageCorner.getY());
}
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Emin K.L.
  • 23
  • 3
  • 1
    1) *"I have been learning Java from a YouTube tutorial"* If you become a successful programmer, you'll be the first who does so by using video tutorials. For a good tutorial, instead see [Trail: Creating a GUI With Swing](https://docs.oracle.com/javase/tutorial/uiswing/index.html). 2) `image.paintIcon(this, g, (int)imageCorner.getX(), (int)imageCorner.getY());` odd way to paint an image. I'd use `g.drawImage(..)` 3) `new ImageIcon("walle.png");` That tries to load the image by `File` and will not work in many situations. Use `.getResource(..)` for an URL instead. 4) [Edit] to add a [mre]. .. – Andrew Thompson Mar 08 '22 at 19:06
  • .. Hotlink to an image from [this answer](https://stackoverflow.com/questions/19209650/example-images-for-code-and-mark-up-qas/19209651#19209651). – Andrew Thompson Mar 08 '22 at 19:07
  • 1
    The file name is relative, so you might want to give the full path of the image file. I'm guessing the image isn't loading and you have a blank image being painted. You could also try using a JFileChooser at the start of the program so you can select the image file and create your ImageIcon that way. – Ryan Mar 08 '22 at 19:07
  • 1) I don't think printing an empty Image is a problem, if that was the case it would cause a FileNotFoundException instead of printing null. Forementioned PNG is in the same directory (I don't use an IDE) and in this way assigning an ImageIcon never been a problem for me previously. 2) I am still trying to make what was suggested to work out. 3) @AndrewThompson Thanks for the course suggestion, I will definitely check it. – Emin K.L. Mar 08 '22 at 20:10
  • 1
    @EminK.L. "*if that was the case it would cause a FileNotFoundException instead of printing null"* - actually, `ImageIcon` is a pain in the ... code. It doesn't throw exceptions, it fails silently. Instead, you should be using `ImageIO.read`, which will throw an exception. *"PNG is in the same directory"* - The same directory as the class file or the same directory that you're running the code from? If the image is in the same folder as the class file, then you should be treating it as embedded resource, using `Class#getResource` instead of `File` – MadProgrammer Mar 08 '22 at 20:49
  • @MadProgrammer sorry for leaving that ambiguous, all PNG, java and class folders are in same directory and I directly run from there. – Emin K.L. Mar 09 '22 at 07:41

1 Answers1

3

ImageIcon("walle.png") is looking for the file relative to the location from which you executed the java command.

You can check what the "working" directory is by adding System.getProperty("user.dir") to your code. You can also check to see if the file exists from within the current context using System.getProperty(new File("walle.png").exists())

if that was the case it would cause a FileNotFoundException instead of printing null

Actually, ImageIcon doesn't throw an exception, it simply fails silently, which is why I tend to recommend not using it.

Instead, you should be using ImageIO, part from supporting more formats (and been expandable), it will also throw an exception if the image can't be loaded and won't return until the image is fully loaded.

See Reading/Loading an Image for more details

Forementioned PNG is in the same directory

Same directory as the class or the working directory? In general, I recommend getting use to using embedded resources, as it resolves many of the issues with "execution context"

I don't use an IDE

I'd probably recommend making use of one as it will help solve some of these issues and let you focus on learning the language.

So, my directory structure looks something like...

src/
    images/
        happy.png
    stackoverflow/
        Main.java

In this setup, the happy.png becomes an "embedded" resource, which will get packaged with the class files when it's exported, this means, that the resource is always in the same location, no matter the context of execution

enter image description here

package stackoverflow;

import java.awt.Dimension;
import java.awt.EventQueue;
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;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage image;

        public TestPane() throws IOException {
            image = ImageIO.read(getClass().getResource("/images/happy.png"));            
        }

        @Override
        public Dimension getPreferredSize() {
            return image == null ? new Dimension(200, 200) : new Dimension(image.getWidth(), image.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (image == null) {
                return;
            }
            Graphics2D g2d = (Graphics2D) g.create();
            int x = (getWidth() - image.getWidth()) / 2;
            int y = (getHeight() - image.getHeight()) / 2;
            g2d.drawImage(image, x, y, this);
            g2d.dispose();
        }

    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366