0

I have just started learning java and I've been working on this code for a moving object with keyboard input. I am now trying to add in a background, but it keeps erroring with:

javax.imageio.IIOException: Can't read input file!
    at javax.imageio.ImageIO.read(Unknown Source)
    at game.GameLoop.run(GameLoop.java:24)
    at java.lang.Thread.run(Unknown Source)

The code I have in Game.java is:

package game;

import java.applet.*;
import java.awt.*;

public class Game extends GameLoop{

    public void init(){
        setSize(864,480);
        Thread th = new Thread(this);
        th.start();
        offscreen = createImage(864,480);
        d = offscreen.getGraphics();
        addKeyListener(this);
    }

    public void paint(Graphics g){
        d.clearRect(0, 0, 864, 480);
        d.drawImage(background, 0, 0, this);
        d.drawRect(x, y, 20, 20);
        g.drawImage(offscreen, 0, 0, this);
    }

    public void update(Graphics g){
        paint(g);
    }
}

And here is my GameLoop.java:

package game;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class GameLoop extends Applet implements Runnable, KeyListener{

    public int x, y;
    public Image offscreen;
    public Graphics d;
    public boolean up, down, left, right;
    public BufferedImage background;

    public void run(){
        x = 100;
        y = 100;
        try {
            background = ImageIO.read(new File("background.png"));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        while(true){
            x = 100;
            y = 100;
            while(true){
                if (left == true){
                    x-=4;
                }
                if (right == true){
                    x+=4;
                }
                if (up == true){
                    y-=4;
                }
                if (down == true){
                    y+=4;
                }
                if ( x <= 0 ){
                    x = 0;
                }
                if ( y <= 0 ){
                    y = 0;
                }
                if ( x >= 843 ){
                    x = 843;
                }
                if ( y >= 460 ){
                    y = 459;
                }
                repaint();
            try{
                Thread.sleep(20);
            } catch(InterruptedException e){
                e.printStackTrace();
            }
            }
        }
    }

    //@Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == 37){
            left = true;
        }
        if(e.getKeyCode() == 38){
            up = true;
        }
        if(e.getKeyCode() == 39){
            right = true;
        }
        if(e.getKeyCode() == 40){
            down = true;
        }
    }

    //@Override
    public void keyReleased(KeyEvent e) {
        if(e.getKeyCode() == 37){
            left = false;
        }
        if(e.getKeyCode() == 38){
            up = false;
        }
        if(e.getKeyCode() == 39){
            right = false;
        }
        if(e.getKeyCode() == 40){
            down = false;
        }
    }

    //@Override
    public void keyTyped(KeyEvent e) {
    }
}

Sorry about the editing I can't seem to get it all in the ``, and I will also fix the messy code, but do you guys have any ideas what is causing this error, there is a file in the src dir called background.png, it is very basic and made in MS paint, if that helps.

Thanks.

14
  • 2
    Different IDEs require different locations for files such as text or image resources. Try copying the image to several different locations, most likely one level above src, to see if that fixes it. Commented Nov 10, 2012 at 3:22
  • Is ur file in same directory ? Commented Nov 10, 2012 at 3:22
  • 3
    To check the default directory path: File here = new File("."); System.out.println(here.getCanonicalPath()); Commented Nov 10, 2012 at 3:25
  • 1
    @AngusMoore - I had a similar problem a week or two ago, I'm pretty sure with Eclipse the level above src is the one you want. Glad I could help! Commented Nov 10, 2012 at 3:26
  • 3
    Applets won't (in most cases) allow you to read files. You will need to emeded the resource in the Jar our deploy it within the same context. Better to use JPanel and JFrame Commented Nov 10, 2012 at 3:34

2 Answers 2

4

There are two places a simple, sand-boxed applet can obtain images.

Where

  1. A loose file on the same server the applet was supplied from. E.G. This might be used for a sand-boxed 'image slideshow' where the image names are supplied in applet parameters.
  2. A Jar on the run-time class-path of the applet. Best for resources which would not typically change (barring localized images, where it becomes more complicated). E.G. This might be used for button/menu icons, or BG images.

"background.png" strongly indicates the 2nd scenario - 'part of the app. itself'.

How to find

Both types of resources should identified by URL (do not try to establish a File as it will fail when the applet is deployed).

The way to obtain an URL for the 2nd case is something along the lines of:

URL urlToBG = this.getClass().getResource("/path/to/the/background.png");

..where /path/to/the/ might simply be /resources/ or /images/. It is the path within a Jar on the classpath, where the image can be found.

How to load

Most methods that will load a File are overloaded to accept an URL. This notably applies to ImageIO.read(URL).

While the Applet class has inbuilt methods to load images, I recommend sticking with ImageIO since it provides more comprehensive feed-back on failure.

Further tips

Tip 1

Thread.sleep(20);

Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling Thread.sleep(n) implement a Swing Timer for repeating tasks or a SwingWorker for long running tasks. See Concurrency in Swing for more details.

Tip 2

It is the third millennium, time to start using Swing instead of AWT. That would mean extending JApplet instead of Applet. Then you might shift the logic of painting into a JPanel that is double-buffered by default, and could be used in either the applet or a frame (or a window or a dialog..).

Tip 3

setSize(864,480);

The size of an applet is set in HTML, and the applet should accept whatever size it is assigned and work within that. Taking that into account, statements like:

d.clearRect(0, 0, 864, 480);

..should read more like:

d.clearRect(0, 0, getWidth(), getHeight());
Sign up to request clarification or add additional context in comments.

2 Comments

Very impressive.. But the answer to my question was inside the bin directory, which is where eclipse locates the resources, thanks anyway.
Are you still using a File to load it?
1

@Patricia Shanahan Your comment actually helped me to solve the same problem.

I've used that code:

File here = new File(".");
try {
    System.out.println(here.getCanonicalPath());
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

and from there you can figure out the correct path to use.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.