Question

Having problems loading/showing an image in a java applet. Not sure if I'm loading the image incorrectly or if I'm accessing it incorrectly. Here's the code that draws the ship and the background(it's an asteroid-like game). The background draws correctly but the ship doesn't. This is the main class method that I'm dealing with:

public void paintFrame(Graphics g) {
        Dimension d = size();
        g.fillRect(0, 0, d.width, d.height);
        g.drawImage(ship.getImage(), d.width/2, d.height/2, null);
}

I create an instance of the ship class at the beginning of the class. However, if I try to instantiate the ship class in a method (such as "Ship ship = new Ship();), it says the variable "ship" is never used.

Here's the entire ship class:

public class Ship {
    private int dx;
    private int dy;
    private int x;
    private int y;
    private Image image;    

    public Ship() {
        ImageIcon ii = new ImageIcon("ship1.png");
        image = ii.getImage();
    }

    public Image getImage() {
        return image;
    }
}

If I run it as is, it runs without errors, but it doesn't display the ship. If I try to create the instance of the ship anywhere else except at the top, it gives me a NullPointerException.

Update

Here's my entire main class:

import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;

public class RunGame extends Applet implements Runnable {
    int frame;
    int delay;
    Thread animator;
    Ship ship = new Ship();
    Level level;
    Dimension offDimension;
    Image offImage;
    Graphics offGraphics;

    /**
     * Initialize the applet and compute the delay between frames.
     */
    public void init() {
        String str = getParameter("fps");
        int fps = (str != null) ? Integer.parseInt(str) : 10;
        delay = (fps > 0) ? (1000 / fps) : 100;

    }

    /**
     * Method is called when the applet becomes visible on
     * the screen.
     */
    public void start() {
    animator = new Thread(this);
    animator.start();

    }

    /**
     * This method is called by the thread that was created in
     * the start method. It does the main animation.
     */
    public void run() {
    // Remember the starting time
    long tm = System.currentTimeMillis();
    while (Thread.currentThread() == animator) {
        // Display the next frame of animation.
        repaint();

        // Delay depending on how far we are behind.
        try {
        tm += delay;
        Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));
        } catch (InterruptedException e) {
        break;
        }

        // Advance the frame
        frame++;
    }
    }

    /**
     * This method is called when the applet is no longer
     * visible. Set the animator variable to null so that the
     * thread will exit before displaying the next frame.
     */
    public void stop() {
    animator = null;
    offImage = null;
    offGraphics = null;
    }

    /**
     * Update a frame of animation.
     */
    public void update(Graphics g) {
        Dimension d = size();

        // Create the offscreen graphics context
        if ((offGraphics == null) || (d.width != offDimension.width) || (d.height != offDimension.height)) {
            offDimension = d;
            offImage = createImage(d.width, d.height);
            offGraphics = offImage.getGraphics();
        }

        // Erase the previous image
        offGraphics.setColor(getBackground());
        offGraphics.fillRect(0, 0, d.width, d.height);
        offGraphics.setColor(Color.black);

        // Paint the frame into the image
        paintFrame(offGraphics);

        // Paint the image onto the screen
        g.drawImage(offImage, 0, 0, null);
    }

    /**
     * Paint the previous frame (if any).
     */
    public void paint(Graphics g) {
        if (offImage != null) {
            g.drawImage(offImage, 0, 0, null);
        }
    }

    /**
     * Paint a frame of animation.
     */
    public void paintFrame(Graphics g) {
        Dimension d = size();
        g.fillRect(0, 0, d.width, d.height);
        //g.drawImage(level.getImage(), 0, 0, null);
        g.drawImage(ship.getImage(), 400, 300, null);
    }
}
Was it helpful?

Solution

ImageIcon ii = new ImageIcon("ship1.png");  

The ImageIcon constructor that accepts a String presumes the string represents ..

..a file name or a file path.

'Applets and files do not mix.' Only a trusted applet can load a File object, and even then, only from the file system of the end user. The File objects cannot point back to the server.

Applets would more typically work with paths formed from an URL. The Applet class provides a number of methods to help form that URL, and the ImageIcon constructor is overloaded to accept an URL.

..Not sure if I'm loading the image incorrectly or if I'm accessing it incorrectly.

Debugging 101 is to display the image immediately after loading it. Drop the image icon into a label and use a JOptionPane to show the label.

OTHER TIPS

Without seeing your full code we can't really tell what's going on with the exception, but in your call to drawImage() specify 'this' as the last parameter instead of null. Images are loaded asynchronously and so they need something that implements ImageObserver (such as your frame) to tell when they have managed to load a bit more (or all of it) - so that they can repaint.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top