Search code examples
javamacosswingfullscreenimageicon

ImageIcon Not Displaying in java


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


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();
                }
            });
        }
    }