3

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

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Pilkin
  • 33
  • 1
  • 1
  • 4

2 Answers2

8

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();
            }
        });
    }
}
Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Hi,i put the background.jpg in the res folder, but it asked me to change bg into an ImageIcon, not an Image. This meaning that i can not do g.drawImage(bg,0,0,null);. I tried changing it to drawLine, but that did not help either. – Pilkin Feb 01 '14 at 20:28
  • you need to use .getImage() like you did before at the end of the `ImageIcon` instantiation. Make sure to keep `bg` as an `Image` you can't paint and `ImageIcon` – Paul Samsotha Feb 01 '14 at 20:30
  • I have done this, when i run the program it does not display the image. Why would this be happening. It is displaying pink on the whole screen. – Pilkin Feb 01 '14 at 20:34
  • I am using mac OS X, and the screen goes out of fullscreen so the dock is showing in the first second. – Pilkin Feb 01 '14 at 20:36
  • Use `bg = ImageIO.read(Images.class.getResource("/res/background.jpg");` And wrap it in a try/catch block. If the image isnt loaded then you know the path is wrong. If it doesn't throw an exception, then you the problem is somewhere else – Paul Samsotha Feb 01 '14 at 20:37
  • I have done it, but it still does not display. The res is in the src and i'm not getting any exceptions, i put this try{ bg = ImageIO.read(Images.class.getResource("/res/background.jpg")); } catch(Exception b){ b.printStackTrace(); } – Pilkin Feb 01 '14 at 20:42
  • Where else would the problem be coming from? – Pilkin Feb 01 '14 at 20:42
  • Are you using `JPanel` or `JFrame` still? – Paul Samsotha Feb 01 '14 at 20:46
  • Im using the JFrame, how could i use the jpanel? – Pilkin Feb 01 '14 at 20:49
  • See my **UPDATE** You can test it out. just change it your file path. I'm about to knock out. It's late here. Hopefully you get it solved. It works fine for me. – Paul Samsotha Feb 01 '14 at 20:51
  • I got this error Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: input == null! at javax.imageio.ImageIO.read(ImageIO.java:1388) at main.TestImage$NewImagePanel.(TestImage.java:28) at main.TestImage.(TestImage.java:16) at main.TestImage$1.run(TestImage.java:50) at... the rest was too long – Pilkin Feb 01 '14 at 20:56
  • and thankyou for helping me, im kinda a newb to java :) – Pilkin Feb 01 '14 at 20:57
  • That error means your path is wrong. You need your file in `src/res` and use this path `"/res/background.jpg"`. – Paul Samsotha Feb 01 '14 at 20:58
  • Omg, Thankyou so much, this error has been troubling me so much, You are the BEST, thankyou. ps. On a side note it did work :) – Pilkin Feb 01 '14 at 21:01
  • Also would how could i implement this in the Images class? – Pilkin Feb 01 '14 at 21:04
  • Short answer, **Don't** just make changes to my code as you see fit. Your code has references to class in which I have no idea what they are. I really have to knock out now. good luck. – Paul Samsotha Feb 01 '14 at 21:07
3
  1. JFrame isn't proper component (its container) for displaying an Image

  2. usage of paint() for JFrame isn't proper way how to display image or custom painting, graphics

  3. use JLabel with setIcon() in the case isn't JFrame used as container and there are/isn't any JComponent(s) in the JFrame

  4. use JPanel (put to the JFrame.CENTER area) with override paintComponent(instead of paint) in the case that there will be JPanel used as container for another JComponent(s)

  5. more in Oracle tutorial Working with Images

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Thank you mKorbel, what would i run paint in that is not the JFrame. How could i paint without JFrame? what would i use instead – Pilkin Feb 01 '14 at 20:31