ImageIcon Not Displaying in java

fullscreen, imageicon, java, macos, swing

Solution

When using images, you want to load them through URL with `Class.getResource()`, which returns a URL. Passing a String the the `ImageIcon` will cause the image to be looked up through the file system. Though this may work during development in your IDE, you'll come to find out it won't work at time of deployment. Better make the changes now. To use this method, you want do this

ImageIcon icon = new ImageIcon(Images.class.getResource("/Users/georgebastow/Picture/background.jpg"));

For this to work though, you file structure needs to look like this

ProjectRoot
          src
             Users
                  georgebastow
                            Picture
                                  background.jpg

A more common approach is just to put the image a reousrces folder in the src

ProjectRoot
          src
             resources
                     background.jpg

And use this path

ImageIcon icon = new ImageIcon(Images.class.getResource("/resources/background.jpg"));                     

When you build, your IDE will transfer the images to the class path.

Side Note

- Don't paint on top level containers like `JFrame`. Instead use `JPanel` or `JComponent` and override the `paintComponent` method. if using `JPanel`, you should also call `super.paintComponent` in the `paintComponent` method.

Run you Swing Apps from the Event Dispatch Thread like this

public static void main(String[] args) {
    SwingUtiliities.invokeLater(new Runnable(){
        public void run() {
            new Images();
        }
    });
}

See Initial Thread

Don't call `Thread.sleep()`. When running from the EDT (like you should), you will block it. Instead use a `java.swing.Timer` if it's animation you're looking for. Even if it's not animation, still use it! See this example for `Timer` program.

- Also as @mKorbel mentioned, you never add anything to the frame.

UPDATE

Run this example. I also forgot to mention, when you paint on `JPanel` you also want to override the `getPreferredSize()`. This will give your panel a size.

`src/resources/stackoverflow5.png`

import java.awt.Dimension;
import java.awt.Graphics;
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 TestImage {

    public TestImage() {
        JFrame frame = new JFrame("Test Image");
        frame.add(new NewImagePanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public class NewImagePanel extends JPanel {

        private BufferedImage img;

        public NewImagePanel() {
            try {
                img = ImageIO.read(TestImage.class.getResource("/resources/stackoverflow5.png"));
            } catch (IOException ex) {
                System.out.println("Could not load image");
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 600);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestImage();
            }
        });
    }
}

Problem

This code is supposed to display a background image and the player. But it just comes up with a pink screen. I can't really figure out where the problem is coming from, here is my code. ``` package main; import java.awt.*; import javax.swing.ImageIcon; import javax.swing.JFrame; public class Images extends JFrame { public static void main(String Args[]) { DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.REFRESH_RATE_UNKNOWN); // This is going to take 4 parameter, first 2 is x and y for resolotion. Bit depth, the number of bits in a cloour // 16 is your bit depth. the last one is the monitor refresh, it means it will refres how much it wants Images i = new Images(); // making an object for this class i.run(dm); // making a run method and is taking the dm as a parameter, in this method we are putting stuff on the screen. } private Screen s; // Creating the Screen, from the Screen.java private Image bg; // Background private Image pic; // Face icon private boolean loaded; // Making the loaded //Run method private void run(DisplayMode dm) { // this is where we do things for the screen setBackground(Color.PINK); // Setting the Background setForeground(Color.WHITE); // Setting the ForeGround setFont(new Font("Arial", Font.PLAIN, 24)); // setting the font s = new Screen(); // now we can call ALL methods from the Screen object try { s.setFullScreen(dm, this); // This is setting the full screen, it takes in 2 parameters, dm is the display mode, so its setting the display settings, the next part is the this, what is just s, the screen object. loadpics(); // calling the loadpics method try { // so if that try block works, then it will put it to sleep for 5 seconds Thread.sleep(5000); // its doing this because, at the bottom (s.restorescreen) this makes it into a window again. so it needs to show it for 5 seconds. } catch (Exception ex) { } } finally { s.restoreScreen(); } } // Loads Pictures private void loadpics() { System.out.println("Loadpics == true"); bg = new ImageIcon("Users/georgebastow/Picture/background.jpg").getImage(); // Gets the background pic = new ImageIcon("Users/georgebastow/Picture/Player.png").getImage(); // Gets the Player System.out.println("Loaded == true in da future!"); loaded = true; // If the pics are loaded then... } public void paint(Graphics g) { if (g instanceof Graphics2D) { // This has to happen, its saying if g is in the class Graphics2D, so if we have the latest version of java, then this will run Graphics2D g2 = (Graphics2D) g; // Were making the Text smooth but we can only do it on a graphcis2D object. g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // we are making the text aniti alias and turning it on!(it means making the text smooths! :) ) } if(loaded == true){ System.out.println("Loaded == true3"); g.drawImage(bg,0,0,null); g.drawImage(pic, 170, 180, null); System.out.println("Loaded == true4"); } } } ``` Many Thanks in Advance

Original source